Version 0.7.0.0

svn merge -r 26574:26775 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@26783 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer_experimental/bin/formatter.dart b/pkg/analyzer_experimental/bin/formatter.dart
index 5673426..3fc928d 100755
--- a/pkg/analyzer_experimental/bin/formatter.dart
+++ b/pkg/analyzer_experimental/bin/formatter.dart
@@ -4,6 +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.
 
+import 'dart:convert';
 import 'dart:io';
 
 import 'package:args/args.dart';
diff --git a/pkg/analyzer_experimental/lib/analyzer.dart b/pkg/analyzer_experimental/lib/analyzer.dart
index a88c94c..6424cbf 100644
--- a/pkg/analyzer_experimental/lib/analyzer.dart
+++ b/pkg/analyzer_experimental/lib/analyzer.dart
@@ -14,6 +14,7 @@
 import 'src/generated/parser.dart';
 import 'src/generated/scanner.dart';
 import 'src/generated/source_io.dart';
+import 'src/string_source.dart';
 
 export 'src/error.dart';
 export 'src/generated/ast.dart';
@@ -46,6 +47,25 @@
   return unit;
 }
 
+/// Parses a string of Dart code into an AST.
+///
+/// If [name] is passed, it's used in error messages as the name of the code
+/// being parsed.
+CompilationUnit parseCompilationUnit(String contents, {String name}) {
+  if (name == null) name = '<unknown source>';
+  var source = new StringSource(contents, name);
+  var errorCollector = new _ErrorCollector();
+  var scanner = new StringScanner(source, contents, errorCollector);
+  var token = scanner.tokenize();
+  var parser = new Parser(source, errorCollector);
+  var unit = parser.parseCompilationUnit(token);
+  unit.lineInfo = new LineInfo(scanner.lineStarts);
+
+  if (errorCollector.hasErrors) throw errorCollector.group;
+
+  return unit;
+}
+
 /// Converts an AST node representing a string literal into a [String].
 String stringLiteralToString(StringLiteral literal) {
   return literal.stringValue;
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_core.dart b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
index 4e9d258..4ebd170 100644
--- a/pkg/analyzer_experimental/lib/src/generated/java_core.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
@@ -34,6 +34,9 @@
   if (oTypeName.startsWith("HashMap") && tTypeName == "Map") {
     return true;
   }
+  if (oTypeName.startsWith("LinkedHashMap") && tTypeName == "Map") {
+    return true;
+  }
   if (oTypeName.startsWith("List") && tTypeName == "List") {
     return true;
   }
diff --git a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
index a3745ec..4a17d67 100644
--- a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
@@ -152,11 +152,11 @@
 
   /// A flag to indicate that a newline should be emitted before the next token.
   bool needsNewline = false;
-  
+
   /// A flag to indicate that user introduced newlines should be emitted before
   /// the next token.
   bool preservePrecedingNewlines = false;
-  
+
   /// Initialize a newly created visitor to write source code representing
   /// the visited nodes to the given [writer].
   SourceVisitor(FormatterOptions options, this.lineInfo) :
@@ -164,13 +164,14 @@
                                 lineSeparator: options.lineSeparator);
 
   visitAdjacentStrings(AdjacentStrings node) {
-    visitList(node.strings, ' ');
+    visitNodes(node.strings, separatedBy: space);
   }
 
   visitAnnotation(Annotation node) {
     token(node.atSign);
     visit(node.name);
-    visitPrefixed('.', node.constructorName);
+    token(node.period);
+    visit(node.constructorName);
     visit(node.arguments);
   }
 
@@ -181,7 +182,7 @@
 
   visitArgumentList(ArgumentList node) {
     token(node.leftParenthesis);
-    visitList(node.arguments, ', ');
+    visitNodes(node.arguments, separatedBy: commaSeperator);
     token(node.rightParenthesis);
   }
 
@@ -220,16 +221,10 @@
 
   visitBlock(Block node) {
     token(node.leftBracket);
-    needsNewline = true;
     indent();
-
-    for (var stmt in node.statements) {
-      visit(stmt);
-    }
-
+    visitNodes(node.statements, precededBy: newlines, separatedBy: newlines);
     unindent();
-    preservePrecedingNewlines = true;
-    needsNewline = true;
+    newlines();
     token(node.rightBracket);
   }
 
@@ -242,20 +237,21 @@
   }
 
   visitBreakStatement(BreakStatement node) {
-    preservePrecedingNewlines = true;
     token(node.keyword);
-    visitPrefixed(' ', node.label);
+    visitNode(node.label, precededBy: space);
     token(node.semicolon);
-    needsNewline = true;
   }
 
   visitCascadeExpression(CascadeExpression node) {
     visit(node.target);
-    visitList(node.cascadeSections);
+    visitNodes(node.cascadeSections);
   }
 
   visitCatchClause(CatchClause node) {
-    visitPrefixed('on ', node.exceptionType);
+
+    token(node.onKeyword, precededBy: space, followedBy: space);
+    visit(node.exceptionType);
+
     if (node.catchKeyword != null) {
       if (node.exceptionType != null) {
         space();
@@ -264,37 +260,31 @@
       space();
       token(node.leftParenthesis);
       visit(node.exceptionParameter);
-      visitPrefixed(', ', node.stackTraceParameter);
+      token(node.comma, followedBy: space);
+      visit(node.stackTraceParameter);
       token(node.rightParenthesis);
       space();
     } else {
       space();
     }
     visit(node.body);
-    needsNewline = true;
   }
 
   visitClassDeclaration(ClassDeclaration node) {
-    preservePrecedingNewlines = true;
     modifier(node.abstractKeyword);
     token(node.classKeyword);
     space();
     visit(node.name);
     visit(node.typeParameters);
-    visitPrefixed(' ', node.extendsClause);
-    visitPrefixed(' ', node.withClause);
-    visitPrefixed(' ', node.implementsClause);
+    visitNode(node.extendsClause, precededBy: space);
+    visitNode(node.withClause, precededBy: space);
+    visitNode(node.implementsClause, precededBy: space);
     space();
     token(node.leftBracket);
     indent();
-
-    for (var i = 0; i < node.members.length; i++) {
-      visit(node.members[i]);
-    }
-
+    visitNodes(node.members, precededBy: newlines, separatedBy: newlines);
     unindent();
-
-    emitPrecedingNewlines(node.rightBracket, min: 1);
+    newlines();
     token(node.rightBracket);
   }
 
@@ -311,8 +301,8 @@
       space();
     }
     visit(node.superclass);
-    visitPrefixed(' ', node.withClause);
-    visitPrefixed(' ', node.implementsClause);
+    visitNode(node.withClause, precededBy: space);
+    visitNode(node.implementsClause, precededBy: space);
     token(node.semicolon);
   }
 
@@ -321,18 +311,22 @@
   visitCommentReference(CommentReference node) => null;
 
   visitCompilationUnit(CompilationUnit node) {
-    
+
     // Cache EOF for leading whitespace calculation
     var start = node.beginToken.previous;
     if (start != null && start.type is TokenType_EOF) {
       previousToken = start;
     }
-    
+
     var scriptTag = node.scriptTag;
     var directives = node.directives;
     visit(scriptTag);
-    visitList(directives);
-    visitList(node.declarations);
+
+    preservePrecedingNewlines = true;
+    visitNodes(directives, separatedBy: newlines, followedBy: newlines);
+
+    preservePrecedingNewlines = true;
+    visitNodes(node.declarations, separatedBy: newlines);
 
     // Handle trailing whitespace
     preservePrecedingNewlines = true;
@@ -356,11 +350,14 @@
     modifier(node.constKeyword);
     modifier(node.factoryKeyword);
     visit(node.returnType);
-    visitPrefixed('.', node.name);
+    token(node.period);
+    visit(node.name);
     visit(node.parameters);
-    visitPrefixedList(' : ', node.initializers, ', ');
-    visitPrefixed(' = ', node.redirectedConstructor);
-    visitPrefixedBody(' ', node.body);
+    token(node.separator /* = or : */, precededBy: space, followedBy: space);
+    visitNodes(node.initializers, separatedBy: commaSeperator);
+    visit(node.redirectedConstructor);
+
+    visitPrefixedBody(space, node.body);
   }
 
   visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
@@ -375,32 +372,31 @@
 
   visitConstructorName(ConstructorName node) {
     visit(node.type);
-    visitPrefixed('.', node.name);
+    token(node.period);
+    visit(node.name);
   }
 
   visitContinueStatement(ContinueStatement node) {
     token(node.keyword);
-    visitPrefixed(' ', node.label);
+    visitNode(node.label, precededBy: space);
     token(node.semicolon);
   }
 
   visitDeclaredIdentifier(DeclaredIdentifier node) {
-    token(node.keyword);
-    space();
-    visit(node.type);
-    //TODO(pquitslund): avoiding visitSuffixed(..) but we can do better
-    if (node.type != null) {
-      space();
-    }
+    modifier(node.keyword);
+    visitNode(node.type, followedBy: space);
     visit(node.identifier);
   }
 
   visitDefaultFormalParameter(DefaultFormalParameter node) {
     visit(node.parameter);
     if (node.separator != null) {
-      space();
+      // The '=' separator is preceded by a space
+      if (node.separator.type == TokenType.EQ) {
+        space();
+      }
       token(node.separator);
-      visitPrefixed(' ', node.defaultValue);
+      visitNode(node.defaultValue, precededBy: space);
     }
   }
 
@@ -433,7 +429,7 @@
     token(node.keyword);
     space();
     visit(node.uri);
-    visitPrefixedList(' ', node.combinators, ' ');
+    visitNodes(node.combinators, precededBy: space, separatedBy: space);
     token(node.semicolon);
   }
 
@@ -456,18 +452,14 @@
   }
 
   visitFieldDeclaration(FieldDeclaration node) {
-    needsNewline = true;
-    preservePrecedingNewlines = true;
     modifier(node.keyword);
     visit(node.fields);
     token(node.semicolon);
   }
 
   visitFieldFormalParameter(FieldFormalParameter node) {
-    token(node.keyword);
-    space();
-    visit(node.type);
-    space();
+    token(node.keyword, followedBy: space);
+    visitNode(node.type, followedBy: space);
     token(node.thisToken);
     token(node.period);
     visit(node.identifier);
@@ -519,25 +511,23 @@
     token(node.forKeyword);
     space();
     token(node.leftParenthesis);
-    var initialization = node.initialization;
-    if (initialization != null) {
-      visit(initialization);
+    if (node.initialization != null) {
+      visit(node.initialization);
     } else {
       visit(node.variables);
     }
     token(node.leftSeparator);
-    visitPrefixed(' ', node.condition);
+    space();
+    visit(node.condition);
     token(node.rightSeparator);
-    visitPrefixedList(' ', node.updaters, ', ');
-    token(node.leftParenthesis);
+    visitNodes(node.updaters, precededBy: space, separatedBy: space);
+    token(node.rightParenthesis);
     space();
     visit(node.body);
   }
 
   visitFunctionDeclaration(FunctionDeclaration node) {
-    needsNewline = true;
-    preservePrecedingNewlines = true;
-    visitSuffixed(node.returnType, ' ');
+    visitNode(node.returnType, followedBy: space);
     token(node.propertyKeyword, followedBy: space);
     visit(node.name);
     visit(node.functionExpression);
@@ -545,8 +535,6 @@
 
   visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
     visit(node.functionDeclaration);
-    // TODO(pquitslund): fix and handle in function body
-    append(';');
   }
 
   visitFunctionExpression(FunctionExpression node) {
@@ -563,7 +551,7 @@
   visitFunctionTypeAlias(FunctionTypeAlias node) {
     token(node.keyword);
     space();
-    visitSuffixed(node.returnType, ' ');
+    visitNode(node.returnType, followedBy: space);
     visit(node.name);
     visit(node.typeParameters);
     visit(node.parameters);
@@ -571,7 +559,7 @@
   }
 
   visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    visitSuffixed(node.returnType, ' ');
+    visitNode(node.returnType, followedBy: space);
     visit(node.identifier);
     visit(node.parameters);
   }
@@ -579,11 +567,10 @@
   visitHideCombinator(HideCombinator node) {
     token(node.keyword);
     space();
-    visitList(node.hiddenNames, ', ');
+    visitNodes(node.hiddenNames, separatedBy: commaSeperator);
   }
 
   visitIfStatement(IfStatement node) {
-    preservePrecedingNewlines = true;
     token(node.ifKeyword);
     space();
     token(node.leftParenthesis);
@@ -598,24 +585,22 @@
       space();
       visit(node.elseStatement);
     }
-    needsNewline = true;
   }
-  
+
   visitImplementsClause(ImplementsClause node) {
     token(node.keyword);
     space();
-    visitList(node.interfaces, ', ');
+    visitNodes(node.interfaces, separatedBy: commaSeperator);
   }
 
   visitImportDirective(ImportDirective node) {
-    preservePrecedingNewlines = true;
     token(node.keyword);
     space();
     visit(node.uri);
-    visitPrefixed(' as ', node.prefix);
-    visitPrefixedList(' ', node.combinators, ' ');
+    token(node.asToken, precededBy: space, followedBy: space);
+    visit(node.prefix);
+    visitNodes(node.combinators, precededBy: space, separatedBy: space);
     token(node.semicolon);
-    needsNewline = true;
   }
 
   visitIndexExpression(IndexExpression node) {
@@ -670,7 +655,7 @@
   }
 
   visitLabeledStatement(LabeledStatement node) {
-    visitSuffixedList(node.labels, ' ', ' ');
+    visitNodes(node.labels, separatedBy: space, followedBy: space);
     visit(node.statement);
   }
 
@@ -686,60 +671,51 @@
   }
 
   visitListLiteral(ListLiteral node) {
-    if (node.modifier != null) {
-      token(node.modifier);
-      space();
-    }
+    modifier(node.modifier);
     visit(node.typeArguments);
     token(node.leftBracket);
-    visitList(node.elements, ', ');
+    visitNodes(node.elements, separatedBy: commaSeperator);
     token(node.rightBracket);
   }
 
   visitMapLiteral(MapLiteral node) {
     modifier(node.modifier);
-    visitSuffixed(node.typeArguments, ' ');
+    visitNode(node.typeArguments, followedBy: space);
     token(node.leftBracket);
-    visitList(node.entries, ', ');
+    visitNodes(node.entries, separatedBy: commaSeperator);
     token(node.rightBracket);
   }
 
   visitMapLiteralEntry(MapLiteralEntry node) {
     visit(node.key);
-    space();
     token(node.separator);
     space();
     visit(node.value);
   }
 
   visitMethodDeclaration(MethodDeclaration node) {
-    needsNewline = true;
-    preservePrecedingNewlines = true;
     modifier(node.externalKeyword);
     modifier(node.modifierKeyword);
-    visitSuffixed(node.returnType, ' ');
+    visitNode(node.returnType, followedBy: space);
     modifier(node.propertyKeyword);
     modifier(node.operatorKeyword);
     visit(node.name);
     if (!node.isGetter) {
       visit(node.parameters);
     }
-    visitPrefixedBody(' ', node.body);
+    visitPrefixedBody(space, node.body);
   }
 
   visitMethodInvocation(MethodInvocation node) {
-    if (node.isCascaded) {
-      token(node.period);
-    } else {
-      visitSuffixed(node.target, '.');
-    }
+    visit(node.target);
+    token(node.period);
     visit(node.methodName);
     visit(node.argumentList);
   }
 
   visitNamedExpression(NamedExpression node) {
     visit(node.name);
-    visitPrefixed(' ', node.expression);
+    visitNode(node.expression, precededBy: space);
   }
 
   visitNativeClause(NativeClause node) {
@@ -775,6 +751,8 @@
   visitPartOfDirective(PartOfDirective node) {
     token(node.keyword);
     space();
+    token(node.ofToken);
+    space();
     visit(node.libraryName);
     token(node.semicolon);
   }
@@ -807,7 +785,8 @@
 
   visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
     token(node.keyword);
-    visitPrefixed('.', node.constructorName);
+    token(node.period);
+    visit(node.constructorName);
     visit(node.argumentList);
   }
 
@@ -816,7 +795,6 @@
   }
 
   visitReturnStatement(ReturnStatement node) {
-    preservePrecedingNewlines = true;
     var expression = node.expression;
     if (expression == null) {
       token(node.keyword);
@@ -836,12 +814,12 @@
   visitShowCombinator(ShowCombinator node) {
     token(node.keyword);
     space();
-    visitList(node.shownNames, ', ');
+    visitNodes(node.shownNames, separatedBy: commaSeperator);
   }
 
   visitSimpleFormalParameter(SimpleFormalParameter node) {
     modifier(node.keyword);
-    visitSuffixed(node.type, ' ');
+    visitNode(node.type, followedBy: space);
     visit(node.identifier);
   }
 
@@ -854,12 +832,13 @@
   }
 
   visitStringInterpolation(StringInterpolation node) {
-    visitList(node.elements);
+    visitNodes(node.elements);
   }
 
   visitSuperConstructorInvocation(SuperConstructorInvocation node) {
     token(node.keyword);
-    visitPrefixed('.', node.constructorName);
+    token(node.period);
+    visit(node.constructorName);
     visit(node.argumentList);
   }
 
@@ -868,25 +847,23 @@
   }
 
   visitSwitchCase(SwitchCase node) {
-    preservePrecedingNewlines = true;
-    visitSuffixedList(node.labels, ' ', ' ');
+    visitNodes(node.labels, separatedBy: space, followedBy: space);
     token(node.keyword);
     space();
     visit(node.expression);
     token(node.colon);
+    newlines();
     indent();
-    needsNewline = true;
-    visitList(node.statements);
+    visitNodes(node.statements, separatedBy: newlines);
     unindent();
   }
 
   visitSwitchDefault(SwitchDefault node) {
-    preservePrecedingNewlines = true;
-    visitSuffixedList(node.labels, ' ', ' ');
+    visitNodes(node.labels, separatedBy: space, followedBy: space);
     token(node.keyword);
     token(node.colon);
     space();
-    visitList(node.statements, ' ');
+    visitNodes(node.statements, separatedBy: space);
   }
 
   visitSwitchStatement(SwitchStatement node) {
@@ -898,10 +875,10 @@
     space();
     token(node.leftBracket);
     indent();
-    visitList(node.members);
+    newlines();
+    visitNodes(node.members, separatedBy: newlines, followedBy: newlines);
     unindent();
     token(node.rightBracket);
-    needsNewline = true;
   }
 
   visitSymbolLiteral(SymbolLiteral node) {
@@ -919,23 +896,22 @@
   }
 
   visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    preservePrecedingNewlines = true;
     visit(node.variables);
     token(node.semicolon);
   }
 
   visitTryStatement(TryStatement node) {
-    preservePrecedingNewlines = true;
     token(node.tryKeyword);
     space();
     visit(node.body);
-    visitPrefixedList(' ', node.catchClauses, ' ');
-    visitPrefixed(' finally ', node.finallyClause);
+    visitNodes(node.catchClauses, precededBy: space, separatedBy: space);
+    token(node.finallyKeyword, precededBy: space, followedBy: space);
+    visit(node.finallyClause);
   }
 
   visitTypeArgumentList(TypeArgumentList node) {
     token(node.leftBracket);
-    visitList(node.arguments, ', ');
+    visitNodes(node.arguments, separatedBy: commaSeperator);
     token(node.rightBracket);
   }
 
@@ -946,12 +922,13 @@
 
   visitTypeParameter(TypeParameter node) {
     visit(node.name);
-    visitPrefixed(' extends ', node.bound);
+    token(node.keyword /* extends */, precededBy: space, followedBy: space);
+    visit(node.bound);
   }
 
   visitTypeParameterList(TypeParameterList node) {
     token(node.leftBracket);
-    visitList(node.typeParameters, ', ');
+    visitNodes(node.typeParameters, separatedBy: commaSeperator);
     token(node.rightBracket);
   }
 
@@ -966,16 +943,14 @@
   }
 
   visitVariableDeclarationList(VariableDeclarationList node) {
-    token(node.keyword);
-    space();
-    visitSuffixed(node.type, ' ');
-    visitList(node.variables, ', ');
+    modifier(node.keyword);
+    visitNode(node.type, followedBy: space);
+    visitNodes(node.variables, separatedBy: commaSeperator);
   }
 
   visitVariableDeclarationStatement(VariableDeclarationStatement node) {
     visit(node.variables);
     token(node.semicolon);
-    needsNewline = true;
   }
 
   visitWhileStatement(WhileStatement node) {
@@ -991,7 +966,7 @@
   visitWithClause(WithClause node) {
     token(node.withKeyword);
     space();
-    visitList(node.mixinTypes, ', ');
+    visitNodes(node.mixinTypes, separatedBy: commaSeperator);
   }
 
   /// Safely visit the given [node].
@@ -1001,86 +976,68 @@
     }
   }
 
-  /// Safely visit the given [node], printing the [suffix] after the node if it
-  /// is non-null.
-  visitSuffixed(ASTNode node, String suffix) {
-    if (node != null) {
-      node.accept(this);
-      append(suffix);
-    }
-  }
-
-  /// Safely visit the given [node], printing the [prefix] before the node if
-  /// it is non-null.
-  visitPrefixed(String prefix, ASTNode node) {
-    if (node != null) {
-      append(prefix);
-      node.accept(this);
-    }
-  }
-
   /// Visit the given function [body], printing the [prefix] before if given
   /// body is not empty.
-  visitPrefixedBody(String prefix, FunctionBody body) {
+  visitPrefixedBody(prefix(), FunctionBody body) {
     if (body is! EmptyFunctionBody) {
-      append(prefix);
+      prefix();
     }
     visit(body);
   }
 
-  /// Print a list of [nodes], optionally separated by the given [separator].
-  visitList(NodeList<ASTNode> nodes, [String separator = '']) {
-    if (nodes != null) {
-      var size = nodes.length;
-      for (var i = 0; i < size; i++) {
-        if (i > 0) {
-          append(separator);
-        }
-        nodes[i].accept(this);
-      }
-    }
-  }
-
-  /// Print a list of [nodes], separated by the given [separator].
-  visitSuffixedList(NodeList<ASTNode> nodes, String separator, String suffix) {
+  /// Visit a list of [nodes] if not null, optionally separated and/or preceded
+  /// and followed by the given functions.
+  visitNodes(NodeList<ASTNode> nodes, {precededBy(): null,
+      separatedBy() : null, followedBy(): null}) {
     if (nodes != null) {
       var size = nodes.length;
       if (size > 0) {
+        if (precededBy != null) {
+          precededBy();
+        }
         for (var i = 0; i < size; i++) {
-          if (i > 0) {
-            append(separator);
+          if (i > 0 && separatedBy != null) {
+            separatedBy();
           }
           nodes[i].accept(this);
         }
-        append(suffix);
-      }
-    }
-  }
-
-  /// Print a list of [nodes], separated by the given [separator].
-  visitPrefixedList(String prefix, NodeList<ASTNode> nodes,
-      [String separator = null]) {
-    if (nodes != null) {
-      var size = nodes.length;
-      if (size > 0) {
-        append(prefix);
-        for (var i = 0; i < size; i++) {
-          if (i > 0 && separator != null) {
-            append(separator);
-          }
-          nodes[i].accept(this);
+        if (followedBy != null) {
+          followedBy();
         }
       }
     }
   }
 
-  /// Emit the given [modifier] if it's non null, followed by non-breaking 
+  /// Visit a [node], and if not null, optionally preceded or followed by the
+  /// specified functions.
+  visitNode(ASTNode node, {precededBy(): null, followedBy(): null}) {
+    if (node != null) {
+      if (precededBy != null) {
+        precededBy();
+      }
+      node.accept(this);
+      if (followedBy != null) {
+        followedBy();
+      }
+    }
+  }
+
+
+  /// Emit the given [modifier] if it's non null, followed by non-breaking
   /// whitespace.
   modifier(Token modifier) {
     token(modifier, followedBy: space);
   }
-    
-  token(Token token, {followedBy(), int minNewlines: 0}) {
+
+
+  /// Indicate that at least one newline should be emitted and possibly more
+  /// if the source has them.
+  newlines() {
+    preservePrecedingNewlines = true;
+    needsNewline = true;
+  }
+
+  token(Token token, {precededBy(), followedBy(), int minNewlines: 0}) {
     if (token != null) {
       if (needsNewline) {
         minNewlines = max(1, minNewlines);
@@ -1092,51 +1049,86 @@
           needsNewline = false;
         }
       }
+      if (precededBy !=null) {
+        precededBy();
+      }
+      emitBlockComments(token);
       append(token.lexeme);
-      if (followedBy != null) { 
+      if (followedBy != null) {
         followedBy();
       }
       previousToken = token;
-    }    
+    }
   }
-    
+
+  commaSeperator() {
+    comma();
+    space();
+  }
+
+  comma() {
+    append(',');
+  }
+
   /// Emit a non-breakable space.
   space() {
     //TODO(pquitslund): replace with a proper space token
     append(' ');
   }
-  
+
   /// Emit a breakable space
   breakableSpace() {
     //Implement
   }
-  
+
   /// Append the given [string] to the source writer if it's non-null.
   append(String string) {
     if (string != null) {
       writer.print(string);
     }
   }
-    
+
   /// Indent.
   indent() {
     writer.indent();
   }
-  
+
   /// Unindent
   unindent() {
     writer.unindent();
   }
-  
-  /// Emit any detected newlines or a minimum as specified by [minNewlines].
+
+  emitBlockComments(Token token) {
+    var comment = token.precedingComments;
+    while (comment != null) {
+      if (isBlock(comment)) {
+        append(comment.toString().trim());
+        if (linesBetween(comment.end, token.offset) >= 1) {
+          writer.newline();
+        } else {
+          space();
+        }
+      }
+      comment = comment.next;
+    }
+  }
+
+  /// Emit any detected newlines or a minimum as specified by [min].
   int emitPrecedingNewlines(Token token, {min: 0}) {
     var comment = token.precedingComments;
     var currentToken = comment != null ? comment : token;
     var lines = max(min, countNewlinesBetween(previousToken, currentToken));
     writer.newlines(lines);
+
     while (comment != null) {
-      append(comment.toString().trim());
-      writer.newline();
+      if (!isBlock(comment)) {
+        append(comment.toString().trim());
+        var nextToken = comment.next != null ? comment.next : token;
+        var postCommentNewlines =
+            max(1, countNewlinesBetween(comment, nextToken));
+        writer.newlines(postCommentNewlines);
+        lines += postCommentNewlines;
+      }
       comment = comment.next;
     }
 
@@ -1161,13 +1153,24 @@
     if (last == null || current == null) {
       return 0;
     }
+
+    return linesBetween(last.end - 1, current.offset);
+  }
+
+  /// Test if this [comment] is a block comment.
+  bool isBlock(Token comment) =>
+      comment.type != TokenType.SINGLE_LINE_COMMENT &&
+        linesBetween(comment.offset, comment.end) < 1;
+
+  /// Count the lines between two offsets.
+  int linesBetween(int lastOffset, int currentOffset) {
     var lastLine =
-        lineInfo.getLocation(last.offset).lineNumber;
+        lineInfo.getLocation(lastOffset).lineNumber;
     var currentLine =
-        lineInfo.getLocation(current.offset).lineNumber;
-    return  currentLine - lastLine;
+        lineInfo.getLocation(currentOffset).lineNumber;
+    return currentLine - lastLine;
   }
 
   String toString() => writer.toString();
-  
+
 }
\ No newline at end of file
diff --git a/pkg/analyzer_experimental/lib/src/string_source.dart b/pkg/analyzer_experimental/lib/src/string_source.dart
new file mode 100644
index 0000000..b473365
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/string_source.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.string_source;
+
+import 'generated/source.dart';
+
+/// An implementation of [Source] that's based on an in-memory Dart string.
+class StringSource implements Source {
+  final String _contents;
+  final String fullName;
+  final int modificationStamp;
+
+  StringSource(this._contents, this.fullName)
+      : modificationStamp = new DateTime.now().millisecondsSinceEpoch;
+
+  bool operator==(Object object) => object is StringSource &&
+      object._contents == _contents && object._name == _name;
+
+  bool exists() => true;
+
+  void getContents(Source_ContentReceiver receiver) =>
+      receiver.accept2(_contents, modificationStamp);
+
+  String get encoding => throw UnsupportedError("StringSource doesn't support "
+      "encoding.");
+
+  String get shortName => fullName;
+
+  String get uriKind => throw UnsupportedError("StringSource doesn't support "
+      "uriKind.");
+
+  int get hashCode => _contents.hashCode ^ _name.hashCode;
+
+  bool get isInSystemLibrary => false;
+
+  Source resolveRelative(Uri relativeUri) => throw UnsupportedError(
+      "StringSource doesn't support resolveRelative.");
+}
diff --git a/pkg/analyzer_experimental/test/parse_compilation_unit_test.dart b/pkg/analyzer_experimental/test/parse_compilation_unit_test.dart
new file mode 100644
index 0000000..69389b8
--- /dev/null
+++ b/pkg/analyzer_experimental/test/parse_compilation_unit_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_experimental/analyzer.dart';
+import 'package:unittest/unittest.dart';
+
+void main() {
+  test("parses a valid compilation unit successfully", () {
+    var unit = parseCompilationUnit("void main() => print('Hello, world!');");
+    expect(unit.toString(), equals("void main() => print('Hello, world!');"));
+  });
+
+  test("throws errors for an invalid compilation unit", () {
+    expect(() {
+      parseCompilationUnit("void main() => print('Hello, world!')",
+          name: 'test.dart');
+    }, throwsA(predicate((error) {
+      return error is AnalyzerErrorGroup &&
+          error.toString().contains("line 1 of test.dart");
+    })));
+  });
+
+  test("defaults to '<unknown source>' if no name is provided", () {
+    expect(() {
+      parseCompilationUnit("void main() => print('Hello, world!')");
+    }, throwsA(predicate((error) {
+      return error is AnalyzerErrorGroup &&
+          error.toString().contains("line 1 of <unknown source>");
+    })));
+  });
+}
diff --git a/pkg/analyzer_experimental/test/services/formatter_test.dart b/pkg/analyzer_experimental/test/services/formatter_test.dart
index 2ad1d13..25934ff 100644
--- a/pkg/analyzer_experimental/test/services/formatter_test.dart
+++ b/pkg/analyzer_experimental/test/services/formatter_test.dart
@@ -67,23 +67,61 @@
           '}'
       );
     });
-    
-    
-//    test('CU - comments', () {
-//      expectCUFormatsTo(
-//          'library foo;\n'
-//          '\n'
-//          '//comment one\n\n'
-//          '//comment two\n\n'
-//          'class C {\n}\n',
-//          'library foo;\n'
-//          '\n'
-//          '//comment one\n\n'
-//          '//comment two\n\n'
-//          'class C {\n}\n'
-//      );
-//    });
-    
+
+    test('CU - EOL comments', () {
+      expectCUFormatsTo(
+          '//comment one\n\n'
+          '//comment two\n\n',
+          '//comment one\n\n'
+          '//comment two\n\n'
+      );
+      expectCUFormatsTo(
+          'library foo;\n'
+          '\n'
+          '//comment one\n'
+          '\n'
+          'class C {\n'
+          '}\n',
+          'library foo;\n'
+          '\n'
+          '//comment one\n'
+          '\n'
+          'class C {\n'
+          '}\n'
+      );
+      expectCUFormatsTo(
+          'library foo;\n'
+          '\n'
+          '//comment one\n'
+          '\n'
+          '//comment two\n'
+          '\n'
+          'class C {\n'
+          '}\n',
+          'library foo;\n'
+          '\n'
+          '//comment one\n'
+          '\n'
+          '//comment two\n'
+          '\n'
+          'class C {\n'
+          '}\n'
+      );
+    });
+
+    test('CU - nested functions', () {
+      expectCUFormatsTo(
+          'x() {\n'
+          '  y() {\n'
+          '  }\n'
+          '}\n',
+          'x() {\n'
+          '  y() {\n'
+          '  }\n'
+          '}\n'
+        );
+    });
+
     test('CU - top level', () {
       expectCUFormatsTo(
           '\n\n'
@@ -104,7 +142,7 @@
           'final foo = 32;\n'
       );
     });
-    
+
     test('CU - imports', () {
       expectCUFormatsTo(
           'import "dart:io";\n\n'
@@ -116,6 +154,33 @@
           'foo() {\n'
           '}\n'
       );
+      expectCUFormatsTo(
+          'library a; class B { }',
+          'library a;\n'
+          'class B {\n'
+          '}'
+      );
+    });
+
+    test('CU - method invocations', () {
+      expectCUFormatsTo(
+          'class A {\n'
+          '  foo() {\n'
+          '    bar();\n'
+          '    for (int i = 0; i < 42; i++) {\n'
+          '      baz();\n'
+          '    }\n'
+          '  }\n'
+          '}\n',
+          'class A {\n'
+          '  foo() {\n'
+          '    bar();\n'
+          '    for (int i = 0; i < 42; i++) {\n'
+          '      baz();\n'
+          '    }\n'
+          '  }\n'
+          '}\n'
+        );
     });
 
     test('CU w/class decl comment', () {
@@ -165,7 +230,7 @@
           '}\n'
       );
     });
-    
+
     test('CU (method indent)', () {
       expectCUFormatsTo(
           'class A {\n'
@@ -256,6 +321,173 @@
       );
     });
 
+    test('CU - Block comments', () {
+      expectCUFormatsTo(
+          '/** Old school class comment */\n'
+          'class C {\n'
+          '  /** Foo! */ int foo() => 42;\n'
+          '}\n',
+          '/** Old school class comment */\n'
+          'class C {\n'
+          '  /** Foo! */ int foo() => 42;\n'
+          '}\n'
+      );
+      expectCUFormatsTo(
+          'library foo;\n'
+          'class C /* is cool */ {\n'
+          '  /* int */ foo() => 42;\n'
+          '}\n',
+          'library foo;\n'
+          'class C /* is cool */ {\n'
+          '  /* int */ foo() => 42;\n'
+          '}\n'
+      );
+      expectCUFormatsTo(
+          'library foo;\n'
+          '/* A long\n'
+          ' * Comment\n'
+          '*/\n'
+          'class C /* is cool */ {\n'
+          '  /* int */ foo() => 42;\n'
+          '}\n',
+          'library foo;\n'
+          '/* A long\n'
+          ' * Comment\n'
+          '*/\n'
+          'class C /* is cool */ {\n'
+          '  /* int */ foo() => 42;\n'
+          '}\n'
+      );
+      expectCUFormatsTo(
+          'library foo;\n'
+          '/* A long\n'
+          ' * Comment\n'
+          '*/\n'
+          '\n'
+          '/* And\n'
+          ' * another...\n'
+          '*/\n'
+          '\n'
+          '// Mixing it up\n'
+          '\n'
+          'class C /* is cool */ {\n'
+          '  /* int */ foo() => 42;\n'
+          '}\n',
+          'library foo;\n'
+          '/* A long\n'
+          ' * Comment\n'
+          '*/\n'
+          '\n'
+          '/* And\n'
+          ' * another...\n'
+          '*/\n'
+          '\n'
+          '// Mixing it up\n'
+          '\n'
+          'class C /* is cool */ {\n'
+          '  /* int */ foo() => 42;\n'
+          '}\n'
+      );
+      expectCUFormatsTo(
+          '/// Copyright info\n'
+          '\n'
+          'library foo;\n'
+          '/// Class comment\n'
+          '//TODO: implement\n'
+          'class C {\n'
+          '}\n',
+          '/// Copyright info\n'
+          '\n'
+          'library foo;\n'
+          '/// Class comment\n'
+          '//TODO: implement\n'
+          'class C {\n'
+          '}\n'
+      );
+    });
+    
+    
+    test('CU - constructor', () {
+      expectCUFormatsTo(
+          'class A {\n'
+          '  const _a;\n'
+          '  A();\n'
+          '  int a() => _a;\n'
+          '}\n',
+          'class A {\n'
+          '  const _a;\n'
+          '  A();\n'
+          '  int a() => _a;\n'
+          '}\n'
+        );
+    });
+
+    test('CU - method decl w/ named params', () {
+      expectCUFormatsTo(
+          'class A {\n'
+          '  int a(var x, {optional: null}) => null;\n'
+          '}\n',
+          'class A {\n'
+          '  int a(var x, {optional: null}) => null;\n'
+          '}\n'
+        );
+    });
+
+    test('CU - method decl w/ optional params', () {
+      expectCUFormatsTo(
+          'class A {\n'
+          '  int a(var x, [optional = null]) => null;\n'
+          '}\n',
+          'class A {\n'
+          '  int a(var x, [optional = null]) => null;\n'
+          '}\n'
+        );
+    });
+
+    test('CU - factory constructor redirects', () {
+      expectCUFormatsTo(
+          'class A {\n'
+          '  const factory A() = B;\n'
+          '}\n',
+          'class A {\n'
+          '  const factory A() = B;\n'
+          '}\n'
+        );
+    });
+
+    test('CU - constructor initializers', () {
+      expectCUFormatsTo(
+          'class A {\n'
+          '  int _a;\n'
+          '  A(a) : _a = a;\n'
+          '}\n',
+          'class A {\n'
+          '  int _a;\n'
+          '  A(a) : _a = a;\n'
+          '}\n'
+        );
+    });
+
+    test('CU - constructor auto field inits', () {
+      expectCUFormatsTo(
+          'class A {\n'
+          '  int _a;\n'
+          '  A(this._a);\n'
+          '}\n',
+          'class A {\n'
+          '  int _a;\n'
+          '  A(this._a);\n'
+          '}\n'
+        );
+    });
+
+    test('CU - parts', () {
+      expectCUFormatsTo(
+        'part of foo;',
+        'part of foo;\n'
+      );
+    });
+
     test('stmt', () {
       expectStmtFormatsTo(
          'if (true){\n'
@@ -303,14 +535,21 @@
         '}'
       );
     });
-  
+
     test('stmt (generics)', () {
       expectStmtFormatsTo(
         'var numbers = <int>[1, 2, (3 + 4)];',
         'var numbers = <int>[1, 2, (3 + 4)];'
       );
     });
-    
+
+    test('stmt (maps)', () {
+      expectStmtFormatsTo(
+        'var map = const {"foo": "bar", "fuz": null};',
+        'var map = const {"foo": "bar", "fuz": null};'
+      );
+    });
+
     test('stmt (try/catch)', () {
       expectStmtFormatsTo(
         'try {\n'
@@ -325,7 +564,7 @@
         '}'
       );
     });
-    
+
     test('stmt (binary/ternary ops)', () {
       expectStmtFormatsTo(
         'var a = 1 + 2 / (3 * -b);',
@@ -344,7 +583,34 @@
         'var d = obj is! SomeType;'
       );
     });
-    
+
+    test('stmt (for in)', () {
+      expectStmtFormatsTo(
+        'for (Foo foo in bar.foos) {\n'
+        '  print(foo);\n'
+        '}',
+        'for (Foo foo in bar.foos) {\n'
+        '  print(foo);\n'
+        '}'
+      );
+      expectStmtFormatsTo(
+        'for (final Foo foo in bar.foos) {\n'
+        '  print(foo);\n'
+        '}',
+        'for (final Foo foo in bar.foos) {\n'
+        '  print(foo);\n'
+        '}'
+      );
+      expectStmtFormatsTo(
+        'for (final foo in bar.foos) {\n'
+        '  print(foo);\n'
+        '}',
+        'for (final foo in bar.foos) {\n'
+        '  print(foo);\n'
+        '}'
+      );
+    });
+
     test('initialIndent', () {
       var formatter = new CodeFormatter(
           new FormatterOptions(initialIndentationLevel: 2));
diff --git a/pkg/async_helper/lib/async_helper.dart b/pkg/async_helper/lib/async_helper.dart
new file mode 100644
index 0000000..f1a84b3
--- /dev/null
+++ b/pkg/async_helper/lib/async_helper.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This library is used for testing asynchronous tests.
+/// If a test is asynchronous, it needs to notify the testing driver
+/// about this (otherwise tests may get reported as passing [after main()
+/// finished] even if the asynchronous operations fail).
+/// Tests which can't use the unittest framework should use the helper functions
+/// in this library.
+/// This library provides two methods
+///  - asyncStart(): Needs to be called before an asynchronous operation is
+///                  scheduled.
+///  - asyncEnd(): Needs to be called as soon as the asynchronous operation
+///                ended.
+/// After the last asyncStart() called was matched with a corresponding
+/// asyncEnd() call, the testing driver will be notified that the tests is done.
+
+library async_helper;
+
+// TODO(kustermann): This is problematic because we rely on a working
+// 'dart:isolate' (i.e. it is in particular problematic with dart2js).
+// It would be nice if we could use a different mechanism for different
+// runtimes.
+import 'dart:isolate';
+
+bool _initialized = false;
+ReceivePort _port = null;
+int _asyncLevel = 0;
+
+Exception _buildException(String msg) {
+  return new Exception('Fatal: $msg. This is most likely a bug in your test.');
+}
+
+void asyncStart() {
+  if (_initialized && _asyncLevel == 0) {
+    throw _buildException('asyncStart() was called even though we are done '
+                          'with testing.');
+  }
+  if (!_initialized) {
+    print('unittest-suite-wait-for-done');
+    _initialized = true;
+    _port = new ReceivePort();
+  }
+  _asyncLevel++;
+}
+
+void asyncEnd() {
+  if (_asyncLevel <= 0) {
+    if (!_initialized) {
+      throw _buildException('asyncEnd() was called before asyncStart().');
+    } else {
+      throw _buildException('asyncEnd() was called more often than '
+                            'asyncStart().');
+    }
+  }
+  _asyncLevel--;
+  if (_asyncLevel == 0) {
+    _port.close();
+    _port = null;
+    print('unittest-suite-success');
+  }
+}
diff --git a/pkg/async_helper/pubspec.yaml b/pkg/async_helper/pubspec.yaml
new file mode 100644
index 0000000..e4f33de
--- /dev/null
+++ b/pkg/async_helper/pubspec.yaml
@@ -0,0 +1,9 @@
+name: async_helper
+author: "Dart Team <misc@dartlang.org>"
+homepage: http://www.dartlang.org
+description: >
+ Async_helper is used for asynchronous tests that do not want to
+ make use of the Dart unittest library - for example, the core
+ language tests.
+ Third parties are discouraged from using this, and should use
+ the facilities provided in the unittest library.
diff --git a/pkg/barback/lib/src/asset.dart b/pkg/barback/lib/src/asset.dart
index db7a5ea..254edfb 100644
--- a/pkg/barback/lib/src/asset.dart
+++ b/pkg/barback/lib/src/asset.dart
@@ -5,11 +5,11 @@
 library barback.asset;
 
 import 'dart:async';
-import 'dart:convert' show Encoding, UTF8;
+import 'dart:convert';
 import 'dart:io';
-import 'dart:utf';
 
 import 'asset_id.dart';
+import 'stream_replayer.dart';
 import 'utils.dart';
 
 /// A blob of content.
@@ -34,6 +34,12 @@
   factory Asset.fromPath(AssetId id, String path) =>
       new _FileAsset(id, new File(path));
 
+  /// Creates an asset from a stream.
+  ///
+  /// This immediately starts draining [stream].
+  factory Asset.fromStream(AssetId id, Stream<List<int>> stream) =>
+      new _StreamAsset(id, stream);
+
   /// Returns the contents of the asset as a string.
   ///
   /// If the asset was created from a [String] the original string is always
@@ -118,7 +124,7 @@
       new Future.value(_contents);
 
   Stream<List<int>> read() =>
-      new Future<List<int>>.value(encodeUtf8(_contents)).asStream();
+      new Future<List<int>>.value(UTF8.encode(_contents)).asStream();
 
   String toString() {
     // Don't show the whole string if it's long.
@@ -140,3 +146,24 @@
         .replaceAll("\t", r"\t");
   }
 }
+
+/// An asset whose data is available from a stream.
+class _StreamAsset extends Asset {
+  /// A stream replayer that records and replays the contents of the input
+  /// stream.
+  final StreamReplayer<List<int>> _replayer;
+
+  _StreamAsset(AssetId id, Stream<List<int>> stream)
+      : _replayer = new StreamReplayer(stream),
+        super(id);
+
+  Future<String> readAsString({Encoding encoding}) {
+    if (encoding == null) encoding = UTF8;
+    return _replayer.getReplay().toList()
+        .then((chunks) => encoding.decode(flatten(chunks)));
+  }
+
+  Stream<List<int>> read() => _replayer.getReplay();
+
+  String toString() => "Stream";
+}
diff --git a/pkg/barback/lib/src/package_graph.dart b/pkg/barback/lib/src/package_graph.dart
index a402a27..5afe5f4 100644
--- a/pkg/barback/lib/src/package_graph.dart
+++ b/pkg/barback/lib/src/package_graph.dart
@@ -86,7 +86,8 @@
       });
     }
 
-    _errors = mergeStreams(_cascades.values.map((cascade) => cascade.errors));
+    _errors = mergeStreams(_cascades.values.map((cascade) => cascade.errors),
+        broadcast: true);
   }
 
   /// Gets the asset node identified by [id].
diff --git a/pkg/barback/lib/src/stream_replayer.dart b/pkg/barback/lib/src/stream_replayer.dart
new file mode 100644
index 0000000..177e13d
--- /dev/null
+++ b/pkg/barback/lib/src/stream_replayer.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library barback.stream_replayer;
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'utils.dart';
+
+/// Records the values and errors that are sent through a stream and allows them
+/// to be replayed arbitrarily many times.
+class StreamReplayer<T> {
+  /// The wrapped stream.
+  final Stream<T> _stream;
+
+  /// Whether or not [_stream] has been closed.
+  bool _isClosed = false;
+
+  /// The buffer of events or errors that have already been emitted by
+  /// [_stream].
+  ///
+  /// Each element is a [Either] that's either a value or an error sent through
+  /// the stream.
+  final _buffer = new Queue<Either<T, dynamic>>();
+
+  /// The controllers that are listening for future events from [_stream].
+  final _controllers = new Set<StreamController<T>>();
+
+  StreamReplayer(this._stream) {
+    _stream.listen((data) {
+      _buffer.add(new Either<T, dynamic>.withFirst(data));
+      for (var controller in _controllers) {
+        controller.add(data);
+      }
+    }, onError: (error) {
+      _buffer.add(new Either<T, dynamic>.withSecond(error));
+      for (var controller in _controllers) {
+        controller.addError(error);
+      }
+    }, onDone: () {
+      _isClosed = true;
+      for (var controller in _controllers) {
+        controller.close();
+      }
+      _controllers.clear();
+    });
+  }
+
+  /// Returns a stream that replays the values and errors of the input stream.
+  ///
+  /// This stream is a buffered stream regardless of whether the input stream
+  /// was broadcast or buffered.
+  Stream<T> getReplay() {
+    var controller = new StreamController<T>();
+    for (var eventOrError in _buffer) {
+      eventOrError.match(controller.add, controller.addError);
+    }
+    if (_isClosed) {
+      controller.close();
+    } else {
+      _controllers.add(controller);
+    }
+    return controller.stream;
+  }
+}
diff --git a/pkg/barback/lib/src/utils.dart b/pkg/barback/lib/src/utils.dart
index 3272e9e..0a41c8e 100644
--- a/pkg/barback/lib/src/utils.dart
+++ b/pkg/barback/lib/src/utils.dart
@@ -23,6 +23,52 @@
   int get hashCode => first.hashCode ^ last.hashCode;
 }
 
+/// A class that represents one and only one of two types of values.
+class Either<E, F> {
+  /// Whether this is a value of type `E`.
+  final bool isFirst;
+
+  /// Whether this is a value of type `F`.
+  bool get isSecond => !isFirst;
+
+  /// The value, either of type `E` or `F`.
+  final _value;
+
+  /// The value of type `E`.
+  ///
+  /// It's an error to access this is this is of type `F`.
+  E get first {
+    assert(isFirst);
+    return _value;
+  }
+
+  /// The value of type `F`.
+  ///
+  /// It's an error to access this is this is of type `E`.
+  F get second {
+    assert(isSecond);
+    return _value;
+  }
+
+  /// Creates an [Either] with type `E`.
+  Either.withFirst(this._value)
+      : isFirst = true;
+
+  /// Creates an [Either] with type `F`.
+  Either.withSecond(this._value)
+      : isFirst = false;
+
+  /// Runs [whenFirst] or [whenSecond] depending on the type of [this].
+  ///
+  /// Returns the result of whichvever function was run.
+  match(whenFirst(E value), whenSecond(F value)) {
+    if (isFirst) return whenFirst(first);
+    return whenSecond(second);
+  }
+
+  String toString() => "$_value (${isFirst? 'first' : 'second'})";
+}
+
 /// Converts a number in the range [0-255] to a two digit hex string.
 ///
 /// For example, given `255`, returns `ff`.
@@ -77,14 +123,18 @@
   set1.length == set2.length && set1.containsAll(set2);
 
 /// Merges [streams] into a single stream that emits events from all sources.
-Stream mergeStreams(Iterable<Stream> streams) {
+///
+/// If [broadcast] is true, this will return a broadcast stream; otherwise, it
+/// will return a buffered stream.
+Stream mergeStreams(Iterable<Stream> streams, {bool broadcast: false}) {
   streams = streams.toList();
   var doneCount = 0;
   // Use a sync stream to preserve the synchrony behavior of the input streams.
   // If the inputs are sync, then this will be sync as well; if the inputs are
   // async, then the events we receive will also be async, and forwarding them
   // sync won't change that.
-  var controller = new StreamController(sync: true);
+  var controller = broadcast ? new StreamController.broadcast(sync: true)
+      : new StreamController(sync: true);
 
   for (var stream in streams) {
     stream.listen((value) {
diff --git a/pkg/barback/test/asset_test.dart b/pkg/barback/test/asset_test.dart
index b26d462..5563ebf 100644
--- a/pkg/barback/test/asset_test.dart
+++ b/pkg/barback/test/asset_test.dart
@@ -5,9 +5,8 @@
 library barback.test.asset_test;
 
 import 'dart:async';
-import 'dart:convert' show Encoding, UTF8, LATIN1;
+import 'dart:convert';
 import 'dart:io';
-import 'dart:utf';
 
 import 'package:barback/barback.dart';
 import 'package:path/path.dart' as pathos;
@@ -24,7 +23,7 @@
   Directory tempDir;
   String binaryFilePath;
   String textFilePath;
-  String utf32FilePath;
+  String latin1FilePath;
 
   setUp(() {
     // Create a temp file we can use for assets.
@@ -35,8 +34,8 @@
     textFilePath = pathos.join(tempDir.path, "file.txt");
     new File(textFilePath).writeAsStringSync("çøñ†éℵ™");
 
-    utf32FilePath = pathos.join(tempDir.path, "file.utf32");
-    new File(utf32FilePath).writeAsBytesSync(encodeUtf32("çøñ†éℵ™"));
+    latin1FilePath = pathos.join(tempDir.path, "file.latin1");
+    new File(latin1FilePath).writeAsBytesSync(LATIN1.encode("blåbærgrød"));
   });
 
   tearDown(() {
@@ -73,11 +72,19 @@
     });
   });
 
+  group("Asset.fromStream", () {
+    test("returns an asset with the given ID", () {
+      var asset = new Asset.fromStream(id,
+          new Stream.fromFuture(new Future.value([104, 101, 108, 108, 111])));
+      expect(asset.id, equals(id));
+    });
+  });
+
   group("read()", () {
     test("gets the UTF-8-encoded string for a string asset", () {
       var asset = new Asset.fromString(id, "çøñ†éℵ™");
       expect(asset.read().toList(),
-          completion(equals([encodeUtf8("çøñ†éℵ™")])));
+          completion(equals([UTF8.encode("çøñ†éℵ™")])));
     });
 
     test("gets the raw bytes for a byte asset", () {
@@ -95,20 +102,27 @@
     test("gets the raw bytes for a text file", () {
       var asset = new Asset.fromPath(id, textFilePath);
       expect(asset.read().toList(),
-          completion(equals([encodeUtf8("çøñ†éℵ™")])));
+          completion(equals([UTF8.encode("çøñ†éℵ™")])));
+    });
+
+    test("gets the raw bytes for a stream", () {
+      var asset = new Asset.fromStream(id,
+          new Stream.fromFuture(new Future.value(UTF8.encode("çøñ†éℵ™"))));
+      expect(asset.read().toList(),
+          completion(equals([UTF8.encode("çøñ†éℵ™")])));
     });
   });
 
   group("readAsString()", () {
     group("byte asset", () {
       test("defaults to UTF-8 if encoding is omitted", () {
-        var asset = new Asset.fromBytes(id, encodeUtf8("çøñ†éℵ™"));
+        var asset = new Asset.fromBytes(id, UTF8.encode("çøñ†éℵ™"));
         expect(asset.readAsString(),
             completion(equals("çøñ†éℵ™")));
       });
 
       test("supports UTF-8", () {
-        var asset = new Asset.fromBytes(id, encodeUtf8("çøñ†éℵ™"));
+        var asset = new Asset.fromBytes(id, UTF8.encode("çøñ†éℵ™"));
         expect(asset.readAsString(encoding: UTF8),
             completion(equals("çøñ†éℵ™")));
       });
@@ -137,6 +151,29 @@
             completion(equals("çøñ†éℵ™")));
       });
     });
+
+    group("stream asset", () {
+      test("defaults to UTF-8 if encoding is omitted", () {
+        var asset = new Asset.fromStream(id,
+            new Stream.fromFuture(new Future.value(UTF8.encode("çøñ†éℵ™"))));
+        expect(asset.readAsString(),
+            completion(equals("çøñ†éℵ™")));
+      });
+
+      test("supports UTF-8", () {
+        var asset = new Asset.fromStream(id,
+            new Stream.fromFuture(new Future.value(UTF8.encode("çøñ†éℵ™"))));
+        expect(asset.readAsString(encoding: UTF8),
+            completion(equals("çøñ†éℵ™")));
+      });
+
+      test("supports ISO-8859-1", () {
+        var future = new Future.value(LATIN1.encode("blåbærgrød"));
+        var asset = new Asset.fromStream(id, new Stream.fromFuture(future));
+        expect(asset.readAsString(encoding: LATIN1),
+            completion(equals("blåbærgrød")));
+      });
+    });
   });
 
   group("toString()", () {
diff --git a/pkg/barback/test/stream_replayer_test.dart b/pkg/barback/test/stream_replayer_test.dart
new file mode 100644
index 0000000..f341a29
--- /dev/null
+++ b/pkg/barback/test/stream_replayer_test.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library barback.test.stream_replayer_test;
+
+import 'dart:async';
+
+import 'package:barback/src/stream_replayer.dart';
+import 'package:barback/src/utils.dart';
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+main() {
+  initConfig();
+
+  test("a replay that's retrieved before the stream is finished replays the "
+      "stream", () {
+    var controller = new StreamController<int>();
+    var replay = new StreamReplayer<int>(controller.stream).getReplay();
+
+    controller.add(1);
+    controller.add(2);
+    controller.add(3);
+    controller.close();
+
+    expect(replay.toList(), completion(equals([1, 2, 3])));
+  });
+
+  test("a replay that's retrieved after the stream is finished replays the "
+      "stream", () {
+    var controller = new StreamController<int>();
+    var replayer = new StreamReplayer<int>(controller.stream);
+
+    controller.add(1);
+    controller.add(2);
+    controller.add(3);
+    controller.close();
+
+    expect(replayer.getReplay().toList(), completion(equals([1, 2, 3])));
+  });
+
+  test("multiple replays each replay the stream", () {
+    var controller = new StreamController<int>();
+    var replayer = new StreamReplayer<int>(controller.stream);
+
+    var replay1 = replayer.getReplay();
+    controller.add(1);
+    controller.add(2);
+    controller.add(3);
+    controller.close();
+    var replay2 = replayer.getReplay();
+
+    expect(replay1.toList(), completion(equals([1, 2, 3])));
+    expect(replay2.toList(), completion(equals([1, 2, 3])));
+  });
+
+  test("the replayed stream doesn't close until the source stream closes", () {
+    var controller = new StreamController<int>();
+    var replay = new StreamReplayer<int>(controller.stream).getReplay();
+    var isClosed = false;
+    replay.last.then((_) {
+      isClosed = true;
+    });
+
+    controller.add(1);
+    controller.add(2);
+    controller.add(3);
+
+    expect(pumpEventQueue().then((_) {
+      expect(isClosed, isFalse);
+      controller.close();
+      return pumpEventQueue();
+    }).then((_) {
+      expect(isClosed, isTrue);
+    }), completes);
+  });
+}
diff --git a/pkg/barback/test/utils.dart b/pkg/barback/test/utils.dart
index 1ee03ff..798b958 100644
--- a/pkg/barback/test/utils.dart
+++ b/pkg/barback/test/utils.dart
@@ -39,6 +39,7 @@
   if (_configured) return;
   _configured = true;
   useCompactVMConfiguration();
+  filterStacks = true;
 }
 
 /// Creates a new [PackageProvider] and [PackageGraph] with the given [assets]
diff --git a/pkg/csslib/test/compiler_test.dart b/pkg/csslib/test/compiler_test.dart
index ee37f29..f545a6d 100644
--- a/pkg/csslib/test/compiler_test.dart
+++ b/pkg/csslib/test/compiler_test.dart
@@ -4,7 +4,7 @@
 
 library compiler_test;
 
-import 'dart:utf';
+import 'dart:convert';
 import 'package:unittest/unittest.dart';
 import 'package:csslib/parser.dart';
 import 'package:csslib/visitor.dart';
@@ -521,7 +521,7 @@
       'color : #00F578; border-color: #878787;'
     '}]]>';
 
-  var stylesheet = parse(encodeUtf8(input), errors: errors);
+  var stylesheet = parse(UTF8.encode(input), errors: errors);
 
   expect(stylesheet != null, true);
   expect(errors.isEmpty, true, reason: errors.toString());
diff --git a/pkg/csslib/test/nested_test.dart b/pkg/csslib/test/nested_test.dart
index e6b0025..5423644 100644
--- a/pkg/csslib/test/nested_test.dart
+++ b/pkg/csslib/test/nested_test.dart
@@ -4,7 +4,6 @@
 
 library nested_test;
 
-import 'dart:utf';
 import 'package:unittest/unittest.dart';
 import 'package:csslib/parser.dart';
 import 'package:csslib/visitor.dart';
diff --git a/pkg/csslib/test/var_test.dart b/pkg/csslib/test/var_test.dart
index fb870c7..afdc570 100644
--- a/pkg/csslib/test/var_test.dart
+++ b/pkg/csslib/test/var_test.dart
@@ -4,7 +4,6 @@
 
 library var_test;
 
-import 'dart:utf';
 import 'package:unittest/unittest.dart';
 import 'package:csslib/parser.dart';
 import 'package:csslib/visitor.dart';
@@ -207,7 +206,7 @@
 }
 
 .test-2 {
-  background: var(color-background) var(image-2, url('img_1.png')) 
+  background: var(color-background) var(image-2, url('img_1.png'))
               no-repeat right top;
 }
 
@@ -322,38 +321,44 @@
 
   expect(stylesheet != null, true);
   expect(errors.length, 8, reason: errors.toString());
-  expect(errors[0].toString(),
+  int testBitMap = 0;
+  var errorStrings = [
       'error :14:3: var cycle detected var-six\n'
       '  var-six: var(four);\n'
-      '  ^^^^^^^^^^^^^^^^^^');
-  expect(errors[1].toString(),
+      '  ^^^^^^^^^^^^^^^^^^',
       'error :18:3: var cycle detected var-def-3\n'
       '  var-def-3: var(def-2);\n'
-      '  ^^^^^^^^^^^^^^^^^^^^^');
-  expect(errors[2].toString(),
+      '  ^^^^^^^^^^^^^^^^^^^^^',
       'error :10:3: var cycle detected var-two\n'
       '  var-two: var(one);\n'
-      '  ^^^^^^^^^^^^^^^^^');
-  expect(errors[3].toString(),
+      '  ^^^^^^^^^^^^^^^^^',
       'error :17:3: var cycle detected var-def-2\n'
       '  var-def-2: var(def-3);\n'
-      '  ^^^^^^^^^^^^^^^^^^^^^');
-  expect(errors[4].toString(),
+      '  ^^^^^^^^^^^^^^^^^^^^^',
       'error :16:3: var cycle detected var-def-1\n'
       '  var-def-1: var(def-2);\n'
-      '  ^^^^^^^^^^^^^^^^^^^^^');
-  expect(errors[5].toString(),
+      '  ^^^^^^^^^^^^^^^^^^^^^',
       'error :13:3: var cycle detected var-five\n'
       '  var-five: var(six);\n'
-      '  ^^^^^^^^^^^^^^^^^^');
-  expect(errors[6].toString(),
+      '  ^^^^^^^^^^^^^^^^^^',
       'error :9:3: var cycle detected var-one\n'
       '  var-one: var(two);\n'
-      '  ^^^^^^^^^^^^^^^^^');
-  expect(errors[7].toString(),
+      '  ^^^^^^^^^^^^^^^^^',
       'error :12:3: var cycle detected var-four\n'
       '  var-four: var(five);\n'
-      '  ^^^^^^^^^^^^^^^^^^^');
+      '  ^^^^^^^^^^^^^^^^^^^'
+  ];
+  outer: for (var error in errors) {
+    var errorString = error.toString();
+    for (int i = 0; i < 8; i++) {
+      if (errorString == errorStrings[i]) {
+        testBitMap |= 1 << i;
+        continue outer;
+      }
+    }
+    fail("Unexpected error string: $errorString");
+  }
+  expect(testBitMap, equals((1 << 8) - 1));
   expect(prettyPrint(stylesheet), generated);
 }
 
diff --git a/pkg/csslib/test/visitor_test.dart b/pkg/csslib/test/visitor_test.dart
index e60dbc5..7fcde97 100644
--- a/pkg/csslib/test/visitor_test.dart
+++ b/pkg/csslib/test/visitor_test.dart
@@ -4,7 +4,6 @@
 
 library visitor_test;
 
-import 'dart:utf';
 import 'package:unittest/unittest.dart';
 import 'package:csslib/parser.dart';
 import 'package:csslib/visitor.dart';
diff --git a/pkg/custom_element/lib/custom_element.dart b/pkg/custom_element/lib/custom_element.dart
index 4121dbf..db0c3b8 100644
--- a/pkg/custom_element/lib/custom_element.dart
+++ b/pkg/custom_element/lib/custom_element.dart
@@ -313,6 +313,20 @@
     host.innerHtml = v;
   }
 
+  void setInnerHtml(String html,
+    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    host.setInnerHtml(html, validator: validator, treeSanitizer: treeSanitizer);
+  }
+
+  void set unsafeInnerHtml(String html) {
+    host.unsafeInnerHtml = html;
+  }
+
+  DocumentFragment createFragment(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) =>
+    host.createFragment(html,
+        validator: validator, treeSanitizer: treeSanitizer);
+
   InputMethodContext get inputMethodContext => host.inputMethodContext;
 
   bool get isContentEditable => host.isContentEditable;
@@ -414,10 +428,6 @@
 
   ElementList queryAll(String selectors) => host.queryAll(selectors);
 
-  HtmlCollection get $dom_children => host.$dom_children;
-
-  int get $dom_childElementCount => host.$dom_childElementCount;
-
   String get className => host.className;
   set className(String value) { host.className = value; }
 
@@ -435,10 +445,6 @@
 
   Rect get client => host.client;
 
-  Element get $dom_firstElementChild => host.$dom_firstElementChild;
-
-  Element get $dom_lastElementChild => host.$dom_lastElementChild;
-
   @deprecated
   int get offsetHeight => offset.height;
 
@@ -476,12 +482,6 @@
     host.$dom_setAttributeNS(namespaceUri, localName, value);
   }
 
-  bool $dom_hasAttributeNS(String namespaceUri, String localName) =>
-      host.$dom_hasAttributeNS(namespaceUri, localName);
-
-  void $dom_removeAttributeNS(String namespaceUri, String localName) =>
-      host.$dom_removeAttributeNS(namespaceUri, localName);
-
   Rect getBoundingClientRect() => host.getBoundingClientRect();
 
   List<Rect> getClientRects() => host.getClientRects();
@@ -489,23 +489,9 @@
   List<Node> getElementsByClassName(String name) =>
       host.getElementsByClassName(name);
 
-  List<Node> $dom_getElementsByTagName(String name) =>
-      host.$dom_getElementsByTagName(name);
-
-  bool $dom_hasAttribute(String name) =>
-      host.$dom_hasAttribute(name);
-
-  List<Node> $dom_querySelectorAll(String selectors) =>
-      host.$dom_querySelectorAll(selectors);
-
-  void $dom_removeAttribute(String name) =>
-      host.$dom_removeAttribute(name);
-
   void $dom_setAttribute(String name, String value) =>
       host.$dom_setAttribute(name, value);
 
-  get $dom_attributes => host.$dom_attributes;
-
   List<Node> get $dom_childNodes => host.$dom_childNodes;
 
   Node get firstChild => host.firstChild;
@@ -513,10 +499,8 @@
   Node get lastChild => host.lastChild;
 
   String get localName => host.localName;
-  String get $dom_localName => host.$dom_localName;
 
   String get namespaceUri => host.namespaceUri;
-  String get $dom_namespaceUri => host.$dom_namespaceUri;
 
   int get nodeType => host.nodeType;
 
@@ -527,16 +511,11 @@
 
   bool dispatchEvent(Event event) => host.dispatchEvent(event);
 
-  Node $dom_removeChild(Node oldChild) => host.$dom_removeChild(oldChild);
-
   void $dom_removeEventListener(String type, EventListener listener,
                                 [bool useCapture]) {
     host.$dom_removeEventListener(type, listener, useCapture);
   }
 
-  Node $dom_replaceChild(Node newChild, Node oldChild) =>
-      host.$dom_replaceChild(newChild, oldChild);
-
   get xtag => host.xtag;
 
   set xtag(value) { host.xtag = value; }
@@ -547,22 +526,6 @@
 
   void appendHtml(String html) => host.appendHtml(html);
 
-  void $dom_scrollIntoView([bool alignWithTop]) {
-    if (alignWithTop == null) {
-      host.$dom_scrollIntoView();
-    } else {
-      host.$dom_scrollIntoView(alignWithTop);
-    }
-  }
-
-  void $dom_scrollIntoViewIfNeeded([bool centerIfNeeded]) {
-    if (centerIfNeeded == null) {
-      host.$dom_scrollIntoViewIfNeeded();
-    } else {
-      host.$dom_scrollIntoViewIfNeeded(centerIfNeeded);
-    }
-  }
-
   String get regionOverset => host.regionOverset;
 
   List<Range> getRegionFlowRanges() => host.getRegionFlowRanges();
diff --git a/pkg/custom_element/test/custom_element_test.dart b/pkg/custom_element/test/custom_element_test.dart
index e2f920a..341713a 100644
--- a/pkg/custom_element/test/custom_element_test.dart
+++ b/pkg/custom_element/test/custom_element_test.dart
@@ -25,7 +25,8 @@
 customElementTests() {
   test('register creates the element and calls lifecycle methods', () {
     // Add element to the page.
-    var element = new Element.html('<fancy-button>foo bar</fancy-button>');
+    var element = new Element.html('<fancy-button>foo bar</fancy-button>',
+        treeSanitizer: new NullTreeSanitizer());
     document.body.nodes.add(element);
 
     var xtag = null;
@@ -91,3 +92,10 @@
     lifecycle.add('removed');
   }
 }
+
+/**
+ * Sanitizer which does nothing.
+ */
+class NullTreeSanitizer implements NodeTreeSanitizer {
+  void sanitizeTree(Node node) {}
+}
diff --git a/pkg/fixnum/lib/src/int32.dart b/pkg/fixnum/lib/src/int32.dart
index fb78a48..85fbdc4 100644
--- a/pkg/fixnum/lib/src/int32.dart
+++ b/pkg/fixnum/lib/src/int32.dart
@@ -45,7 +45,7 @@
   static const int _CC_A = 65; // 'A'.codeUnitAt(0)
   static const int _CC_Z = 90; // 'Z'.codeUnitAt(0)
 
-  static int _decodeHex(int c) {
+  static int _decodeDigit(int c) {
     if (c >= _CC_0 && c <= _CC_9) {
       return c - _CC_0;
     } else if (c >= _CC_a && c <= _CC_z) {
@@ -69,7 +69,7 @@
     Int32 x = ZERO;
     for (int i = 0; i < s.length; i++) {
       int c = s.codeUnitAt(i);
-      int digit = _decodeHex(c);
+      int digit = _decodeDigit(c);
       if (digit < 0 || digit >= radix) {
         throw new Exception("Non-radix code unit: $c");
       }
diff --git a/pkg/fixnum/lib/src/int64.dart b/pkg/fixnum/lib/src/int64.dart
index 1a9d73a..036a06b 100644
--- a/pkg/fixnum/lib/src/int64.dart
+++ b/pkg/fixnum/lib/src/int64.dart
@@ -26,9 +26,9 @@
   static const int _BITS01 = 44; // 2 * _BITS
   static const int _BITS2 = 20; // 64 - _BITS01
   static const int _MASK = 4194303; // (1 << _BITS) - 1
-  static const int _MASK_2 = 1048575; // (1 << _BITS2) - 1
+  static const int _MASK2 = 1048575; // (1 << _BITS2) - 1
   static const int _SIGN_BIT = 19; // _BITS2 - 1
-  static const int _SIGN_BIT_VALUE = 524288; // 1 << _SIGN_BIT
+  static const int _SIGN_BIT_MASK = 524288; // 1 << _SIGN_BIT
 
   // Cached constants
   static Int64 _MAX_VALUE;
@@ -37,27 +37,6 @@
   static Int64 _ONE;
   static Int64 _TWO;
 
-  // Precompute the radix strings for MIN_VALUE to avoid the problem
-  // of overflow of -MIN_VALUE.
-  static List<String> _minValues = const <String>[
-      null, null,
-      "-1000000000000000000000000000000000000000000000000000000000000000", // 2
-      "-2021110011022210012102010021220101220222", // base 3
-      "-20000000000000000000000000000000", // base 4
-      "-1104332401304422434310311213", // base 5
-      "-1540241003031030222122212", // base 6
-      "-22341010611245052052301", // base 7
-      "-1000000000000000000000", // base 8
-      "-67404283172107811828", // base 9
-      "-9223372036854775808", // base 10
-      "-1728002635214590698", // base 11
-      "-41A792678515120368", // base 12
-      "-10B269549075433C38", // base 13
-      "-4340724C6C71DC7A8", // base 14
-      "-160E2AD3246366808", // base 15
-      "-8000000000000000" // base 16
-  ];
-
   // The remainder of the last divide operation.
   static Int64 _remainder;
 
@@ -67,7 +46,7 @@
    */
   static Int64 get MAX_VALUE {
     if (_MAX_VALUE == null) {
-      _MAX_VALUE = new Int64._bits(_MASK, _MASK, _MASK_2 >> 1);
+      _MAX_VALUE = new Int64._bits(_MASK, _MASK, _MASK2 >> 1);
     }
     return _MAX_VALUE;
   }
@@ -78,7 +57,7 @@
    */
   static Int64 get MIN_VALUE {
     if (_MIN_VALUE == null) {
-      _MIN_VALUE = new Int64._bits(0, 0, _SIGN_BIT_VALUE);
+      _MIN_VALUE = new Int64._bits(0, 0, _SIGN_BIT_MASK);
     }
     return _MIN_VALUE;
   }
@@ -114,41 +93,67 @@
   }
 
   /**
-   * Parses a [String] in a given [radix] between 2 and 16 and returns an
+   * Parses a [String] in a given [radix] between 2 and 36 and returns an
    * [Int64].
    */
-  // TODO(rice) - make this faster by converting several digits at once.
   static Int64 parseRadix(String s, int radix) {
-    if ((radix <= 1) || (radix > 16)) {
+    if ((radix <= 1) || (radix > 36)) {
       throw new ArgumentError("Bad radix: $radix");
     }
-    Int64 x = ZERO;
+    return _parseRadix(s, radix);
+  }
+
+  static Int64 _parseRadix(String s, int radix) {
     int i = 0;
     bool negative = false;
     if (s[0] == '-') {
       negative = true;
       i++;
     }
+    int d0 = 0, d1 = 0, d2 = 0;  //  low, middle, high components.
     for (; i < s.length; i++) {
       int c = s.codeUnitAt(i);
-      int digit = Int32._decodeHex(c);
+      int digit = Int32._decodeDigit(c);
       if (digit < 0 || digit >= radix) {
         throw new Exception("Non-radix char code: $c");
       }
-      x = (x * radix) + digit;
+
+      // [radix] and [digit] are at most 6 bits, component is 22, so we can
+      // multiply and add within 30 bit temporary values.
+      d0 = d0 * radix + digit;
+      int carry = d0 >> _BITS;
+      d0 &= _MASK;
+
+      d1 = d1 * radix + carry;
+      carry = d1 >> _BITS;
+      d1 &= _MASK;
+
+      d2 = d2 * radix + carry;
+      d2 &= _MASK2;
     }
-    return negative ? -x : x;
+
+    if (negative) {
+      d0 = 0 - d0;
+      int borrow = (d0 >> _BITS) & 1;
+      d0 &= _MASK;
+      d1 = 0 - d1 - borrow;
+      borrow = (d1 >> _BITS) & 1;
+      d1 &= _MASK;
+      d2 = 0 - d2 - borrow;
+      d2 &= _MASK2;
+    }
+    return new Int64._bits(d0, d1, d2);
   }
 
   /**
    * Parses a decimal [String] and returns an [Int64].
    */
-  static Int64 parseInt(String s) => parseRadix(s, 10);
+  static Int64 parseInt(String s) => _parseRadix(s, 10);
 
   /**
    * Parses a hexadecimal [String] and returns an [Int64].
    */
-  static Int64 parseHex(String s) => parseRadix(s, 16);
+  static Int64 parseHex(String s) => _parseRadix(s, 16);
 
   //
   // Public constructors
@@ -171,7 +176,7 @@
     if (_haveBigInts) {
       _l = value & _MASK;
       _m = (value >> _BITS) & _MASK;
-      _h = (value >> _BITS01) & _MASK_2;
+      _h = (value >> _BITS01) & _MASK2;
     } else {
       // Avoid using bitwise operations that coerce their input to 32 bits.
       _h = value ~/ 17592186044416; // 2^44
@@ -184,7 +189,7 @@
     if (negative) {
       _l = ~_l & _MASK;
       _m = ~_m & _MASK;
-      _h = ~_h & _MASK_2;
+      _h = ~_h & _MASK2;
     }
   }
 
@@ -232,12 +237,13 @@
    * Constructs an [Int64] from a pair of 32-bit integers having the value
    * [:((top & 0xffffffff) << 32) | (bottom & 0xffffffff):].
    */
-  Int64.fromInts(int top, int bottom) {
+  factory Int64.fromInts(int top, int bottom) {
     top &= 0xffffffff;
     bottom &= 0xffffffff;
-    _l = bottom & _MASK;
-    _m = ((top & 0xfff) << 10) | ((bottom >> _BITS) & 0x3ff);
-    _h = (top >> 12) & _MASK_2;
+    int d0 = bottom & _MASK;
+    int d1 = ((top & 0xfff) << 10) | ((bottom >> _BITS) & 0x3ff);
+    int d2 = (top >> 12) & _MASK2;
+    return new Int64._bits(d0, d1, d2);
   }
 
   // Returns the [Int64] representation of the specified value. Throws
@@ -259,7 +265,7 @@
     int sum1 = _m + o._m + _shiftRight(sum0, _BITS);
     int sum2 = _h + o._h + _shiftRight(sum1, _BITS);
 
-    Int64 result = new Int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK_2);
+    Int64 result = new Int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK2);
     return result;
   }
 
@@ -269,7 +275,7 @@
     int sum1 = _m - o._m + _shiftRight(sum0, _BITS);
     int sum2 = _h - o._h + _shiftRight(sum1, _BITS);
 
-    Int64 result = new Int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK_2);
+    Int64 result = new Int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK2);
     return result;
   }
 
@@ -279,7 +285,7 @@
     int sum1 = -_m + _shiftRight(sum0, _BITS);
     int sum2 = -_h + _shiftRight(sum1, _BITS);
 
-    return new Int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK_2);
+    return new Int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK2);
   }
 
   Int64 operator *(other) {
@@ -361,7 +367,7 @@
     c0 &= _MASK;
     c2 += c1 >> _BITS;
     c1 &= _MASK;
-    c2 &= _MASK_2;
+    c2 &= _MASK2;
 
     return new Int64._bits(c0, c1, c2);
   }
@@ -415,7 +421,7 @@
   }
 
   Int64 operator ~() {
-    var result = new Int64._bits((~_l) & _MASK, (~_m) & _MASK, (~_h) & _MASK_2);
+    var result = new Int64._bits((~_l) & _MASK, (~_m) & _MASK, (~_h) & _MASK2);
     return result;
   }
 
@@ -440,7 +446,7 @@
       res2 = _l << (n - _BITS01);
     }
 
-    return new Int64._bits(res0 & _MASK, res1 & _MASK, res2 & _MASK_2);
+    return new Int64._bits(res0 & _MASK, res1 & _MASK, res2 & _MASK2);
   }
 
   Int64 operator >>(int n) {
@@ -453,7 +459,7 @@
 
     // Sign extend h(a).
     int a2 = _h;
-    bool negative = (a2 & _SIGN_BIT_VALUE) != 0;
+    bool negative = (a2 & _SIGN_BIT_MASK) != 0;
     if (negative) {
       a2 += 0x3 << _BITS2; // add extra one bits on the left
     }
@@ -461,19 +467,19 @@
     if (n < _BITS) {
       res2 = _shiftRight(a2, n);
       if (negative) {
-        res2 |= _MASK_2 & ~(_MASK_2 >> n);
+        res2 |= _MASK2 & ~(_MASK2 >> n);
       }
       res1 = _shiftRight(_m, n) | (a2 << (_BITS - n));
       res0 = _shiftRight(_l, n) | (_m << (_BITS - n));
     } else if (n < _BITS01) {
-      res2 = negative ? _MASK_2 : 0;
+      res2 = negative ? _MASK2 : 0;
       res1 = _shiftRight(a2, n - _BITS);
       if (negative) {
         res1 |= _MASK & ~(_MASK >> (n - _BITS));
       }
       res0 = _shiftRight(_m, n - _BITS) | (a2 << (_BITS01 - n));
     } else {
-      res2 = negative ? _MASK_2 : 0;
+      res2 = negative ? _MASK2 : 0;
       res1 = negative ? _MASK : 0;
       res0 = _shiftRight(a2, n - _BITS01);
       if (negative) {
@@ -481,7 +487,7 @@
       }
     }
 
-    return new Int64._bits(res0 & _MASK, res1 & _MASK, res2 & _MASK_2);
+    return new Int64._bits(res0 & _MASK, res1 & _MASK, res2 & _MASK2);
   }
 
   Int64 shiftRightUnsigned(int n) {
@@ -491,7 +497,7 @@
     n &= 63;
 
     int res0, res1, res2;
-    int a2 = _h & _MASK_2; // Ensure a2 is positive.
+    int a2 = _h & _MASK2; // Ensure a2 is positive.
     if (n < _BITS) {
       res2 = a2 >> n;
       res1 = (_m >> n) | (a2 << (_BITS - n));
@@ -506,7 +512,7 @@
       res0 = a2 >> (n - _BITS01);
     }
 
-    return new Int64._bits(res0 & _MASK, res1 & _MASK, res2 & _MASK_2);
+    return new Int64._bits(res0 & _MASK, res1 & _MASK, res2 & _MASK2);
   }
 
   /**
@@ -570,8 +576,8 @@
   }
 
   bool get isEven => (_l & 0x1) == 0;
-  bool get isMaxValue => (_h == _MASK_2 >> 1) && _m == _MASK && _l == _MASK;
-  bool get isMinValue => _h == _SIGN_BIT_VALUE && _m == 0 && _l == 0;
+  bool get isMaxValue => (_h == _MASK2 >> 1) && _m == _MASK && _l == _MASK;
+  bool get isMinValue => _h == _SIGN_BIT_MASK && _m == 0 && _l == 0;
   bool get isNegative => (_h >> (_BITS2 - 1)) != 0;
   bool get isOdd => (_l & 0x1) == 1;
   bool get isZero => _h == 0 && _m == 0 && _l == 0;
@@ -648,10 +654,10 @@
     int m = _m;
     int h = _h;
     bool negative = false;
-    if ((_h & _SIGN_BIT_VALUE) != 0) {
+    if ((_h & _SIGN_BIT_MASK) != 0) {
       l = ~_l & _MASK;
       m = ~_m & _MASK;
-      h = ~_h & _MASK_2;
+      h = ~_h & _MASK2;
       negative = true;
     }
 
@@ -679,33 +685,7 @@
   /**
    * Returns the value of this [Int64] as a decimal [String].
    */
-  // TODO(rice) - Make this faster by converting several digits at once.
-  String toString() {
-    Int64 a = this;
-    if (a.isZero) {
-      return "0";
-    }
-    if (a.isMinValue) {
-      return "-9223372036854775808";
-    }
-
-    String result = "";
-    bool negative = false;
-    if (a.isNegative) {
-      negative = true;
-      a = -a;
-    }
-
-    Int64 ten = new Int64._bits(10, 0, 0);
-    while (!a.isZero) {
-      a = _divMod(a, ten, true);
-      result = "${_remainder._l}$result";
-    }
-    if (negative) {
-      result = "-$result";
-    }
-    return result;
-  }
+  String toString() => _toRadixString(10);
 
   // TODO(rice) - Make this faster by avoiding arithmetic.
   String toHexString() {
@@ -724,32 +704,152 @@
   }
 
   String toRadixString(int radix) {
-    if ((radix <= 1) || (radix > 16)) {
+    if ((radix <= 1) || (radix > 36)) {
       throw new ArgumentError("Bad radix: $radix");
     }
-    Int64 a = this;
-    if (a.isZero) {
-      return "0";
-    }
-    if (a.isMinValue) {
-      return _minValues[radix];
-    }
-
-    String result = "";
-    bool negative = false;
-    if (a.isNegative) {
-      negative = true;
-      a = -a;
-    }
-
-    Int64 r = new Int64._bits(radix, 0, 0);
-    while (!a.isZero) {
-      a = _divMod(a, r, true);
-      result = "${_hexDigit(_remainder._l)}$result";
-    }
-    return negative ? "-$result" : result;
+    return _toRadixString(radix);
   }
 
+  String _toRadixString(int radix) {
+    int d0 = _l;
+    int d1 = _m;
+    int d2 = _h;
+
+    if (d0 == 0 && d1 == 0 && d2 == 0) return '0';
+
+    String sign = '';
+    if ((d2 & _SIGN_BIT_MASK) != 0) {
+      sign = '-';
+
+      // Negate in-place.
+      d0 = 0 - d0;
+      int borrow = (d0 >> _BITS) & 1;
+      d0 &= _MASK;
+      d1 = 0 - d1 - borrow;
+      borrow = (d1 >> _BITS) & 1;
+      d1 &= _MASK;
+      d2 = 0 - d2 - borrow;
+      d2 &= _MASK2;
+      // d2, d1, d0 now are an unsigned 64 bit integer for MIN_VALUE and an
+      // unsigned 63 bit integer for other values.
+    }
+
+    // Rearrange components into five components where all but the most
+    // significant are 10 bits wide.
+    //
+    //     d4, d3, d4, d1, d0:  24 + 10 + 10 + 10 + 10 bits
+    //
+    // The choice of 10 bits allows a remainder of 20 bits to be scaled by 10
+    // bits and added during division while keeping all intermediate values
+    // within 30 bits (unsigned small integer range for 32 bit implementations
+    // of Dart VM and V8).
+    //
+    //     6  6         5         4         3         2         1
+    //     3210987654321098765432109876543210987654321098765432109876543210
+    //     [--------d2--------][---------d1---------][---------d0---------]
+    //  -->
+    //     [----------d4----------][---d3---][---d2---][---d1---][---d0---]
+
+
+    int d4 = (d2 << 4) | (d1 >> 18);
+    int d3 = (d1 >> 8) & 0x3ff;
+    d2 = ((d1 << 2) | (d0 >> 20)) & 0x3ff;
+    d1 = (d0 >> 10) & 0x3ff;
+    d0 = d0 & 0x3ff;
+
+    int fatRadix = _fatRadixTable[radix];
+
+    // Generate chunks of digits.  In radix 10, generate 6 digits per chunk.
+    //
+    // This loop generates at most 3 chunks, so we store the chunks in locals
+    // rather than a list.  We are trying to generate digits 20 bits at a time
+    // until we have only 30 bits left.  20 + 20 + 30 > 64 would imply that we
+    // need only two chunks, but radix values 17-19 and 33-36 generate only 15
+    // or 16 bits per iteration, so sometimes the third chunk is needed.
+
+    String chunk1 = "", chunk2 = "", chunk3 = "";
+
+    while (!(d4 == 0 && d3 == 0)) {
+      int q = d4 ~/ fatRadix;
+      int r = d4 - q * fatRadix;
+      d4 = q;
+      d3 += r << 10;
+
+      q = d3 ~/ fatRadix;
+      r = d3 - q * fatRadix;
+      d3 = q;
+      d2 += r << 10;
+
+      q = d2 ~/ fatRadix;
+      r = d2 - q * fatRadix;
+      d2 = q;
+      d1 += r << 10;
+
+      q = d1 ~/ fatRadix;
+      r = d1 - q * fatRadix;
+      d1 = q;
+      d0 += r << 10;
+
+      q = d0 ~/ fatRadix;
+      r = d0 - q * fatRadix;
+      d0 = q;
+
+      assert(chunk2 == "");
+      chunk3 = chunk2;
+      chunk2 = chunk1;
+      // Adding [fatRadix] Forces an extra digit which we discard to get a fixed
+      // width.  E.g.  (1000000 + 123) -> "1000123" -> "000123".  An alternative
+      // would be to pad to the left with zeroes.
+      chunk1 = (fatRadix + r).toRadixString(radix).substring(1);
+    }
+    int residue = (d2 << 20) + (d1 << 10) + d0;
+    String leadingDigits = residue == 0 ? '' : residue.toRadixString(radix);
+    return '$sign$leadingDigits$chunk1$chunk2$chunk3';
+  }
+
+  // Table of 'fat' radix values.  Each entry for index `i` is the largest power
+  // of `i` whose remainder fits in 20 bits.
+  static const _fatRadixTable = const <int>[
+      0,
+      0,
+      2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2
+        * 2,
+      3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3,
+      4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4,
+      5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+      6 * 6 * 6 * 6 * 6 * 6 * 6,
+      7 * 7 * 7 * 7 * 7 * 7 * 7,
+      8 * 8 * 8 * 8 * 8 * 8,
+      9 * 9 * 9 * 9 * 9 * 9,
+      10 * 10 * 10 * 10 * 10 * 10,
+      11 * 11 * 11 * 11 * 11,
+      12 * 12 * 12 * 12 * 12,
+      13 * 13 * 13 * 13 * 13,
+      14 * 14 * 14 * 14 * 14,
+      15 * 15 * 15 * 15 * 15,
+      16 * 16 * 16 * 16 * 16,
+      17 * 17 * 17 * 17,
+      18 * 18 * 18 * 18,
+      19 * 19 * 19 * 19,
+      20 * 20 * 20 * 20,
+      21 * 21 * 21 * 21,
+      22 * 22 * 22 * 22,
+      23 * 23 * 23 * 23,
+      24 * 24 * 24 * 24,
+      25 * 25 * 25 * 25,
+      26 * 26 * 26 * 26,
+      27 * 27 * 27 * 27,
+      28 * 28 * 28 * 28,
+      29 * 29 * 29 * 29,
+      30 * 30 * 30 * 30,
+      31 * 31 * 31 * 31,
+      32 * 32 * 32 * 32,
+      33 * 33 * 33,
+      34 * 34 * 34,
+      35 * 35 * 35,
+      36 * 36 * 36
+  ];
+
   String toDebugString() {
     return "Int64[_l=$_l, _m=$_m, _h=$_h]";
   }
@@ -763,11 +863,10 @@
   /**
    * Constructs an [Int64] with the same value as an existing [Int64].
    */
-  Int64._copy(Int64 other) {
-    _l = other._l;
-    _m = other._m;
-    _h = other._h;
-  }
+  Int64._copy(Int64 other)
+      : _l = other._l,
+        _m = other._m,
+        _h = other._h;
 
   // Determine whether the platform supports ints greater than 2^53
   // without loss of precision.
@@ -795,7 +894,7 @@
   void _negate() {
     int neg0 = (~_l + 1) & _MASK;
     int neg1 = (~_m + (neg0 == 0 ? 1 : 0)) & _MASK;
-    int neg2 = (~_h + ((neg0 == 0 && neg1 == 0) ? 1 : 0)) & _MASK_2;
+    int neg2 = (~_h + ((neg0 == 0 && neg1 == 0) ? 1 : 0)) & _MASK2;
 
     _l = neg0;
     _m = neg1;
@@ -865,7 +964,7 @@
 
     a._l = sum0 & _MASK;
     a._m = sum1 & _MASK;
-    a._h = sum2 & _MASK_2;
+    a._h = sum2 & _MASK2;
 
     return true;
   }
diff --git a/pkg/fixnum/test/int_64_test.dart b/pkg/fixnum/test/int_64_test.dart
index 545de3c..20f2822 100644
--- a/pkg/fixnum/test/int_64_test.dart
+++ b/pkg/fixnum/test/int_64_test.dart
@@ -529,6 +529,41 @@
     expect(-(Int64.MIN_VALUE + new Int64.fromInt(1)), Int64.MAX_VALUE);
   });
 
+  group("parse", () {
+    test("parseRadix10", () {
+      checkInt(int x) {
+        expect(Int64.parseRadix('$x', 10), new Int64.fromInt(x));
+      }
+      checkInt(0);
+      checkInt(1);
+      checkInt(-1);
+      checkInt(1000);
+      checkInt(12345678);
+      checkInt(-12345678);
+      checkInt(2147483647);
+      checkInt(2147483648);
+      checkInt(-2147483647);
+      checkInt(-2147483648);
+      checkInt(4294967295);
+      checkInt(4294967296);
+      checkInt(-4294967295);
+      checkInt(-4294967296);
+    });
+
+    test("parseRadix", () {
+      check(String s, int r, String x) {
+        expect(Int64.parseRadix(s, r).toString(), x);
+      }
+      check('ghoul', 36, '27699213');
+      check('ghoul', 35, '24769346');
+      // Min and max value.
+      check("-9223372036854775808", 10, "-9223372036854775808");
+      check("9223372036854775807", 10, "9223372036854775807");
+      // Overflow during parsing.
+      check("9223372036854775808", 10, "-9223372036854775808");
+    });
+  });
+
   group("string representation", () {
     test("toString", () {
       expect(new Int64.fromInt(0).toString(), "0");
@@ -571,10 +606,10 @@
       expect(Int64.MIN_VALUE.toRadixString(9), "-67404283172107811828");
       expect(Int64.MIN_VALUE.toRadixString(10), "-9223372036854775808");
       expect(Int64.MIN_VALUE.toRadixString(11), "-1728002635214590698");
-      expect(Int64.MIN_VALUE.toRadixString(12), "-41A792678515120368");
-      expect(Int64.MIN_VALUE.toRadixString(13), "-10B269549075433C38");
-      expect(Int64.MIN_VALUE.toRadixString(14), "-4340724C6C71DC7A8");
-      expect(Int64.MIN_VALUE.toRadixString(15), "-160E2AD3246366808");
+      expect(Int64.MIN_VALUE.toRadixString(12), "-41a792678515120368");
+      expect(Int64.MIN_VALUE.toRadixString(13), "-10b269549075433c38");
+      expect(Int64.MIN_VALUE.toRadixString(14), "-4340724c6c71dc7a8");
+      expect(Int64.MIN_VALUE.toRadixString(15), "-160e2ad3246366808");
       expect(Int64.MIN_VALUE.toRadixString(16), "-8000000000000000");
       expect(Int64.MAX_VALUE.toRadixString(2),
           "111111111111111111111111111111111111111111111111111111111111111");
@@ -589,11 +624,11 @@
       expect(Int64.MAX_VALUE.toRadixString(9), "67404283172107811827");
       expect(Int64.MAX_VALUE.toRadixString(10), "9223372036854775807");
       expect(Int64.MAX_VALUE.toRadixString(11), "1728002635214590697");
-      expect(Int64.MAX_VALUE.toRadixString(12), "41A792678515120367");
-      expect(Int64.MAX_VALUE.toRadixString(13), "10B269549075433C37");
-      expect(Int64.MAX_VALUE.toRadixString(14), "4340724C6C71DC7A7");
-      expect(Int64.MAX_VALUE.toRadixString(15), "160E2AD3246366807");
-      expect(Int64.MAX_VALUE.toRadixString(16), "7FFFFFFFFFFFFFFF");
+      expect(Int64.MAX_VALUE.toRadixString(12), "41a792678515120367");
+      expect(Int64.MAX_VALUE.toRadixString(13), "10b269549075433c37");
+      expect(Int64.MAX_VALUE.toRadixString(14), "4340724c6c71dc7a7");
+      expect(Int64.MAX_VALUE.toRadixString(15), "160e2ad3246366807");
+      expect(Int64.MAX_VALUE.toRadixString(16), "7fffffffffffffff");
     });
   });
 }
diff --git a/pkg/http/lib/src/multipart_request.dart b/pkg/http/lib/src/multipart_request.dart
index e0c413a..5bbd5b3 100644
--- a/pkg/http/lib/src/multipart_request.dart
+++ b/pkg/http/lib/src/multipart_request.dart
@@ -5,8 +5,8 @@
 library multipart_request;
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:math';
-import 'dart:utf';
 
 import 'base_request.dart';
 import 'byte_stream.dart';
@@ -62,7 +62,7 @@
     fields.forEach((name, value) {
       length += "--".length + _BOUNDARY_LENGTH + "\r\n".length +
           _headerForField(name, value).length +
-          encodeUtf8(value).length + "\r\n".length;
+          UTF8.encode(value).length + "\r\n".length;
     });
 
     for (var file in _files) {
@@ -95,7 +95,7 @@
       controller.add(string.codeUnits);
     }
 
-    writeUtf8(String string) => controller.add(encodeUtf8(string));
+    writeUtf8(String string) => controller.add(UTF8.encode(string));
     writeLine() => controller.add([13, 10]); // \r\n
 
     fields.forEach((name, value) {
diff --git a/pkg/http/lib/src/request.dart b/pkg/http/lib/src/request.dart
index 8aacbe3..f247f00 100644
--- a/pkg/http/lib/src/request.dart
+++ b/pkg/http/lib/src/request.dart
@@ -121,7 +121,7 @@
           'content-type "application/x-www-form-urlencoded".');
     }
 
-    return queryToMap(body);
+    return queryToMap(body, encoding: encoding);
   }
 
   set bodyFields(Map<String, String> fields) {
@@ -132,7 +132,7 @@
           'content-type "${_contentType.value}".');
     }
 
-    this.body = mapToQuery(fields);
+    this.body = mapToQuery(fields, encoding: encoding);
   }
 
   /// Creates a new HTTP request.
diff --git a/pkg/http/lib/src/utils.dart b/pkg/http/lib/src/utils.dart
index cf2096d..fdfa05b 100644
--- a/pkg/http/lib/src/utils.dart
+++ b/pkg/http/lib/src/utils.dart
@@ -16,13 +16,14 @@
 ///
 ///     queryToMap("foo=bar&baz=bang&qux");
 ///     //=> {"foo": "bar", "baz": "bang", "qux": ""}
-Map<String, String> queryToMap(String queryList) {
+Map<String, String> queryToMap(String queryList, {Encoding encoding}) {
   var map = {};
   for (var pair in queryList.split("&")) {
     var split = split1(pair, "=");
     if (split.isEmpty) continue;
-    var key = urlDecode(split[0]);
-    var value = urlDecode(split.length > 1 ? split[1] : "");
+    var key = Uri.decodeQueryComponent(split[0], decode: encoding.decode);
+    var value = Uri.decodeQueryComponent(split.length > 1 ? split[1] : "",
+        decode: encoding.decode);
     map[key] = value;
   }
   return map;
@@ -32,18 +33,34 @@
 ///
 ///     mapToQuery({"foo": "bar", "baz": "bang"});
 ///     //=> "foo=bar&baz=bang"
-String mapToQuery(Map<String, String> map) {
+String mapToQuery(Map<String, String> map, {Encoding encoding}) {
   var pairs = <List<String>>[];
   map.forEach((key, value) =>
-      pairs.add([Uri.encodeQueryComponent(key),
-                 Uri.encodeQueryComponent(value)]));
+      pairs.add([urlEncode(key, encoding: encoding),
+                 urlEncode(value, encoding: encoding)]));
   return pairs.map((pair) => "${pair[0]}=${pair[1]}").join("&");
 }
 
-/// Decodes a URL-encoded string. Unlike [Uri.decodeComponent], this includes
-/// replacing `+` with ` `.
-String urlDecode(String encoded) =>
-  Uri.decodeComponent(encoded.replaceAll("+", " "));
+// TODO(nweiz): get rid of this when issue 12780 is fixed.
+/// URL-encodes [source] using [encoding].
+String urlEncode(String source, {Encoding encoding}) {
+  if (encoding == null) encoding = UTF8;
+  return encoding.encode(source).map((byte) {
+    // Convert spaces to +, like encodeQueryComponent.
+    if (byte == 0x20) return '+';
+    // Pass through digits.
+    if ((byte >= 0x30 && byte < 0x3A) ||
+        // Pass through uppercase letters.
+        (byte >= 0x41 && byte < 0x5B) ||
+        // Pass through lowercase letters.
+        (byte >= 0x61 && byte < 0x7B) ||
+        // Pass through `-._~`.
+        (byte == 0x2D || byte == 0x2E || byte == 0x5F || byte == 0x7E)) {
+      return new String.fromCharCode(byte);
+    }
+    return '%' + byte.toRadixString(16).toUpperCase();
+  }).join();
+}
 
 /// Like [String.split], but only splits on the first occurrence of the pattern.
 /// This will always return an array of two elements or fewer.
diff --git a/pkg/http/test/multipart_test.dart b/pkg/http/test/multipart_test.dart
index cdbb4cd..c42b810 100644
--- a/pkg/http/test/multipart_test.dart
+++ b/pkg/http/test/multipart_test.dart
@@ -5,8 +5,8 @@
 library multipart_test;
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
-import 'dart:utf';
 
 import 'package:http/http.dart' as http;
 import 'package:path/path.dart' as path;
@@ -29,7 +29,7 @@
     if (item is! http.MultipartRequest) return false;
 
     var future = item.finalize().toBytes().then((bodyBytes) {
-      var body = decodeUtf8(bodyBytes);
+      var body = UTF8.decode(bodyBytes);
       var contentType = ContentType.parse(item.headers['content-type']);
       var boundary = contentType.parameters['boundary'];
       var expected = cleanUpLiteral(_pattern)
@@ -145,11 +145,22 @@
         '''));
   });
 
-  // TODO(nweiz): test creating a multipart file with a charset other than UTF-8
-  // once issue 6284 is fixed.
+  test('with a file with a iso-8859-1 body', () {
+    var request = new http.MultipartRequest('POST', dummyUrl);
+    // "Ã¥" encoded as ISO-8859-1 and then read as UTF-8 results in "å".
+    var file = new http.MultipartFile.fromString('file', 'non-ascii: "Ã¥"',
+        contentType: new ContentType('text', 'plain', charset: 'iso-8859-1'));
+    request.files.add(file);
 
-  // TODO(nweiz): test creating a string with a unicode body once issue 6284 is
-  // fixed.
+    expect(request, bodyMatches('''
+        --{{boundary}}
+        content-type: text/plain; charset=iso-8859-1
+        content-disposition: form-data; name="file"
+
+        non-ascii: "å"
+        --{{boundary}}--
+        '''));
+  });
 
   test('with a stream file', () {
     var request = new http.MultipartRequest('POST', dummyUrl);
diff --git a/pkg/http/test/request_test.dart b/pkg/http/test/request_test.dart
index 4761dc0..929cc63 100644
--- a/pkg/http/test/request_test.dart
+++ b/pkg/http/test/request_test.dart
@@ -136,8 +136,19 @@
       expect(request.body, equals("hello"));
     });
 
-    // TODO(nweiz): test that both the getter and the setter respect #encoding
-    // when issue 6284 is fixed.
+    test('is encoded according to the given encoding', () {
+      var request = new http.Request('POST', dummyUrl);
+      request.encoding = LATIN1;
+      request.body = "föøbãr";
+      expect(request.bodyBytes, equals([102, 246, 248, 98, 227, 114]));
+    });
+
+    test('is decoded according to the given encoding', () {
+      var request = new http.Request('POST', dummyUrl);
+      request.encoding = LATIN1;
+      request.bodyBytes = [102, 246, 248, 98, 227, 114];
+      expect(request.body, equals("föøbãr"));
+    });
   });
 
   group('#bodyFields', () {
@@ -180,8 +191,23 @@
           equals({'key 1': 'value', 'key 2': 'other+value'}));
     });
 
-    // TODO(nweiz): test that both the getter and the setter respect #encoding
-    // when issue 6284 is fixed.
+    test('is encoded according to the given encoding', () {
+      var request = new http.Request('POST', dummyUrl);
+      request.headers[HttpHeaders.CONTENT_TYPE] =
+          'application/x-www-form-urlencoded';
+      request.encoding = LATIN1;
+      request.bodyFields = {"föø": "bãr"};
+      expect(request.body, equals('f%F6%F8=b%E3r'));
+    });
+
+    test('is decoded according to the given encoding', () {
+      var request = new http.Request('POST', dummyUrl);
+      request.headers[HttpHeaders.CONTENT_TYPE] =
+          'application/x-www-form-urlencoded';
+      request.encoding = LATIN1;
+      request.body = 'f%F6%F8=b%E3r';
+      expect(request.bodyFields, equals({"föø": "bãr"}));
+    });
   });
 
   test('#followRedirects', () {
diff --git a/pkg/http/test/response_test.dart b/pkg/http/test/response_test.dart
index 531ac02..bc1f33d 100644
--- a/pkg/http/test/response_test.dart
+++ b/pkg/http/test/response_test.dart
@@ -22,8 +22,12 @@
           [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33]));
     });
 
-    // TODO(nweiz): test that this respects the inferred encoding when issue
-    // 6284 is fixed.
+    test('respects the inferred encoding', () {
+      var response = new http.Response("föøbãr", 200,
+          headers: {'content-type': 'text/plain; charset=iso-8859-1'});
+      expect(response.bodyBytes, equals(
+          [102, 246, 248, 98, 227, 114]));
+    });
   });
 
   group('.bytes()', () {
@@ -37,8 +41,11 @@
       expect(response.bodyBytes, equals([104, 101, 108, 108, 111]));
     });
 
-    // TODO(nweiz): test that this respects the inferred encoding when issue
-    // 6284 is fixed.
+    test('respects the inferred encoding', () {
+      var response = new http.Response.bytes([102, 246, 248, 98, 227, 114], 200,
+          headers: {'content-type': 'text/plain; charset=iso-8859-1'});
+      expect(response.body, equals("föøbãr"));
+    });
   });
 
   group('.fromStream()', () {
diff --git a/pkg/intl/lib/date_symbol_data_http_request.dart b/pkg/intl/lib/date_symbol_data_http_request.dart
index 218952c..20d35a1 100644
--- a/pkg/intl/lib/date_symbol_data_http_request.dart
+++ b/pkg/intl/lib/date_symbol_data_http_request.dart
@@ -13,6 +13,7 @@
 import 'src/lazy_locale_data.dart';
 import 'src/date_format_internal.dart';
 import 'src/http_request_data_reader.dart';
+import 'intl.dart';
 
 part "src/data/dates/localeList.dart";
 
@@ -29,11 +30,13 @@
   var reader2 = new HTTPRequestDataReader('${url}patterns/');
   initializeDatePatterns(() => new LazyLocaleData(
       reader2, (x) => x, availableLocalesForDateFormatting));
+  var actualLocale = Intl.verifiedLocale(locale,
+      (l) => availableLocalesForDateFormatting.contains(l));
   return initializeIndividualLocaleDateFormatting(
       (symbols, patterns) {
         return Future.wait([
-            symbols.initLocale(locale),
-            patterns.initLocale(locale)]);
+            symbols.initLocale(actualLocale),
+            patterns.initLocale(actualLocale)]);
       });
 }
 
diff --git a/pkg/intl/test/date_time_format_http_request_test.dart b/pkg/intl/test/date_time_format_http_request_test.dart
index d36ac2b..26bd476 100644
--- a/pkg/intl/test/date_time_format_http_request_test.dart
+++ b/pkg/intl/test/date_time_format_http_request_test.dart
@@ -11,6 +11,7 @@
 
 import 'dart:html';
 import 'package:unittest/html_config.dart';
+import 'package:unittest/unittest.dart';
 import 'package:intl/date_symbol_data_http_request.dart';
 import 'date_time_format_test_stub.dart';
 
@@ -19,5 +20,9 @@
   var url = "http://localhost:${window.location.port}"
     "/root_dart/pkg/intl/lib/src/data/dates/";
 
+   test("Initializing a locale that needs fallback", () {
+     initializeDateFormatting("de_DE", url).then(expectAsync1((_) => true));
+   });
+
   runWith(smallSetOfLocales, url, initializeDateFormatting);
 }
diff --git a/pkg/intl/test/message_extraction/message_extraction_test.dart b/pkg/intl/test/message_extraction/message_extraction_test.dart
index 40c664e..e472cda 100644
--- a/pkg/intl/test/message_extraction/message_extraction_test.dart
+++ b/pkg/intl/test/message_extraction/message_extraction_test.dart
@@ -7,42 +7,14 @@
 import 'package:unittest/unittest.dart';
 import 'dart:io';
 import 'dart:async';
+import 'dart:convert';
 import 'package:path/path.dart' as path;
 import '../data_directory.dart';
 
 final dart = Platform.executable;
 
-// TODO(alanknight): We have no way of knowing what the package-root is,
-// so when we're running under the test framework, which sets the
-// package-root, we use a horrible hack and infer it from the executable.
-final packageDir = _findPackageDir(dart);
-
-/**
- * Find our package directory from the executable. If we seem to be running
- * from out/Release<arch>/dart or the equivalent Debug, then use the packages
- * directory under Release<arch>. Otherwise return null, indicating to use
- * the normal pub packages directory.
- */
-String _findPackageDir(executable) {
-  var oneUp = path.dirname(executable);
-  var tail = path.basename(oneUp);
-  // If we're running from test.dart, we want e.g. out/ReleaseIA32/packages
-  if (tail.contains('Release') || tail.contains('Debug')) {
-      return path.join(oneUp, 'packages/');
-  }
-  // Check for the case where we're running Release<arch>/dart-sdk/bin/dart
-  // (pub bots)
-  var threeUp = path.dirname(path.dirname(oneUp));
-  tail = path.basename(threeUp);
-  if (tail.contains('Release') || tail.contains('Debug')) {
-      return path.join(threeUp, 'packages/');
-  }
-  // Otherwise we will rely on the normal packages directory.
-  return null;
-}
-
-/** If our package root directory is set, return it as a VM argument. */
-final vmArgs = (packageDir == null) ? [] : ['--package-root=$packageDir'];
+/** The VM arguments we were given, most important package-root. */
+final vmArgs = Platform.executableArguments;
 
 /**
  * Translate a file path into this test directory, regardless of the
@@ -103,7 +75,8 @@
       ..add(filesInTheRightDirectory.first)
       ..addAll(["--output-dir=${dir()}"])
       ..addAll(filesInTheRightDirectory.skip(1));
-  var result = Process.run(dart, args);
+  var result = Process.run(dart, args, stdoutEncoding: UTF8,
+      stderrEncoding: UTF8);
   return result;
 }
 
diff --git a/pkg/json/README.md b/pkg/json/README.md
new file mode 100644
index 0000000..677a4d4
--- /dev/null
+++ b/pkg/json/README.md
@@ -0,0 +1,5 @@
+A JSON library for Dart.
+
+The path package provides some extensible classes for JSON manipulations. It
+is (in its original form) a copy of the `dart:json` library before that was
+deprecated.
diff --git a/pkg/json/lib/json.dart b/pkg/json/lib/json.dart
new file mode 100644
index 0000000..58b6c796d
--- /dev/null
+++ b/pkg/json/lib/json.dart
@@ -0,0 +1,828 @@
+// Copyright (c) 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.
+
+/**
+ * Utilities for encoding and decoding JSON (JavaScript Object Notation) data.
+ */
+
+library json;
+
+// JSON parsing and serialization.
+
+/**
+ * Error thrown by JSON serialization if an object cannot be serialized.
+ *
+ * The [unsupportedObject] field holds that object that failed to be serialized.
+ *
+ * If an object isn't directly serializable, the serializer calls the 'toJson'
+ * method on the object. If that call fails, the error will be stored in the
+ * [cause] field. If the call returns an object that isn't directly
+ * serializable, the [cause] will be null.
+ */
+class JsonUnsupportedObjectError extends Error {
+  /** The object that could not be serialized. */
+  final unsupportedObject;
+  /** The exception thrown by object's [:toJson:] method, if any. */
+  final cause;
+
+  JsonUnsupportedObjectError(this.unsupportedObject, { this.cause });
+
+  String toString() {
+    if (cause != null) {
+      return "Calling toJson method on object failed.";
+    } else {
+      return "Object toJson method returns non-serializable value.";
+    }
+  }
+}
+
+
+/**
+ * Reports that an object could not be stringified due to cyclic references.
+ *
+ * An object that references itself cannot be serialized by [stringify].
+ * When the cycle is detected, a [JsonCyclicError] is thrown.
+ */
+class JsonCyclicError extends JsonUnsupportedObjectError {
+  /** The first object that was detected as part of a cycle. */
+  JsonCyclicError(Object object): super(object);
+  String toString() => "Cyclic error in JSON stringify";
+}
+
+
+/**
+ * Parses [json] and build the corresponding parsed JSON value.
+ *
+ * Parsed JSON values are of the types [num], [String], [bool], [Null],
+ * [List]s of parsed JSON values or [Map]s from [String] to parsed
+ * JSON values.
+ *
+ * The optional [reviver] function, if provided, is called once for each
+ * object or list property parsed. The arguments are the property name
+ * ([String]) or list index ([int]), and the value is the parsed value.
+ * The return value of the reviver will be used as the value of that property
+ * instead the parsed value.
+ *
+ * Throws [FormatException] if the input is not valid JSON text.
+ */
+parse(String json, [reviver(var key, var value)]) {
+  BuildJsonListener listener;
+  if (reviver == null) {
+    listener = new BuildJsonListener();
+  } else {
+    listener = new ReviverJsonListener(reviver);
+  }
+  new JsonParser(json, listener).parse();
+  return listener.result;
+}
+
+/**
+ * Serializes [object] into a JSON string.
+ *
+ * Directly serializable values are [num], [String], [bool], and [Null], as well
+ * as some [List] and [Map] values.
+ * For [List], the elements must all be serializable.
+ * For [Map], the keys must be [String] and the values must be serializable.
+ *
+ * If a value is any other type is attempted serialized, a "toJson()" method
+ * is invoked on the object and the result, which must be a directly
+ * serializable value, is serialized instead of the original value.
+ *
+ * If the object does not support this method, throws, or returns a
+ * value that is not directly serializable, a [JsonUnsupportedObjectError]
+ * exception is thrown. If the call throws (including the case where there
+ * is no nullary "toJson" method, the error is caught and stored in the
+ * [JsonUnsupportedObjectError]'s [:cause:] field.
+ *
+ * If a [List] or [Map] contains a reference to itself, directly or through
+ * other lists or maps, it cannot be serialized and a [JsonCyclicError] is
+ * thrown.
+ *
+ * Json Objects should not change during serialization.
+ * If an object is serialized more than once, [stringify] is allowed to cache
+ * the JSON text for it. I.e., if an object changes after it is first
+ * serialized, the new values may or may not be reflected in the result.
+ */
+String stringify(Object object) {
+  return _JsonStringifier.stringify(object);
+}
+
+/**
+ * Serializes [object] into [output] stream.
+ *
+ * Performs the same operations as [stringify] but outputs the resulting
+ * string to an existing [StringSink] instead of creating a new [String].
+ *
+ * If serialization fails by throwing, some data might have been added to
+ * [output], but it won't contain valid JSON text.
+ */
+void printOn(Object object, StringSink output) {
+  return _JsonStringifier.printOn(object, output);
+}
+
+//// Implementation ///////////////////////////////////////////////////////////
+
+// Simple API for JSON parsing.
+
+abstract class JsonListener {
+  void handleString(String value) {}
+  void handleNumber(num value) {}
+  void handleBool(bool value) {}
+  void handleNull() {}
+  void beginObject() {}
+  void propertyName() {}
+  void propertyValue() {}
+  void endObject() {}
+  void beginArray() {}
+  void arrayElement() {}
+  void endArray() {}
+  /** Called on failure to parse [source]. */
+  void fail(String source, int position, String message) {}
+}
+
+/**
+ * A [JsonListener] that builds data objects from the parser events.
+ *
+ * This is a simple stack-based object builder. It keeps the most recently
+ * seen value in a variable, and uses it depending on the following event.
+ */
+class BuildJsonListener extends JsonListener {
+  /**
+   * Stack used to handle nested containers.
+   *
+   * The current container is pushed on the stack when a new one is
+   * started. If the container is a [Map], there is also a current [key]
+   * which is also stored on the stack.
+   */
+  List stack = [];
+  /** The current [Map] or [List] being built. */
+  var currentContainer;
+  /** The most recently read property key. */
+  String key;
+  /** The most recently read value. */
+  var value;
+
+  /** Pushes the currently active container (and key, if a [Map]). */
+  void pushContainer() {
+    if (currentContainer is Map) stack.add(key);
+    stack.add(currentContainer);
+  }
+
+  /** Pops the top container from the [stack], including a key if applicable. */
+  void popContainer() {
+    value = currentContainer;
+    currentContainer = stack.removeLast();
+    if (currentContainer is Map) key = stack.removeLast();
+  }
+
+  void handleString(String value) { this.value = value; }
+  void handleNumber(num value) { this.value = value; }
+  void handleBool(bool value) { this.value = value; }
+  void handleNull() { this.value = null; }
+
+  void beginObject() {
+    pushContainer();
+    currentContainer = {};
+  }
+
+  void propertyName() {
+    key = value;
+    value = null;
+  }
+
+  void propertyValue() {
+    Map map = currentContainer;
+    map[key] = value;
+    key = value = null;
+  }
+
+  void endObject() {
+    popContainer();
+  }
+
+  void beginArray() {
+    pushContainer();
+    currentContainer = [];
+  }
+
+  void arrayElement() {
+    List list = currentContainer;
+    currentContainer.add(value);
+    value = null;
+  }
+
+  void endArray() {
+    popContainer();
+  }
+
+  /** Read out the final result of parsing a JSON string. */
+  get result {
+    assert(currentContainer == null);
+    return value;
+  }
+}
+
+typedef _Reviver(var key, var value);
+
+class ReviverJsonListener extends BuildJsonListener {
+  final _Reviver reviver;
+  ReviverJsonListener(reviver(key, value)) : this.reviver = reviver;
+
+  void arrayElement() {
+    List list = currentContainer;
+    value = reviver(list.length, value);
+    super.arrayElement();
+  }
+
+  void propertyValue() {
+    value = reviver(key, value);
+    super.propertyValue();
+  }
+
+  get result {
+    return reviver("", value);
+  }
+}
+
+class JsonParser {
+  // A simple non-recursive state-based parser for JSON.
+  //
+  // Literal values accepted in states ARRAY_EMPTY, ARRAY_COMMA, OBJECT_COLON
+  // and strings also in OBJECT_EMPTY, OBJECT_COMMA.
+  //               VALUE  STRING  :  ,  }  ]        Transitions to
+  // EMPTY            X      X                   -> END
+  // ARRAY_EMPTY      X      X             @     -> ARRAY_VALUE / pop
+  // ARRAY_VALUE                     @     @     -> ARRAY_COMMA / pop
+  // ARRAY_COMMA      X      X                   -> ARRAY_VALUE
+  // OBJECT_EMPTY            X          @        -> OBJECT_KEY / pop
+  // OBJECT_KEY                   @              -> OBJECT_COLON
+  // OBJECT_COLON     X      X                   -> OBJECT_VALUE
+  // OBJECT_VALUE                    @  @        -> OBJECT_COMMA / pop
+  // OBJECT_COMMA            X                   -> OBJECT_KEY
+  // END
+  // Starting a new array or object will push the current state. The "pop"
+  // above means restoring this state and then marking it as an ended value.
+  // X means generic handling, @ means special handling for just that
+  // state - that is, values are handled generically, only punctuation
+  // cares about the current state.
+  // Values for states are chosen so bits 0 and 1 tell whether
+  // a string/value is allowed, and setting bits 0 through 2 after a value
+  // gets to the next state (not empty, doesn't allow a value).
+
+  // State building-block constants.
+  static const int INSIDE_ARRAY = 1;
+  static const int INSIDE_OBJECT = 2;
+  static const int AFTER_COLON = 3;  // Always inside object.
+
+  static const int ALLOW_STRING_MASK = 8;  // Allowed if zero.
+  static const int ALLOW_VALUE_MASK = 4;  // Allowed if zero.
+  static const int ALLOW_VALUE = 0;
+  static const int STRING_ONLY = 4;
+  static const int NO_VALUES = 12;
+
+  // Objects and arrays are "empty" until their first property/element.
+  static const int EMPTY = 0;
+  static const int NON_EMPTY = 16;
+  static const int EMPTY_MASK = 16;  // Empty if zero.
+
+
+  static const int VALUE_READ_BITS = NO_VALUES | NON_EMPTY;
+
+  // Actual states.
+  static const int STATE_INITIAL      = EMPTY | ALLOW_VALUE;
+  static const int STATE_END          = NON_EMPTY | NO_VALUES;
+
+  static const int STATE_ARRAY_EMPTY  = INSIDE_ARRAY | EMPTY | ALLOW_VALUE;
+  static const int STATE_ARRAY_VALUE  = INSIDE_ARRAY | NON_EMPTY | NO_VALUES;
+  static const int STATE_ARRAY_COMMA  = INSIDE_ARRAY | NON_EMPTY | ALLOW_VALUE;
+
+  static const int STATE_OBJECT_EMPTY = INSIDE_OBJECT | EMPTY | STRING_ONLY;
+  static const int STATE_OBJECT_KEY   = INSIDE_OBJECT | NON_EMPTY | NO_VALUES;
+  static const int STATE_OBJECT_COLON = AFTER_COLON | NON_EMPTY | ALLOW_VALUE;
+  static const int STATE_OBJECT_VALUE = AFTER_COLON | NON_EMPTY | NO_VALUES;
+  static const int STATE_OBJECT_COMMA = INSIDE_OBJECT | NON_EMPTY | STRING_ONLY;
+
+  // Character code constants.
+  static const int BACKSPACE       = 0x08;
+  static const int TAB             = 0x09;
+  static const int NEWLINE         = 0x0a;
+  static const int CARRIAGE_RETURN = 0x0d;
+  static const int FORM_FEED       = 0x0c;
+  static const int SPACE           = 0x20;
+  static const int QUOTE           = 0x22;
+  static const int PLUS            = 0x2b;
+  static const int COMMA           = 0x2c;
+  static const int MINUS           = 0x2d;
+  static const int DECIMALPOINT    = 0x2e;
+  static const int SLASH           = 0x2f;
+  static const int CHAR_0          = 0x30;
+  static const int CHAR_9          = 0x39;
+  static const int COLON           = 0x3a;
+  static const int CHAR_E          = 0x45;
+  static const int LBRACKET        = 0x5b;
+  static const int BACKSLASH       = 0x5c;
+  static const int RBRACKET        = 0x5d;
+  static const int CHAR_a          = 0x61;
+  static const int CHAR_b          = 0x62;
+  static const int CHAR_e          = 0x65;
+  static const int CHAR_f          = 0x66;
+  static const int CHAR_l          = 0x6c;
+  static const int CHAR_n          = 0x6e;
+  static const int CHAR_r          = 0x72;
+  static const int CHAR_s          = 0x73;
+  static const int CHAR_t          = 0x74;
+  static const int CHAR_u          = 0x75;
+  static const int LBRACE          = 0x7b;
+  static const int RBRACE          = 0x7d;
+
+  final String source;
+  final JsonListener listener;
+  JsonParser(this.source, this.listener);
+
+  /** Parses [source], or throws if it fails. */
+  void parse() {
+    final List<int> states = <int>[];
+    int state = STATE_INITIAL;
+    int position = 0;
+    int length = source.length;
+    while (position < length) {
+      int char = source.codeUnitAt(position);
+      switch (char) {
+        case SPACE:
+        case CARRIAGE_RETURN:
+        case NEWLINE:
+        case TAB:
+          position++;
+          break;
+        case QUOTE:
+          if ((state & ALLOW_STRING_MASK) != 0) fail(position);
+          position = parseString(position + 1);
+          state |= VALUE_READ_BITS;
+          break;
+        case LBRACKET:
+          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+          listener.beginArray();
+          states.add(state);
+          state = STATE_ARRAY_EMPTY;
+          position++;
+          break;
+        case LBRACE:
+          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+          listener.beginObject();
+          states.add(state);
+          state = STATE_OBJECT_EMPTY;
+          position++;
+          break;
+        case CHAR_n:
+          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+          position = parseNull(position);
+          state |= VALUE_READ_BITS;
+          break;
+        case CHAR_f:
+          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+          position = parseFalse(position);
+          state |= VALUE_READ_BITS;
+          break;
+        case CHAR_t:
+          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+          position = parseTrue(position);
+          state |= VALUE_READ_BITS;
+          break;
+        case COLON:
+          if (state != STATE_OBJECT_KEY) fail(position);
+          listener.propertyName();
+          state = STATE_OBJECT_COLON;
+          position++;
+          break;
+        case COMMA:
+          if (state == STATE_OBJECT_VALUE) {
+            listener.propertyValue();
+            state = STATE_OBJECT_COMMA;
+            position++;
+          } else if (state == STATE_ARRAY_VALUE) {
+            listener.arrayElement();
+            state = STATE_ARRAY_COMMA;
+            position++;
+          } else {
+            fail(position);
+          }
+          break;
+        case RBRACKET:
+          if (state == STATE_ARRAY_EMPTY) {
+            listener.endArray();
+          } else if (state == STATE_ARRAY_VALUE) {
+            listener.arrayElement();
+            listener.endArray();
+          } else {
+            fail(position);
+          }
+          state = states.removeLast() | VALUE_READ_BITS;
+          position++;
+          break;
+        case RBRACE:
+          if (state == STATE_OBJECT_EMPTY) {
+            listener.endObject();
+          } else if (state == STATE_OBJECT_VALUE) {
+            listener.propertyValue();
+            listener.endObject();
+          } else {
+            fail(position);
+          }
+          state = states.removeLast() | VALUE_READ_BITS;
+          position++;
+          break;
+        default:
+          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+          position = parseNumber(char, position);
+          state |= VALUE_READ_BITS;
+          break;
+      }
+    }
+    if (state != STATE_END) fail(position);
+  }
+
+  /**
+   * Parses a "true" literal starting at [position].
+   *
+   * [:source[position]:] must be "t".
+   */
+  int parseTrue(int position) {
+    assert(source.codeUnitAt(position) == CHAR_t);
+    if (source.length < position + 4) fail(position, "Unexpected identifier");
+    if (source.codeUnitAt(position + 1) != CHAR_r ||
+        source.codeUnitAt(position + 2) != CHAR_u ||
+        source.codeUnitAt(position + 3) != CHAR_e) {
+      fail(position);
+    }
+    listener.handleBool(true);
+    return position + 4;
+  }
+
+  /**
+   * Parses a "false" literal starting at [position].
+   *
+   * [:source[position]:] must be "f".
+   */
+  int parseFalse(int position) {
+    assert(source.codeUnitAt(position) == CHAR_f);
+    if (source.length < position + 5) fail(position, "Unexpected identifier");
+    if (source.codeUnitAt(position + 1) != CHAR_a ||
+        source.codeUnitAt(position + 2) != CHAR_l ||
+        source.codeUnitAt(position + 3) != CHAR_s ||
+        source.codeUnitAt(position + 4) != CHAR_e) {
+      fail(position);
+    }
+    listener.handleBool(false);
+    return position + 5;
+  }
+
+  /** Parses a "null" literal starting at [position].
+   *
+   * [:source[position]:] must be "n".
+   */
+  int parseNull(int position) {
+    assert(source.codeUnitAt(position) == CHAR_n);
+    if (source.length < position + 4) fail(position, "Unexpected identifier");
+    if (source.codeUnitAt(position + 1) != CHAR_u ||
+        source.codeUnitAt(position + 2) != CHAR_l ||
+        source.codeUnitAt(position + 3) != CHAR_l) {
+      fail(position);
+    }
+    listener.handleNull();
+    return position + 4;
+  }
+
+  int parseString(int position) {
+    // Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"'
+    // Initial position is right after first '"'.
+    int start = position;
+    int char;
+    do {
+      if (position == source.length) {
+        fail(start - 1, "Unterminated string");
+      }
+      char = source.codeUnitAt(position);
+      if (char == QUOTE) {
+        listener.handleString(source.substring(start, position));
+        return position + 1;
+      }
+      if (char < SPACE) {
+        fail(position, "Control character in string");
+      }
+      position++;
+    } while (char != BACKSLASH);
+    // Backslash escape detected. Collect character codes for rest of string.
+    int firstEscape = position - 1;
+    List<int> chars = <int>[];
+    while (true) {
+      if (position == source.length) {
+        fail(start - 1, "Unterminated string");
+      }
+      char = source.codeUnitAt(position);
+      switch (char) {
+        case CHAR_b: char = BACKSPACE; break;
+        case CHAR_f: char = FORM_FEED; break;
+        case CHAR_n: char = NEWLINE; break;
+        case CHAR_r: char = CARRIAGE_RETURN; break;
+        case CHAR_t: char = TAB; break;
+        case SLASH:
+        case BACKSLASH:
+        case QUOTE:
+          break;
+        case CHAR_u:
+          int hexStart = position - 1;
+          int value = 0;
+          for (int i = 0; i < 4; i++) {
+            position++;
+            if (position == source.length) {
+              fail(start - 1, "Unterminated string");
+            }
+            char = source.codeUnitAt(position);
+            char -= 0x30;
+            if (char < 0) fail(hexStart, "Invalid unicode escape");
+            if (char < 10) {
+              value = value * 16 + char;
+            } else {
+              char = (char | 0x20) - 0x31;
+              if (char < 0 || char > 5) {
+                fail(hexStart, "Invalid unicode escape");
+              }
+              value = value * 16 + char + 10;
+            }
+          }
+          char = value;
+          break;
+        default:
+          if (char < SPACE) fail(position, "Control character in string");
+          fail(position, "Unrecognized string escape");
+      }
+      do {
+        chars.add(char);
+        position++;
+        if (position == source.length) fail(start - 1, "Unterminated string");
+        char = source.codeUnitAt(position);
+        if (char == QUOTE) {
+          String result = new String.fromCharCodes(chars);
+          if (start < firstEscape) {
+            result = "${source.substring(start, firstEscape)}$result";
+          }
+          listener.handleString(result);
+          return position + 1;
+        }
+        if (char < SPACE) {
+          fail(position, "Control character in string");
+        }
+      } while (char != BACKSLASH);
+      position++;
+    }
+  }
+
+  int _handleLiteral(start, position, isDouble) {
+    String literal = source.substring(start, position);
+    // This correctly creates -0 for doubles.
+    num value = (isDouble ? double.parse(literal) : int.parse(literal));
+    listener.handleNumber(value);
+    return position;
+  }
+
+  int parseNumber(int char, int position) {
+    // Format:
+    //  '-'?('0'|[1-9][0-9]*)('.'[0-9]+)?([eE][+-]?[0-9]+)?
+    int start = position;
+    int length = source.length;
+    bool isDouble = false;
+    if (char == MINUS) {
+      position++;
+      if (position == length) fail(position, "Missing expected digit");
+      char = source.codeUnitAt(position);
+    }
+    if (char < CHAR_0 || char > CHAR_9) {
+      fail(position, "Missing expected digit");
+    }
+    if (char == CHAR_0) {
+      position++;
+      if (position == length) return _handleLiteral(start, position, false);
+      char = source.codeUnitAt(position);
+      if (CHAR_0 <= char && char <= CHAR_9) {
+        fail(position);
+      }
+    } else {
+      do {
+        position++;
+        if (position == length) return _handleLiteral(start, position, false);
+        char = source.codeUnitAt(position);
+      } while (CHAR_0 <= char && char <= CHAR_9);
+    }
+    if (char == DECIMALPOINT) {
+      isDouble = true;
+      position++;
+      if (position == length) fail(position, "Missing expected digit");
+      char = source.codeUnitAt(position);
+      if (char < CHAR_0 || char > CHAR_9) fail(position);
+      do {
+        position++;
+        if (position == length) return _handleLiteral(start, position, true);
+        char = source.codeUnitAt(position);
+      } while (CHAR_0 <= char && char <= CHAR_9);
+    }
+    if (char == CHAR_e || char == CHAR_E) {
+      isDouble = true;
+      position++;
+      if (position == length) fail(position, "Missing expected digit");
+      char = source.codeUnitAt(position);
+      if (char == PLUS || char == MINUS) {
+        position++;
+        if (position == length) fail(position, "Missing expected digit");
+        char = source.codeUnitAt(position);
+      }
+      if (char < CHAR_0 || char > CHAR_9) {
+        fail(position, "Missing expected digit");
+      }
+      do {
+        position++;
+        if (position == length) return _handleLiteral(start, position, true);
+        char = source.codeUnitAt(position);
+      } while (CHAR_0 <= char && char <= CHAR_9);
+    }
+    return _handleLiteral(start, position, isDouble);
+  }
+
+  void fail(int position, [String message]) {
+    if (message == null) message = "Unexpected character";
+    listener.fail(source, position, message);
+    // If the listener didn't throw, do it here.
+    String slice;
+    int sliceEnd = position + 20;
+    if (sliceEnd > source.length) {
+      slice = "'${source.substring(position)}'";
+    } else {
+      slice = "'${source.substring(position, sliceEnd)}...'";
+    }
+    throw new FormatException("Unexpected character at $position: $slice");
+  }
+}
+
+
+class _JsonStringifier {
+  StringSink sink;
+  List<Object> seen;  // TODO: that should be identity set.
+
+  _JsonStringifier(this.sink) : seen = [];
+
+  static String stringify(final object) {
+    StringBuffer output = new StringBuffer();
+    _JsonStringifier stringifier = new _JsonStringifier(output);
+    stringifier.stringifyValue(object);
+    return output.toString();
+  }
+
+  static void printOn(final object, StringSink output) {
+    _JsonStringifier stringifier = new _JsonStringifier(output);
+    stringifier.stringifyValue(object);
+  }
+
+  static String numberToString(num x) {
+    return x.toString();
+  }
+
+  // ('0' + x) or ('a' + x - 10)
+  static int hexDigit(int x) => x < 10 ? 48 + x : 87 + x;
+
+  static void escape(StringSink sb, String s) {
+    final int length = s.length;
+    bool needsEscape = false;
+    final charCodes = new List<int>();
+    for (int i = 0; i < length; i++) {
+      int charCode = s.codeUnitAt(i);
+      if (charCode < 32) {
+        needsEscape = true;
+        charCodes.add(JsonParser.BACKSLASH);
+        switch (charCode) {
+        case JsonParser.BACKSPACE:
+          charCodes.add(JsonParser.CHAR_b);
+          break;
+        case JsonParser.TAB:
+          charCodes.add(JsonParser.CHAR_t);
+          break;
+        case JsonParser.NEWLINE:
+          charCodes.add(JsonParser.CHAR_n);
+          break;
+        case JsonParser.FORM_FEED:
+          charCodes.add(JsonParser.CHAR_f);
+          break;
+        case JsonParser.CARRIAGE_RETURN:
+          charCodes.add(JsonParser.CHAR_r);
+          break;
+        default:
+          charCodes.add(JsonParser.CHAR_u);
+          charCodes.add(hexDigit((charCode >> 12) & 0xf));
+          charCodes.add(hexDigit((charCode >> 8) & 0xf));
+          charCodes.add(hexDigit((charCode >> 4) & 0xf));
+          charCodes.add(hexDigit(charCode & 0xf));
+          break;
+        }
+      } else if (charCode == JsonParser.QUOTE ||
+          charCode == JsonParser.BACKSLASH) {
+        needsEscape = true;
+        charCodes.add(JsonParser.BACKSLASH);
+        charCodes.add(charCode);
+      } else {
+        charCodes.add(charCode);
+      }
+    }
+    sb.write(needsEscape ? new String.fromCharCodes(charCodes) : s);
+  }
+
+  void checkCycle(final object) {
+    // TODO: use Iterables.
+    for (int i = 0; i < seen.length; i++) {
+      if (identical(seen[i], object)) {
+        throw new JsonCyclicError(object);
+      }
+    }
+    seen.add(object);
+  }
+
+  void stringifyValue(final object) {
+    // Tries stringifying object directly. If it's not a simple value, List or
+    // Map, call toJson() to get a custom representation and try serializing
+    // that.
+    if (!stringifyJsonValue(object)) {
+      checkCycle(object);
+      try {
+        var customJson = object.toJson();
+        if (!stringifyJsonValue(customJson)) {
+          throw new JsonUnsupportedObjectError(object);
+        }
+        seen.removeLast();
+      } catch (e) {
+        throw new JsonUnsupportedObjectError(object, cause: e);
+      }
+    }
+  }
+
+  /**
+   * Serializes a [num], [String], [bool], [Null], [List] or [Map] value.
+   *
+   * Returns true if the value is one of these types, and false if not.
+   * If a value is both a [List] and a [Map], it's serialized as a [List].
+   */
+  bool stringifyJsonValue(final object) {
+    if (object is num) {
+      // TODO: use writeOn.
+      sink.write(numberToString(object));
+      return true;
+    } else if (identical(object, true)) {
+      sink.write('true');
+      return true;
+    } else if (identical(object, false)) {
+      sink.write('false');
+       return true;
+    } else if (object == null) {
+      sink.write('null');
+      return true;
+    } else if (object is String) {
+      sink.write('"');
+      escape(sink, object);
+      sink.write('"');
+      return true;
+    } else if (object is List) {
+      checkCycle(object);
+      List a = object;
+      sink.write('[');
+      if (a.length > 0) {
+        stringifyValue(a[0]);
+        // TODO: switch to Iterables.
+        for (int i = 1; i < a.length; i++) {
+          sink.write(',');
+          stringifyValue(a[i]);
+        }
+      }
+      sink.write(']');
+      seen.removeLast();
+      return true;
+    } else if (object is Map) {
+      checkCycle(object);
+      Map<String, Object> m = object;
+      sink.write('{');
+      bool first = true;
+      m.forEach((String key, Object value) {
+        if (!first) {
+          sink.write(',"');
+        } else {
+          sink.write('"');
+        }
+        escape(sink, key);
+        sink.write('":');
+        stringifyValue(value);
+        first = false;
+      });
+      sink.write('}');
+      seen.removeLast();
+      return true;
+    } else {
+      return false;
+    }
+  }
+}
diff --git a/pkg/json/pubspec.yaml b/pkg/json/pubspec.yaml
new file mode 100644
index 0000000..1ff8b89
--- /dev/null
+++ b/pkg/json/pubspec.yaml
@@ -0,0 +1,9 @@
+name: json
+author: Dart Team <misc@dartlang.org>
+description: >
+ A JSON library. Intended for advanced use where the built-in facilities are
+ too limiting.
+homepage: http://www.dartlang.org
+documentation: http://api.dartlang.org/docs/pkg/json
+dev_dependencies:
+  unittest: any
diff --git a/pkg/json/test/json_test.dart b/pkg/json/test/json_test.dart
new file mode 100644
index 0000000..d146ce3
--- /dev/null
+++ b/pkg/json/test/json_test.dart
@@ -0,0 +1,189 @@
+// 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 json_tests;
+import 'package:unittest/unittest.dart';
+import 'package:json/json.dart' as json;
+
+main() {
+  test('Parse', () {
+    // Scalars.
+    expect(json.parse(' 5 '), equals(5));
+    expect(json.parse(' -42 '), equals(-42));
+    expect(json.parse(' 3e0 '), equals(3));
+    expect(json.parse(' 3.14 '), equals(3.14));
+    expect(json.parse('true '), isTrue);
+    expect(json.parse(' false'), isFalse);
+    expect(json.parse(' null '), isNull);
+    expect(json.parse('\n\rnull\t'), isNull);
+    expect(json.parse(' "hi there\\" bob" '), equals('hi there" bob'));
+    expect(json.parse(' "" '), isEmpty);
+
+    // Lists.
+    expect(json.parse(' [] '), isEmpty);
+    expect(json.parse('[ ]'), isEmpty);
+    expect(json.parse(' [3, -4.5, true, "hi", false] '),
+      equals([3, -4.5, true, 'hi', false]));
+    // Nulls are tricky.
+    expect(json.parse('[null]'), orderedEquals([null]));
+    expect(json.parse(' [3, -4.5, null, true, "hi", false] '),
+      equals([3, -4.5, null, true, 'hi', false]));
+    expect(json.parse('[[null]]'), equals([[null]]));
+    expect(json.parse(' [ [3], [], [null], ["hi", true]] '),
+      equals([[3], [], [null], ['hi', true]]));
+
+    // Maps.
+    expect(json.parse(' {} '), isEmpty);
+    expect(json.parse('{ }'), isEmpty);
+
+    expect(json.parse(
+        ' {"x":3, "y": -4.5,  "z" : "hi","u" : true, "v": false } '),
+        equals({"x":3, "y": -4.5,  "z" : "hi", "u" : true, "v": false }));
+
+    expect(json.parse(' {"x":3, "y": -4.5,  "z" : "hi" } '),
+        equals({"x":3, "y": -4.5,  "z" : "hi" }));
+
+    expect(json.parse(' {"y": -4.5,  "z" : "hi" ,"x":3 } '),
+        equals({"y": -4.5,  "z" : "hi" ,"x":3 }));
+
+    expect(json.parse('{ " hi bob " :3, "": 4.5}'),
+        equals({ " hi bob " :3, "": 4.5}));
+
+    expect(json.parse(' { "x" : { } } '), equals({ 'x' : {}}));
+    expect(json.parse('{"x":{}}'), equals({ 'x' : {}}));
+
+    // Nulls are tricky.
+    expect(json.parse('{"w":null}'), equals({ 'w' : null}));
+
+    expect(json.parse('{"x":{"w":null}}'), equals({"x":{"w":null}}));
+
+    expect(json.parse(' {"x":3, "y": -4.5,  "z" : "hi",'
+                   '"w":null, "u" : true, "v": false } '),
+        equals({"x":3, "y": -4.5,  "z" : "hi",
+                   "w":null, "u" : true, "v": false }));
+
+    expect(json.parse('{"x": {"a":3, "b": -4.5}, "y":[{}], '
+                   '"z":"hi","w":{"c":null,"d":true}, "v":null}'),
+        equals({"x": {"a":3, "b": -4.5}, "y":[{}],
+                   "z":"hi","w":{"c":null,"d":true}, "v":null}));
+  });
+
+  test('stringify', () {
+    // Scalars.
+    expect(json.stringify(5), equals('5'));
+    expect(json.stringify(-42), equals('-42'));
+    // Dart does not guarantee a formatting for doubles,
+    // so reparse and compare to the original.
+    validateRoundTrip(3.14);
+    expect(json.stringify(true), equals('true'));
+    expect(json.stringify(false), equals('false'));
+    expect(json.stringify(null), equals('null'));
+    expect(json.stringify(' hi there" bob '), equals('" hi there\\" bob "'));
+    expect(json.stringify('hi\\there'), equals('"hi\\\\there"'));
+    // TODO(devoncarew): these tests break the dartium build
+    //expect(json.stringify('hi\nthere'), equals('"hi\\nthere"'));
+    //expect(json.stringify('hi\r\nthere'), equals('"hi\\r\\nthere"'));
+    expect(json.stringify(''), equals('""'));
+
+    // Lists.
+    expect(json.stringify([]), equals('[]'));
+    expect(json.stringify(new List(0)), equals('[]'));
+    expect(json.stringify(new List(3)), equals('[null,null,null]'));
+    validateRoundTrip([3, -4.5, null, true, 'hi', false]);
+    expect(json.stringify([[3], [], [null], ['hi', true]]),
+      equals('[[3],[],[null],["hi",true]]'));
+
+    // Maps.
+    expect(json.stringify({}), equals('{}'));
+    expect(json.stringify(new Map()), equals('{}'));
+    expect(json.stringify({'x':{}}), equals('{"x":{}}'));
+    expect(json.stringify({'x':{'a':3}}), equals('{"x":{"a":3}}'));
+
+    // Dart does not guarantee an order on the keys
+    // of a map literal, so reparse and compare to the original Map.
+    validateRoundTrip(
+        {'x':3, 'y':-4.5, 'z':'hi', 'w':null, 'u':true, 'v':false});
+    validateRoundTrip({"x":3, "y":-4.5, "z":'hi'});
+    validateRoundTrip({' hi bob ':3, '':4.5});
+    validateRoundTrip(
+        {'x':{'a':3, 'b':-4.5}, 'y':[{}], 'z':'hi', 'w':{'c':null, 'd':true},
+                  'v':null});
+
+    expect(json.stringify(new ToJson(4)), "4");
+    expect(json.stringify(new ToJson([4, "a"])), '[4,"a"]');
+    expect(json.stringify(new ToJson([4, new ToJson({"x":42})])),
+           '[4,{"x":42}]');
+
+    expect(() {
+      json.stringify([new ToJson(new ToJson(4))]);
+    }, throwsJsonError);
+
+    expect(() {
+      json.stringify([new Object()]);
+    }, throwsJsonError);
+
+  });
+
+  test('stringify throws if argument cannot be converted', () {
+    /**
+     * Checks that we get an exception (rather than silently returning null) if
+     * we try to stringify something that cannot be converted to json.
+     */
+    expect(() => json.stringify(new TestClass()), throwsJsonError);
+  });
+
+  test('stringify throws if toJson throws', () {
+    expect(() => json.stringify(new ToJsoner("bad", throws: true)),
+           throwsJsonError);
+  });
+
+  test('stringify throws if toJson returns non-serializable value', () {
+    expect(() => json.stringify(new ToJsoner(new TestClass())),
+           throwsJsonError);
+  });
+
+  test('stringify throws on cyclic values', () {
+    var a = [];
+    var b = a;
+    for (int i = 0; i < 50; i++) {
+      b = [b];
+    }
+    a.add(b);
+    expect(() => json.stringify(a), throwsJsonError);
+  });
+}
+
+class TestClass {
+  int x;
+  String y;
+
+  TestClass() : x = 3, y = 'joe' { }
+}
+
+class ToJsoner {
+  final Object returnValue;
+  final bool throws;
+  ToJsoner(this.returnValue, {this.throws});
+  Object toJson() {
+    if (throws) throw returnValue;
+    return returnValue;
+  }
+}
+
+class ToJson {
+  final object;
+  const ToJson(this.object);
+  toJson() => object;
+}
+
+var throwsJsonError =
+    throwsA(new isInstanceOf<json.JsonUnsupportedObjectError>());
+
+/**
+ * Checks that the argument can be converted to a JSON string and
+ * back, and produce something equivalent to the argument.
+ */
+validateRoundTrip(expected) {
+  expect(json.parse(json.stringify(expected)), equals(expected));
+}
diff --git a/pkg/mdv/test/custom_element_bindings_test.dart b/pkg/mdv/test/custom_element_bindings_test.dart
index 882bf16..0c277bd 100644
--- a/pkg/mdv/test/custom_element_bindings_test.dart
+++ b/pkg/mdv/test/custom_element_bindings_test.dart
@@ -32,7 +32,7 @@
 
   createTestHtml(s) {
     var div = new DivElement();
-    div.innerHtml = s;
+    div.setInnerHtml(s, treeSanitizer: new NullTreeSanitizer());
     testDiv.append(div);
 
     for (var node in div.queryAll('*')) {
@@ -273,3 +273,10 @@
   bool get isEmpty => _map.isEmpty;
   bool get isNotEmpty => _map.isNotEmpty;
 }
+
+/**
+ * Sanitizer which does nothing.
+ */
+class NullTreeSanitizer implements NodeTreeSanitizer {
+  void sanitizeTree(Node node) {}
+}
diff --git a/pkg/mdv/test/template_element_test.dart b/pkg/mdv/test/template_element_test.dart
index e90cf9c..a26d62b 100644
--- a/pkg/mdv/test/template_element_test.dart
+++ b/pkg/mdv/test/template_element_test.dart
@@ -40,7 +40,7 @@
 
   createTestHtml(s) {
     var div = new DivElement();
-    div.innerHtml = s;
+    div.setInnerHtml(s, treeSanitizer: new NullTreeSanitizer());
     testDiv.append(div);
 
     for (var node in div.queryAll('*')) {
@@ -1779,3 +1779,10 @@
   }
   return value;
 }
+
+/**
+ * Sanitizer which does nothing.
+ */
+class NullTreeSanitizer implements NodeTreeSanitizer {
+  void sanitizeTree(Node node) {}
+}
diff --git a/pkg/mime/lib/mime.dart b/pkg/mime/lib/mime.dart
index 44c6cad..652aa85 100644
--- a/pkg/mime/lib/mime.dart
+++ b/pkg/mime/lib/mime.dart
@@ -2,6 +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.
 
+/**
+ * Help for working with file format identifiers
+ * such as `text/html` and `image/png`.
+ *
+ * More details, including a list of types, are in the Wikipedia article
+ * [Internet media type](http://en.wikipedia.org/wiki/Internet_media_type).
+ * For information on installing and importing this library, see the
+ * [mime package on pub.dartlang.org]
+ * (http://pub.dartlang.org/packages/mime).
+ */
 library mime;
 
 import 'dart:async';
diff --git a/pkg/oauth2/lib/src/credentials.dart b/pkg/oauth2/lib/src/credentials.dart
index b02f470..5bbec16 100644
--- a/pkg/oauth2/lib/src/credentials.dart
+++ b/pkg/oauth2/lib/src/credentials.dart
@@ -81,8 +81,7 @@
     var parsed;
     try {
       parsed = JSON.parse(json);
-    } catch (e) {
-      // TODO(nweiz): narrow this catch clause once issue 6775 is fixed.
+    } on FormatException catch (e) {
       validate(false, 'invalid JSON');
     }
 
diff --git a/pkg/oauth2/lib/src/handle_access_token_response.dart b/pkg/oauth2/lib/src/handle_access_token_response.dart
index 5e5f6e2..c14b8d1e 100644
--- a/pkg/oauth2/lib/src/handle_access_token_response.dart
+++ b/pkg/oauth2/lib/src/handle_access_token_response.dart
@@ -40,8 +40,7 @@
   var parameters;
   try {
     parameters = JSON.parse(response.body);
-  } catch (e) {
-    // TODO(nweiz): narrow this catch clause once issue 6775 is fixed.
+  } on FormatException catch (e) {
     validate(false, 'invalid JSON');
   }
 
@@ -110,8 +109,7 @@
   var parameters;
   try {
     parameters = JSON.parse(response.body);
-  } catch (e) {
-    // TODO(nweiz): narrow this catch clause once issue 6775 is fixed.
+  } on FormatException catch (e) {
     validate(false, 'invalid JSON');
   }
 
diff --git a/pkg/observe/lib/src/path_observer.dart b/pkg/observe/lib/src/path_observer.dart
index f4f9bcd..6e31b55 100644
--- a/pkg/observe/lib/src/path_observer.dart
+++ b/pkg/observe/lib/src/path_observer.dart
@@ -45,7 +45,7 @@
     if (_isValid) {
       for (var segment in path.trim().split('.')) {
         if (segment == '') continue;
-        var index = int.parse(segment, onError: (_) => null);
+        var index = int.parse(segment, radix: 10, onError: (_) => null);
         _segments.add(index != null ? index : new Symbol(segment));
       }
     }
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 4acfd1b..f70e05a 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -73,7 +73,6 @@
 [ $runtime == vm && $system == windows ]
 docgen/test/single_library_test: Fail # Issue 11985
 intl/test/find_default_locale_standalone_test: Fail # Issue 8110
-intl/test/message_extraction/message_extraction_test: Fail # Issue 9167
 
 [ $compiler == dart2js ]
 stack_trace/test/trace_test: Pass, Timeout # Issue 11645
@@ -102,25 +101,19 @@
 # printed. Minified versions of these tests exist that test the behavior when
 # minified.
 unittest/test/*_unminified_test: Skip # DO NOT COPY THIS UNLESS YOU WORK ON DART2JS
-csslib: Pass, Crash # crashing randomly, see issue 12468
 
 [ $compiler == dart2js && $browser ]
 stack_trace/test/vm_test: Fail, OK # VM-specific traces
 crypto/test/sha256_test: Slow, Pass
 crypto/test/sha1_test: Slow, Pass
 
-[ $compiler == dart2js ]
-csslib/test/var_test: Fail # looking for VM-specific stack traces, issue 12469
-
-[ $compiler == dart2js && $runtime == drt ]
-csslib: Pass, Fail # issue 12466
-
 [ $browser ]
 analyzer_experimental/test/error_test: Fail, OK # Uses dart:io.
 analyzer_experimental/test/generated/element_test: Fail, OK # Uses dart:io.
 analyzer_experimental/test/generated/resolver_test: Fail, OK # Uses dart:io.
 analyzer_experimental/test/options_test: Fail, OK # Uses dart:io.
 analyzer_experimental/test/services/formatter_test: Fail, OK # Uses dart:io.
+analyzer_experimental/test/parse_compilation_unit_test: Fail, OK # Uses dart:io.
 barback/test/*: Fail, OK # Uses dart:io.
 http/test/client_test: Fail, OK # Uses dart:io.
 http/test/http_test: Fail, OK # Uses dart:io.
diff --git a/pkg/polymer/example/component/news/test/expected/news_index_test.html.txt b/pkg/polymer/example/component/news/test/expected/news_index_test.html.txt
index f5907ed..8a45ae6 100644
--- a/pkg/polymer/example/component/news/test/expected/news_index_test.html.txt
+++ b/pkg/polymer/example/component/news/test/expected/news_index_test.html.txt
@@ -1,5 +1,5 @@
 Content-Type: text/plain
-<html><head><style>template { display: none; }</style>
+<html><head><style shadowcssshim="">template { display: none; }</style>
   <title>Simple Web Components Example</title>
   
   <script src="../../packages/polymer/testing/testing.js"></script>
@@ -82,4 +82,5 @@
 
 
 <script type="text/javascript" src="packages/shadow_dom/shadow_dom.debug.js"></script>
+<script type="text/javascript" src="packages/browser/interop.js"></script>
 <script type="application/dart" src="news_index_test.html_bootstrap.dart"></script></body></html>
diff --git a/pkg/polymer/lib/deploy.dart b/pkg/polymer/lib/deploy.dart
new file mode 100644
index 0000000..86f157b
--- /dev/null
+++ b/pkg/polymer/lib/deploy.dart
@@ -0,0 +1,229 @@
+// 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.
+
+/**
+ * Temporary deploy command used to create a version of the app that can be
+ * compiled with dart2js and deployed. This library should go away once `pub
+ * deploy` can be configured to run barback transformers.
+ *
+ * From an application package you can run this program by calling dart with a
+ * 'package:' url to this file:
+ *
+ *    dart package:polymer/deploy.dart
+ */
+library polymer.deploy;
+
+import 'dart:async';
+import 'dart:io';
+import 'dart:json' as json;
+
+import 'package:barback/barback.dart';
+import 'package:path/path.dart' as path;
+import 'package:polymer/src/transform.dart' show phases;
+import 'package:stack_trace/stack_trace.dart';
+import 'package:yaml/yaml.dart';
+import 'package:args/args.dart';
+
+main() {
+  var args = _parseArgs();
+  if (args == null) return;
+  print('polymer/deploy.dart: creating a deploy target for "$_currentPackage"');
+  var barback = new Barback(new _PolymerDeployProvider());
+  _initializeBarback(barback);
+  _attachListeners(barback);
+  _emitAllFiles(barback, args['out']);
+}
+
+/** Tell barback which transformers to use and which assets to process. */
+void _initializeBarback(Barback barback) {
+  var assets = [];
+  for (var package in _packageDirs.keys) {
+    // Do not process packages like 'polymer' where there is nothing to do.
+    if (_ignoredPackages.contains(package)) continue;
+    barback.updateTransformers(package, phases);
+
+    // notify barback to process anything under 'lib' and 'asset'
+    for (var filepath in _listDir(package, 'lib')) {
+      assets.add(new AssetId(package, filepath));
+    }
+
+    for (var filepath in _listDir(package, 'asset')) {
+      assets.add(new AssetId(package, filepath));
+    }
+  }
+
+  // In case of the current package, include also 'web'.
+  for (var filepath in _listDir(_currentPackage, 'web')) {
+    assets.add(new AssetId(_currentPackage, filepath));
+  }
+  barback.updateSources(assets);
+}
+
+/** Return the relative path of each file under [subDir] in a [package]. */
+Iterable<String> _listDir(String package, String subDir) {
+  var packageDir = _packageDirs[package];
+  if (packageDir == null) return const [];
+  var dir = new Directory(path.join(packageDir, subDir));
+  if (!dir.existsSync()) return const [];
+  return dir.listSync(recursive: true, followLinks: false)
+      .where((f) => f is File)
+      .map((f) => path.relative(f.path, from: packageDir));
+}
+
+/** Attach error listeners on [barback] so we can report errors. */
+void _attachListeners(Barback barback) {
+  // Listen for errors and results
+  barback.errors.listen((e) {
+    var trace = getAttachedStackTrace(e);
+    if (trace != null) {
+      print(Trace.format(trace));
+    }
+    print('error running barback: $e');
+    exit(1);
+  });
+
+  barback.results.listen((result) {
+    if (!result.succeeded) {
+      print("build failed with errors: ${result.errors}");
+      exit(1);
+    }
+  });
+}
+
+/** Ensure [dirpath] exists. */
+void _ensureDir(var dirpath) {
+  new Directory(dirpath).createSync(recursive: true);
+}
+
+/**
+ * Emits all outputs of [barback] and copies files that we didn't process (like
+ * polymer's libraries).
+ */
+Future _emitAllFiles(Barback barback, String outDir) {
+  return barback.getAllAssets().then((assets) {
+    // Copy all the assets we transformed
+    var futures = [];
+    for (var asset in assets) {
+      var id = asset.id;
+      var filepath;
+      if (id.package == _currentPackage && id.path.startsWith('web/')) {
+        filepath = path.join(outDir, id.path);
+      } else if (id.path.startsWith('lib/')) {
+        filepath = path.join(outDir, 'web', 'packages', id.package,
+            id.path.substring(4));
+      } else {
+        // TODO(sigmund): do something about other assets?
+        continue;
+      }
+
+      _ensureDir(path.dirname(filepath));
+      var writer = new File(filepath).openWrite();
+      futures.add(writer.addStream(asset.read()).then((_) => writer.close()));
+    }
+    return Future.wait(futures);
+  }).then((_) {
+    // Copy also all the files we didn't process
+    var futures = [];
+    for (var package in _ignoredPackages) {
+      for (var relpath in _listDir(package, 'lib')) {
+        var inpath = path.join(_packageDirs[package], relpath);
+        var outpath = path.join(outDir, 'web', 'packages', package,
+            relpath.substring(4));
+        _ensureDir(path.dirname(outpath));
+
+        var writer = new File(outpath).openWrite();
+        futures.add(writer.addStream(new File(inpath).openRead())
+          .then((_) => writer.close()));
+      }
+    }
+    return Future.wait(futures)
+      .then((_) => print('Done! All files written to "$outDir"'));
+  });
+}
+
+/** A simple provider that reads files directly from the pub cache. */
+class _PolymerDeployProvider implements PackageProvider {
+
+  Iterable<String> get packages => _packageDirs.keys;
+  _PolymerDeployProvider();
+
+  Future<Asset> getAsset(AssetId id) =>
+      new Future.value(new Asset.fromPath(id, path.join(
+              _packageDirs[id.package],
+              // Assets always use the posix style paths
+              path.joinAll(path.posix.split(id.path)))));
+}
+
+
+/** The current package extracted from the pubspec.yaml file. */
+String _currentPackage = () {
+  var pubspec = new File('pubspec.yaml');
+  if (!pubspec.existsSync()) {
+    print('error: pubspec.yaml file not found, please run this script from '
+        'your package root directory.');
+    return null;
+  }
+  return loadYaml(pubspec.readAsStringSync())['name'];
+}();
+
+/**
+ * Maps package names to the path in the file system where to find the sources
+ * of such package. This map will contain an entry for the current package and
+ * everything it depends on (extracted via `pub list-pacakge-dirs`).
+ */
+Map<String, String> _packageDirs = () {
+  var pub = path.join(path.dirname(new Options().executable),
+      Platform.isWindows ? 'pub.bat' : 'pub');
+  var result = Process.runSync(pub, ['list-package-dirs']);
+  if (result.exitCode != 0) {
+    print("unexpected error invoking 'pub':");
+    print(result.stdout);
+    print(result.stderr);
+    exit(result.exitCode);
+  }
+  var map = json.parse(result.stdout)["packages"];
+  map.forEach((k, v) { map[k] = path.dirname(v); });
+  map[_currentPackage] = '.';
+  return map;
+}();
+
+/**
+ * Internal packages used by polymer which we can copy directly to the output
+ * folder without having to process them with barback.
+ */
+// TODO(sigmund): consider computing this list by recursively parsing
+// pubspec.yaml files in the [_packageDirs].
+Set<String> _ignoredPackages =
+    (const [ 'analyzer_experimental', 'args', 'barback', 'browser', 'csslib',
+             'custom_element', 'fancy_syntax', 'html5lib', 'html_import', 'js',
+             'logging', 'mdv', 'meta', 'mutation_observer', 'observe', 'path',
+             'polymer', 'polymer_expressions', 'serialization', 'shadow_dom',
+             'source_maps', 'stack_trace', 'unittest',
+             'unmodifiable_collection', 'yaml'
+           ]).toSet();
+
+ArgResults _parseArgs() {
+  var parser = new ArgParser()
+      ..addFlag('help', abbr: 'h', help: 'Displays this help message',
+          defaultsTo: false, negatable: false)
+      ..addOption('out', abbr: 'o', help: 'Directory where to generated files',
+          defaultsTo: 'out');
+  try {
+    var results = parser.parse(new Options().arguments);
+    if (results['help']) {
+      _showUsage(parser);
+      return null;
+    }
+    return results;
+  } on FormatException catch (e) {
+    print(e.message);
+    _showUsage(parser);
+    return null;
+  }
+}
+
+_showUsage(parser) {
+  print('Usage: dart package:polymer/deploy.dart [options]');
+  print(parser.getUsage());
+}
diff --git a/pkg/polymer/lib/polymer_element.dart b/pkg/polymer/lib/polymer_element.dart
index 297625e..14d4096 100644
--- a/pkg/polymer/lib/polymer_element.dart
+++ b/pkg/polymer/lib/polymer_element.dart
@@ -178,15 +178,13 @@
     // TODO(terry): Need to detect if ShadowCSS.js has been loaded.  Under
     //              Dartium this wouldn't exist.  However, dart:js isn't robust
     //              to use to detect in both Dartium and dart2js if Platform is
-    //              defined. Instead in Dartium it throws an exception but in
-    //              dart2js it works enough to know if Platform is defined (just
-    //              can't be used for further derefs).  This bug is described
+    //              defined.  This bug is described in
     //              https://code.google.com/p/dart/issues/detail?id=12548
     //              When fixed only use dart:js.  This is necessary under
     //              Dartium (no compile) we want to run w/o the JS polyfill.
-    try {
-      if (dartJs.context["Platform"] == null) { return; }
-    } on NoSuchMethodError catch (e) { return; }
+    if (dartJs.context == null || !dartJs.context.hasProperty('Platform')) {
+      return;
+    }
 
     var platform = js.context["Platform"];
     if (platform == null) return;
diff --git a/pkg/polymer/lib/src/emitters.dart b/pkg/polymer/lib/src/emitters.dart
index c5da7ba..e611c59 100644
--- a/pkg/polymer/lib/src/emitters.dart
+++ b/pkg/polymer/lib/src/emitters.dart
@@ -179,7 +179,7 @@
   // TODO(jmesserly): put this in the global CSS file?
   // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#css-additions
   document.head.nodes.insert(0, parseFragment(
-      '<style>template { display: none; }</style>'));
+      '<style shadowcssshim="">template { display: none; }</style>'));
 
   // Move all <element> declarations to the main HTML file
   // TODO(sigmund): remove this once we have HTMLImports implemented.
diff --git a/pkg/polymer/lib/src/file_system/console.dart b/pkg/polymer/lib/src/file_system/console.dart
index 6776745..346eb4b 100644
--- a/pkg/polymer/lib/src/file_system/console.dart
+++ b/pkg/polymer/lib/src/file_system/console.dart
@@ -5,8 +5,8 @@
 library console;
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
-import 'dart:utf';
 import 'package:polymer/src/file_system.dart';
 
 /** File system implementation for console VM (i.e. no browser). */
@@ -42,6 +42,6 @@
 
   // TODO(jmesserly): do we support any encoding other than UTF-8 for Dart?
   Future<String> readText(String path) {
-    return readTextOrBytes(path).then(decodeUtf8);
+    return readTextOrBytes(path).then(UTF8.decode);
   }
 }
diff --git a/pkg/polymer/lib/testing/testing.js b/pkg/polymer/lib/testing/testing.js
index de27047..957a48c 100644
--- a/pkg/polymer/lib/testing/testing.js
+++ b/pkg/polymer/lib/testing/testing.js
@@ -55,18 +55,35 @@
         cleanTree(n);
       }
 
-      // Remove dart-port attributes
-      if (node.attributes) {
-        for (var i = 0; i < node.attributes.length; i++) {
-          if (node.attributes[i].value.indexOf('dart-port') == 0) {
-            node.removeAttribute(i);
+      // TODO(terry): Need to remove attributes in the dart-port: namespace
+      //              these are added for JS interop. See bug
+      //              https://code.google.com/p/dart/issues/detail?id=12645
+      //              The new dart:js shouldn't need these attrs for dart2js or
+      //              Dartium (won't need with native support) then remove the
+      //              below code.
+      // Remove JS interop dart-port attributes,
+      if (node.tagName == 'HTML' && node.attributes) {
+        for (var i = node.attributes.length; i--; i >= 0) {
+          var attrNode = node.attributes[i];
+          if (attrNode && attrNode.name.indexOf('dart-port:') == 0) {
+            node.removeAttributeNode(attrNode);
           }
         }
       }
 
-      if (node.tagName == 'script' &&
-          node.textContent.indexOf('_DART_TEMPORARY_ATTACHED') >= 0)  {
-        node.parentNode.removeChild(node);
+      if (node.tagName == 'SCRIPT') {
+        if (node.textContent.indexOf('_DART_TEMPORARY_ATTACHED') >= 0)  {
+          node.parentNode.removeChild(node);
+        } else {
+          // Remove the JS Interop script.
+          var typeAttr = node.getAttributeNode("type");
+          if (typeAttr && typeAttr.value == "text/javascript") {
+            if (node.textContent.indexOf(
+                "(function() {\n  // Proxy support for js.dart.\n\n") == 0) {
+              node.parentNode.removeChild(node);
+            }
+          }
+        }
       }
     }
 
diff --git a/pkg/polymer/pubspec.yaml b/pkg/polymer/pubspec.yaml
index 78b2b66..eb03098 100644
--- a/pkg/polymer/pubspec.yaml
+++ b/pkg/polymer/pubspec.yaml
@@ -12,8 +12,8 @@
   browser: any
   csslib: any
   custom_element: any
-  html_import: any
   html5lib: any
+  html_import: any
   js: any
   logging: any
   mdv: any
@@ -24,3 +24,4 @@
   source_maps: any
   # TODO(jmesserly): make this a dev_dependency
   unittest: any
+  yaml: any
diff --git a/pkg/polymer/test/css_test.dart b/pkg/polymer/test/css_test.dart
index 1702312..9a53ef4 100644
--- a/pkg/polymer/test/css_test.dart
+++ b/pkg/polymer/test/css_test.dart
@@ -412,64 +412,62 @@
         }
       }
 
-      // Check for warning messages about var- cycles.
+      // Check for warning messages about var- cycles in no expected order.
       expect(messages.messages.length, 8);
-
-      var errorMessage = messages.messages[0];
-      expect(errorMessage.message, contains('var cycle detected var-def-1'));
-      expect(errorMessage.span, isNotNull);
-      expect(errorMessage.span.start.line, 11);
-      expect(errorMessage.span.start.column, 22);
-      expect(errorMessage.span.text, '@def-1: var(def-2)');
-
-      errorMessage = messages.messages[1];
-      expect(errorMessage.message, contains('var cycle detected var-five'));
-      expect(errorMessage.span, isNotNull);
-      expect(errorMessage.span.start.line, 8);
-      expect(errorMessage.span.start.column, 22);
-      expect(errorMessage.span.text, '@five: var(six)');
-
-      errorMessage = messages.messages[2];
-      expect(errorMessage.message, contains('var cycle detected var-six'));
-      expect(errorMessage.span, isNotNull);
-      expect(errorMessage.span.start.line, 9);
-      expect(errorMessage.span.start.column, 22);
-      expect(errorMessage.span.text, '@six: var(four)');
-
-      errorMessage = messages.messages[3];
-      expect(errorMessage.message, contains('var cycle detected var-def-3'));
-      expect(errorMessage.span, isNotNull);
-      expect(errorMessage.span.start.line, 13);
-      expect(errorMessage.span.start.column, 22);
-      expect(errorMessage.span.text, '@def-3: var(def-2)');
-
-      errorMessage = messages.messages[4];
-      expect(errorMessage.message, contains('var cycle detected var-two'));
-      expect(errorMessage.span, isNotNull);
-      expect(errorMessage.span.start.line, 5);
-      expect(errorMessage.span.start.column, 22);
-      expect(errorMessage.span.text, '@two: var(one)');
-
-      errorMessage = messages.messages[5];
-      expect(errorMessage.message, contains('var cycle detected var-def-2'));
-      expect(errorMessage.span, isNotNull);
-      expect(errorMessage.span.start.line, 12);
-      expect(errorMessage.span.start.column, 22);
-      expect(errorMessage.span.text, '@def-2: var(def-3)');
-
-      errorMessage = messages.messages[6];
-      expect(errorMessage.message, contains('var cycle detected var-one'));
-      expect(errorMessage.span, isNotNull);
-      expect(errorMessage.span.start.line, 4);
-      expect(errorMessage.span.start.column, 22);
-      expect(errorMessage.span.text, '@one: var(two)');
-
-      errorMessage = messages.messages[7];
-      expect(errorMessage.message, contains('var cycle detected var-four'));
-      expect(errorMessage.span, isNotNull);
-      expect(errorMessage.span.start.line, 7);
-      expect(errorMessage.span.start.column, 22);
-      expect(errorMessage.span.text, '@four: var(five)');
+      int testBitMap = 0;
+      for (var errorMessage in messages.messages) {
+        var message = errorMessage.message;
+        if (message.contains('var cycle detected var-def-1')) {
+          expect(errorMessage.span, isNotNull);
+          expect(errorMessage.span.start.line, 11);
+          expect(errorMessage.span.start.column, 22);
+          expect(errorMessage.span.text, '@def-1: var(def-2)');
+          testBitMap |= 1 << 0;
+        } else if (message.contains('var cycle detected var-five')) {
+          expect(errorMessage.span, isNotNull);
+          expect(errorMessage.span.start.line, 8);
+          expect(errorMessage.span.start.column, 22);
+          expect(errorMessage.span.text, '@five: var(six)');
+          testBitMap |= 1 << 1;
+        } else if (message.contains('var cycle detected var-six')) {
+          expect(errorMessage.span, isNotNull);
+          expect(errorMessage.span.start.line, 9);
+          expect(errorMessage.span.start.column, 22);
+          expect(errorMessage.span.text, '@six: var(four)');
+          testBitMap |= 1 << 2;
+        } else if (message.contains('var cycle detected var-def-3')) {
+          expect(errorMessage.span, isNotNull);
+          expect(errorMessage.span.start.line, 13);
+          expect(errorMessage.span.start.column, 22);
+          expect(errorMessage.span.text, '@def-3: var(def-2)');
+          testBitMap |= 1 << 3;
+        } else if (message.contains('var cycle detected var-two')) {
+          expect(errorMessage.span, isNotNull);
+          expect(errorMessage.span.start.line, 5);
+          expect(errorMessage.span.start.column, 22);
+          expect(errorMessage.span.text, '@two: var(one)');
+          testBitMap |= 1 << 4;
+        } else if (message.contains('var cycle detected var-def-2')) {
+          expect(errorMessage.span, isNotNull);
+          expect(errorMessage.span.start.line, 12);
+          expect(errorMessage.span.start.column, 22);
+          expect(errorMessage.span.text, '@def-2: var(def-3)');
+          testBitMap |= 1 << 5;
+        } else if (message.contains('var cycle detected var-one')) {
+          expect(errorMessage.span, isNotNull);
+          expect(errorMessage.span.start.line, 4);
+          expect(errorMessage.span.start.column, 22);
+          expect(errorMessage.span.text, '@one: var(two)');
+          testBitMap |= 1 << 6;
+        } else if (message.contains('var cycle detected var-four')) {
+          expect(errorMessage.span, isNotNull);
+          expect(errorMessage.span.start.line, 7);
+          expect(errorMessage.span.start.column, 22);
+          expect(errorMessage.span.text, '@four: var(five)');
+          testBitMap |= 1 << 7;
+        }
+      }
+      expect(testBitMap, equals((1 << 8) - 1));
     }));
   });
 }
diff --git a/pkg/scheduled_test/lib/scheduled_test.dart b/pkg/scheduled_test/lib/scheduled_test.dart
index c91aad7..0a3b2bf 100644
--- a/pkg/scheduled_test/lib/scheduled_test.dart
+++ b/pkg/scheduled_test/lib/scheduled_test.dart
@@ -196,9 +196,9 @@
 import 'src/schedule.dart';
 import 'src/schedule_error.dart';
 
-export 'package:unittest/matcher.dart' hide completes, completion;
-export 'package:unittest/unittest.dart' show
-    Configuration, logMessage, expectThrow;
+export 'package:unittest/unittest.dart' hide
+    test, solo_test, group, setUp, tearDown, unittestConfiguration,
+    currentTestCase, completes, completion;
 
 export 'src/schedule.dart';
 export 'src/schedule_error.dart';
@@ -383,3 +383,6 @@
 void set unittestConfiguration(unittest.Configuration value) {
   unittest.unittestConfiguration = value;
 }
+
+// TODO(nweiz): re-export these once issue 9535 is fixed.
+unittest.TestCase get currentTestCase => unittest.currentTestCase;
diff --git a/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
index ad304ed..eca863a 100644
--- a/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
@@ -5,9 +5,9 @@
 library descriptor.file;
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
 import 'dart:math' as math;
-import 'dart:utf';
 
 import 'package:path/path.dart' as path;
 
@@ -90,7 +90,7 @@
 
 class _StringFileDescriptor extends FileDescriptor {
   _StringFileDescriptor(String name, String contents)
-      : super._(name, encodeUtf8(contents));
+      : super._(name, UTF8.encode(contents));
 
   Future _validateNow(List<int> actualContents) {
     if (orderedIterableEquals(contents, actualContents)) return null;
diff --git a/pkg/sequence_zip/lib/iterable_zip.dart b/pkg/sequence_zip/lib/iterable_zip.dart
index 90c4c4f..f21da73 100644
--- a/pkg/sequence_zip/lib/iterable_zip.dart
+++ b/pkg/sequence_zip/lib/iterable_zip.dart
@@ -2,6 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+/**
+ * Help for combining multiple Iterables into a single Iterable.
+ *
+ * This API is also available as part of the
+ * [sequence_zip](#sequence_zip) library.
+ */
 library iterable_zip;
 
 import "dart:collection";
diff --git a/pkg/sequence_zip/lib/sequence_zip.dart b/pkg/sequence_zip/lib/sequence_zip.dart
index e8331ac..2f0d7e6 100644
--- a/pkg/sequence_zip/lib/sequence_zip.dart
+++ b/pkg/sequence_zip/lib/sequence_zip.dart
@@ -2,6 +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.
 
+/**
+ * Utilities for combining multiple streams or Iterables
+ * into a single stream or Iterable, respectively.
+ *
+ * This library defines no new APIs.
+ * It's a convenience library for using the APIs in the
+ * [iterable_zip](#iterable_zip) and
+ * [stream_zip](#stream_zip) libraries.
+ */
 library sequence_zip;
 
 export "iterable_zip.dart";
diff --git a/pkg/sequence_zip/lib/stream_zip.dart b/pkg/sequence_zip/lib/stream_zip.dart
index d1a47ab..0b4b40a 100644
--- a/pkg/sequence_zip/lib/stream_zip.dart
+++ b/pkg/sequence_zip/lib/stream_zip.dart
@@ -2,6 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+/**
+ * Help for combining multiple streams into a single stream.
+ *
+ * This API is also available as part of the
+ * [sequence_zip](#sequence_zip) library.
+ */
 library stream_zip;
 
 import "dart:async";
diff --git a/pkg/serialization/lib/serialization.dart b/pkg/serialization/lib/serialization.dart
index 9323ec1..aa32bd7 100644
--- a/pkg/serialization/lib/serialization.dart
+++ b/pkg/serialization/lib/serialization.dart
@@ -3,25 +3,17 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /**
- * This provides a general-purpose serialization facility for Dart objects. A
- * [Serialization] is defined in terms of [SerializationRule]s and supports
+ * A general-purpose serialization facility for Dart objects.
+ *
+ * A [Serialization] is defined in terms of [SerializationRule]s and supports
  * reading and writing to different formats.
  *
- * ## Installing ##
+ * For information on installing and importing this library, see the
+ * [serialization package on pub.dartlang.org]
+ * (http://pub.dartlang.org/packages/serialization).
  *
- * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
- * file.
+ * ## Setup
  *
- *     dependencies:
- *       serialization: any
- *
- * Then run `pub install`.
- *
- * For more information, see the
- * [serialization package on pub.dartlang.org][pkg].
- *
- * Setup
- * =====
  * A simple example of usage is
  *
  *      var address = new Address();
@@ -59,8 +51,8 @@
  *            constructor: "",
  *            excludeFields: ["other", "stuff"]);
  *
- * Writing Rules
- * =============
+ * ## Writing rules
+ *
  * We can also use a completely non-reflective rule to serialize and
  * de-serialize objects. This can be more work, but it does work in
  * dart2js, where mirrors are not yet implemented. We can specify this in two
@@ -117,8 +109,8 @@
  * consistent with the representation it uses. We pass it the runtimeType
  * of the object, and functions equivalent to the methods on [CustomRule]
  *
- * Constant Values
- * ===============
+ * ## Constant values
+ * 
  * There are cases where the constructor needs values that we can't easily get
  * from the serialized object. For example, we may just want to pass null, or a
  * constant value. To support this, we can specify as constructor fields
@@ -135,8 +127,8 @@
  *       s..addRuleFor(fooHolderInstance).setFieldWith("foo",
  *           (parent, value) => for (var each in value) parent.addFoo(value));
  *
- * Writing
- * =======
+ * ## Writing
+ *
  * To write objects, we use the write() method.
  *
  *       var output = serialization.write(someObject);
@@ -163,8 +155,8 @@
  *
  * These representations are not yet considered stable.
  *
- * Reading
- * =======
+ * ## Reading
+ *
  * To read objects, the corresponding [Serialization.read] method can be used.
  *
  *       Address input = serialization.read(input);
@@ -184,8 +176,8 @@
  * other services might expect. Using CustomRule or ClosureRule also does not
  * yet work with the [Serialization.selfDescribing] variable.
  *
- * Named Objects
- * =============
+ * ## Named objects
+ *
  * When reading, some object references should not be serialized, but should be
  * connected up to other instances on the receiving side. A notable example of
  * this is when serialization rules have been stored. Instances of BasicRule
@@ -199,9 +191,6 @@
  *     new Serialization()
  *       ..addRuleFor(new Person(), constructorFields: ["name"])
  *       ..namedObjects['Person'] = reflect(new Person()).type;
- *
- * [pub]: http://pub.dartlang.org
- * [pkg]: http://pub.dartlang.org/packages/serialization
  */
 library serialization;
 
@@ -297,8 +286,10 @@
     this.rules = new UnmodifiableListView(rules);
 
   /**
-   * Create a [BasicRule] rule for the type of
-   * [instanceOfType]. Optionally
+   * Create a [BasicRule] rule for [instanceOrType]. Normally this will be
+   * a type, but for backward compatibilty we also allow you to pass an
+   * instance (except an instance of Type), and the rule will be created
+   * for its runtimeType. Optionally
    * allows specifying a [constructor] name, the list of [constructorFields],
    * and the list of [fields] not used in the constructor. Returns the new
    * rule. Note that [BasicRule] uses reflection, and so will not work with the
@@ -321,9 +312,8 @@
    * are not inherited, and so may need to be specified separately for each
    * subclass.
    */
-  // TODO(alanknight): Take a type rather than an instance. Issue 6282 and 6433.
   BasicRule addRuleFor(
-      instanceOfType,
+      instanceOrType,
       {String constructor,
         List constructorFields,
         List<String> fields,
@@ -331,7 +321,7 @@
 
     var rule = new BasicRule(
         turnInstanceIntoSomethingWeCanUse(
-            instanceOfType),
+            instanceOrType),
         constructor, constructorFields, fields, excludeFields);
     addRule(rule);
     return rule;
diff --git a/pkg/serialization/lib/src/mirrors_helpers.dart b/pkg/serialization/lib/src/mirrors_helpers.dart
index 19360bf..fe211aa 100644
--- a/pkg/serialization/lib/src/mirrors_helpers.dart
+++ b/pkg/serialization/lib/src/mirrors_helpers.dart
@@ -82,8 +82,11 @@
 }
 
 /**
- * A particularly bad case of polyfill, because we cannot yet use type names
- * 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.
+ * Given either an instance or a type, returns the type. Instances of Type
+ * will be treated as types. Passing in an instance is really just backward
+ * compatibility.
  */
-ClassMirror turnInstanceIntoSomethingWeCanUse(x) => reflect(x).type;
+ClassMirror turnInstanceIntoSomethingWeCanUse(x) {
+  if (x is Type) return reflectClass(x);
+  return reflect(x).type;
+}
diff --git a/pkg/serialization/lib/src/serialization_helpers.dart b/pkg/serialization/lib/src/serialization_helpers.dart
index 87fe55c..015215c 100644
--- a/pkg/serialization/lib/src/serialization_helpers.dart
+++ b/pkg/serialization/lib/src/serialization_helpers.dart
@@ -9,6 +9,8 @@
  */
 library serialization_helpers;
 
+import 'dart:collection';
+
 /**
  * A named function of one argument that just returns it. Useful for using
  * as a default value for a function parameter or other places where you want
@@ -180,82 +182,60 @@
 }
 
 /**
- * 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.
+ * This is used in the implementation of [IdentityMap]. We wrap all the keys
+ * in an [_IdentityMapKey] that compares using the identity of the wrapped
+ * objects. It also treats equal primitive values as identical
+ * to conserve space.
  */
-class IdentityMap<K, V> implements Map<K, V> {
+class _IdentityMapKey {
+  _IdentityMapKey(this._value);
+  var _value;
 
-  final List<K> keys = <K>[];
-  final List<V> values = <V>[];
+  /**
+   * Check if an object is primitive to know if we should compare it using
+   * equality or identity. We don't test null/true/false where it's the same.
+   */
+  _isPrimitive(x) => x is String || x is num;
 
-  V operator [](Object key) {
-    var index =  _indexOf(key);
-    return (index == -1) ? null : values[index];
+  operator ==(_IdentityMapKey w) =>
+      _isPrimitive(_value) ? _value == w._value : identical(_value, w._value);
+  get hashCode => _value.hashCode;
+  get object => _value;
+}
+
+/**
+ * This provides an identity map. We wrap all the objects in
+ * an [_IdentityMapKey] that compares using the identity of the
+ * wrapped objects. It also treats equal primitive values as identical
+ * to conserve space.
+ */
+class IdentityMap<K, V> extends HashMap<K, V> {
+// TODO(alanknight): Replace with a system identity-based map once
+// one is available. Issue 4161.
+
+  // Check before wrapping because some methods may call others, e.g. on
+  // dart2js putIfAbsent calls containsKey, so without this we wrap forever.
+  _wrap(Object key) =>
+      (key is _IdentityMapKey) ? key : new _IdentityMapKey(key);
+  _unwrap(_IdentityMapKey wrapper) => wrapper.object;
+
+  Iterable<K> get keys => super.keys.map((x) => _unwrap(x));
+  Iterable<V> get values => super.values;
+
+  void forEach(void f(K key, V value)) {
+    super.forEach((k, v) => f(_unwrap(k), v));
   }
 
+  V operator [](K key) => super[_wrap(key)];
+
   void operator []=(K key, V value) {
-    var index = _indexOf(key);
-    if (index == -1) {
-      keys.add(key);
-      values.add(value);
-    } else {
-      values[index] = value;
-    }
+      super[_wrap(key)] = value;
   }
 
-  V 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];
-    }
-  }
+  V putIfAbsent(K key, Function ifAbsent) =>
+      super.putIfAbsent(_wrap(key), ifAbsent);
 
-  int _indexOf(Object 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;
-  }
+  bool containsKey(Object key) => super.containsKey(_wrap(key));
 
-  bool containsKey(Object 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(Object 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;
-  bool get isNotEmpty => !isEmpty;
-
-  // Note that this is doing an equality comparison.
-  bool containsValue(Object x) => values.contains(x);
-
-  void addAll(Map<K, V> other) {
-    other.forEach((K key, V value) {
-      this[key] = value;
-    });
-  }
+  V remove(Object key) => super.remove(_wrap(key));
 }
diff --git a/pkg/serialization/test/no_library_test.dart b/pkg/serialization/test/no_library_test.dart
index 30c1067..33eeda1 100644
--- a/pkg/serialization/test/no_library_test.dart
+++ b/pkg/serialization/test/no_library_test.dart
@@ -14,7 +14,7 @@
   test("Serializing something without a library directive", () {
     var thing = new Thing()..name = 'testThing';
     var s = new Serialization()
-      ..addRuleFor(thing);
+      ..addRuleFor(Thing);
     var serialized = s.write(thing);
     var newThing = s.read(serialized);
     expect(thing.name, newThing.name);
diff --git a/pkg/serialization/test/serialization_test.dart b/pkg/serialization/test/serialization_test.dart
index abf0d2d..3cb5a75 100644
--- a/pkg/serialization/test/serialization_test.dart
+++ b/pkg/serialization/test/serialization_test.dart
@@ -26,7 +26,7 @@
   test('Basic extraction of a simple object', () {
     // TODO(alanknight): Switch these to use literal types. Issue
     var s = new Serialization()
-        ..addRuleFor(a1).configureForMaps();
+        ..addRuleFor(Address).configureForMaps();
     Map extracted = states(a1, s).first;
     expect(extracted.length, 4);
     expect(extracted['street'], 'N 34th');
@@ -44,8 +44,8 @@
   test('Slightly further with a simple object', () {
     var p1 = new Person()..name = 'Alice'..address = a1;
     var s = new Serialization()
-        ..addRuleFor(p1).configureForMaps()
-        ..addRuleFor(a1).configureForMaps();
+        ..addRuleFor(Person).configureForMaps()
+        ..addRuleFor(Address).configureForMaps();
     // TODO(alanknight): Need a better API for getting to flat state without
     // actually writing.
     var w = new Writer(s, const InternalMapFormat());
@@ -67,7 +67,7 @@
 
   test('exclude fields', () {
     var s = new Serialization()
-        ..addRuleFor(a1,
+        ..addRuleFor(Address,
             excludeFields: ['state', 'zip']).configureForMaps();
     var extracted = states(a1, s).first;
     expect(extracted.length, 2);
@@ -98,7 +98,7 @@
     x.b = "b";
     x._c = "c";
     var s = new Serialization()
-      ..addRuleFor(x,
+      ..addRuleFor(Various,
           constructor: "Foo",
           constructorFields: ["d", "e"]);
     var state = states(x, s).first;
@@ -133,7 +133,7 @@
     var _collectionSym = reflect(stream).type.variables.keys.firstWhere(
         (x) => MirrorSystem.getName(x) == "_collection");
     var s = new Serialization()
-      ..addRuleFor(stream,
+      ..addRuleFor(Stream,
           constructorFields: [_collectionSym]);
     var state = states(stream, s).first;
     // Define names for the variable offsets to make this more readable.
@@ -289,7 +289,7 @@
     // the result.
     var s = new Serialization.blank()
       // Add the rules in a deliberately unusual order.
-      ..addRuleFor(new Node(''), constructorFields: ['name'])
+      ..addRuleFor(Node, constructorFields: ['name'])
       ..addRule(new ListRule())
       ..addRule(new PrimitiveRule())
       ..selfDescribing = false;
@@ -312,7 +312,7 @@
     n2.parent = n1;
     n3.parent = n1;
     var s = new Serialization()
-      ..addRuleFor(n1, constructorFields: ["name"]).
+      ..addRuleFor(Node, constructorFields: ["name"]).
           setFieldWith("children", (parent, child) =>
               parent.reflectee.children = child);
     var w = new Writer(s);
@@ -322,7 +322,7 @@
     expect(w.states[1].length, 0);
     expect(w.states[2].length, 1);
     s = new Serialization()
-      ..addRuleFor(n1, constructorFields: ["name"]);
+      ..addRuleFor(Node, constructorFields: ["name"]);
     w = new Writer(s);
     w.write(n1);
     expect(w.states[1].length, 1);
@@ -338,7 +338,7 @@
     n3.parent = n1;
     var s = new Serialization()
       ..selfDescribing = false
-      ..addRuleFor(n1, constructorFields: ["name"]);
+      ..addRuleFor(NodeEqualByName, constructorFields: ["name"]);
     var m1 = writeAndReadBack(s, null, n1);
     var m2 = m1.children.first;
     var m3 = m1.children.last;
@@ -351,7 +351,7 @@
   test("Constant values as fields", () {
     var s = new Serialization()
       ..selfDescribing = false
-      ..addRuleFor(a1,
+      ..addRuleFor(Address,
           constructor: 'withData',
           constructorFields: ["street", "Kirkland", "WA", "98103"],
           fields: []);
@@ -375,8 +375,8 @@
   test("Straight JSON format, nested objects", () {
     var p1 = new Person()..name = 'Alice'..address = a1;
     var s = new Serialization()..selfDescribing = false;
-    var addressRule = s.addRuleFor(a1)..configureForMaps();
-    var personRule = s.addRuleFor(p1)..configureForMaps();
+    var addressRule = s.addRuleFor(Address)..configureForMaps();
+    var personRule = s.addRuleFor(Person)..configureForMaps();
     var writer = s.newWriter(const SimpleJsonFormat(storeRoundTripInfo: true));
     var out = json.stringify(writer.write(p1));
     var reconstituted = json.parse(out);
@@ -401,8 +401,8 @@
     var p1 = new Person()..name = 'Alice'..address = a1;
     // Use maps for one rule, lists for the other.
     var s = new Serialization()
-      ..addRuleFor(a1)
-      ..addRuleFor(p1).configureForMaps();
+      ..addRuleFor(Address)
+      ..addRuleFor(Person).configureForMaps();
     var p2 = writeAndReadBack(s,
         const SimpleJsonFormat(storeRoundTripInfo: true), p1);
     expect(p2.name, "Alice");
@@ -430,6 +430,7 @@
     var p1 = new Person()..name = 'Alice'..address = a1;
     // Use maps for one rule, lists for the other.
     var s = new Serialization()
+      // Deliberately left as passing instances to test backward-compatibility.
       ..addRuleFor(a1)
       ..addRuleFor(p1).configureForMaps();
     for (var eachFormat in formats) {
@@ -476,8 +477,8 @@
     var s = new Serialization()
       ..selfDescribing = false
       ..addRule(new NamedObjectRule())
-      ..addRuleFor(a1)
-      ..addRuleFor(p1).configureForMaps()
+      ..addRuleFor(Address)
+      ..addRuleFor(Person).configureForMaps()
       ..namedObjects["foo"] = a1;
     var format = const SimpleJsonFormat(storeRoundTripInfo: true);
     var out = s.write(p1, format: format);
@@ -520,7 +521,7 @@
   });
 
   test("Map with string keys stays that way", () {
-    var s = new Serialization()..addRuleFor(new Person());
+    var s = new Serialization()..addRuleFor(Person);
     var data = {"abc" : 1, "def" : "ghi"};
     data["person"] = new Person()..name = "Foo";
     var output = s.write(data, format: const InternalMapFormat());
@@ -589,16 +590,16 @@
 
   var meta = new Serialization()
     ..selfDescribing = false
-    ..addRuleFor(new ListRule())
-    ..addRuleFor(new PrimitiveRule())
+    ..addRuleFor(ListRule)
+    ..addRuleFor(PrimitiveRule)
     // TODO(alanknight): Handle CustomRule as well.
     // Note that we're passing in a constant for one of the fields.
-    ..addRuleFor(basicRule,
+    ..addRuleFor(BasicRule,
         constructorFields: ['type',
           'constructorName',
           'constructorFields', 'regularFields', []],
         fields: [])
-     ..addRuleFor(new Serialization(), constructor: "blank")
+     ..addRuleFor(Serialization, constructor: "blank")
          .setFieldWith('rules',
            (InstanceMirror s, List rules) {
              rules.forEach((x) => s.reflectee.addRule(x));
@@ -648,7 +649,7 @@
 /** Return a serialization for Node objects, using a reflective rule. */
 Serialization nodeSerializerReflective(Node n) {
   return new Serialization()
-    ..addRuleFor(n, constructorFields: ["name"])
+    ..addRuleFor(Node, constructorFields: ["name"])
     ..namedObjects['Node'] = reflect(new Node('')).type;
 }
 
@@ -658,7 +659,8 @@
  */
 Serialization nodeSerializerUsingMaps(Node n) {
   return new Serialization()
-    ..addRuleFor(n, constructorFields: ["name"]).configureForMaps()
+    // Get the type using runtimeType to verify that works.
+    ..addRuleFor(n.runtimeType, constructorFields: ["name"]).configureForMaps()
     ..namedObjects['Node'] = reflect(new Node('')).type;
 }
 
@@ -681,7 +683,7 @@
   // considers all of its state non-essential, thus breaking the cycle.
   var s = new Serialization.blank()
     ..addRuleFor(
-        n,
+        Node,
         constructor: "parentEssential",
         constructorFields: ["parent"])
     ..addDefaultRules()
diff --git a/pkg/source_maps/lib/printer.dart b/pkg/source_maps/lib/printer.dart
index 95539d2..0898017 100644
--- a/pkg/source_maps/lib/printer.dart
+++ b/pkg/source_maps/lib/printer.dart
@@ -5,7 +5,6 @@
 /// Contains a code printer that generates code by recording the source maps.
 library source_maps.printer;
 
-import 'dart:utf' show stringToCodepoints;
 import 'builder.dart';
 import 'span.dart';
 
@@ -38,7 +37,7 @@
   /// line in the target file (printed here) corresponds to a new line in the
   /// source file.
   void add(String str, {projectMarks: false}) {
-    var chars = stringToCodepoints(str);
+    var chars = str.runes.toList();
     var length = chars.length;
     for (int i = 0; i < length; i++) {
       var c = chars[i];
diff --git a/pkg/source_maps/lib/span.dart b/pkg/source_maps/lib/span.dart
index e5057fc..17ccd27 100644
--- a/pkg/source_maps/lib/span.dart
+++ b/pkg/source_maps/lib/span.dart
@@ -5,7 +5,6 @@
 /// Dart classes representing the souce spans and source files.
 library source_maps.span;
 
-import 'dart:utf' show stringToCodepoints;
 import 'dart:math' show min, max;
 
 import 'src/utils.dart';
@@ -201,7 +200,7 @@
 
   SourceFile.text(this.url, String text)
       : _lineStarts = <int>[0],
-        _decodedChars = stringToCodepoints(text) {
+        _decodedChars = text.runes.toList() {
     for (int i = 0; i < _decodedChars.length; i++) {
       var c = _decodedChars[i];
       if (c == _CR) {
diff --git a/pkg/stack_trace/lib/src/trace.dart b/pkg/stack_trace/lib/src/trace.dart
index 19f0a12..bf14ee2 100644
--- a/pkg/stack_trace/lib/src/trace.dart
+++ b/pkg/stack_trace/lib/src/trace.dart
@@ -19,8 +19,14 @@
 /// V8's traces start with a line that's either just "Error" or else is a
 /// description of the exception that occurred. That description can be multiple
 /// lines, so we just look for any line other than the first that begins with
-/// four spaces and "at".
-final _v8Trace = new RegExp(r"\n    at ");
+/// three or four spaces and "at".
+final _v8Trace = new RegExp(r"\n    ?at ");
+
+/// A RegExp to match indidual lines of V8's stack traces.
+///
+/// This is intended to filter out the leading exception details of the trace
+/// though it is possible for the message to match this as well.
+final _v8TraceLine = new RegExp(r"    ?at ");
 
 /// A RegExp to match Firefox's stack traces.
 ///
@@ -106,7 +112,7 @@
           // It's possible that an Exception's description contains a line that
           // looks like a V8 trace line, which will screw this up.
           // Unfortunately, that's impossible to detect.
-          .skipWhile((line) => !line.startsWith("    at "))
+          .skipWhile((line) => !line.startsWith(_v8TraceLine))
           .map((line) => new Frame.parseV8(line)));
 
   /// Parses a string representation of an Internet Explorer stack trace.
diff --git a/pkg/unittest/lib/html_enhanced_config.dart b/pkg/unittest/lib/html_enhanced_config.dart
index 723fc0c..75f02ab 100644
--- a/pkg/unittest/lib/html_enhanced_config.dart
+++ b/pkg/unittest/lib/html_enhanced_config.dart
@@ -68,12 +68,12 @@
 
     var cssElement = document.head.query('#${_CSSID}');
     if (cssElement == null){
-      document.head.children.add(new Element.html(
-          '<style id="${_CSSID}"></style>'));
-      cssElement = document.head.query('#${_CSSID}');
+      cssElement = new StyleElement();
+      cssElement.id = _CSSID;
+      document.head.append(cssElement);
     }
 
-    cssElement.innerHtml = _htmlTestCSS;
+    cssElement.text = _htmlTestCSS;
     window.postMessage('unittest-suite-wait-for-done', '*');
   }
 
diff --git a/pkg/unmodifiable_collection/lib/unmodifiable_collection.dart b/pkg/unmodifiable_collection/lib/unmodifiable_collection.dart
index dbdf64d..b94a0c4 100644
--- a/pkg/unmodifiable_collection/lib/unmodifiable_collection.dart
+++ b/pkg/unmodifiable_collection/lib/unmodifiable_collection.dart
@@ -3,22 +3,29 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /**
- * Unmodifiable wrappers for [List], [Set] and [Map] objects.
+ * Wrappers that prevent List, Set, or Map objects from being modified.
  *
- * The wrappers allow reading from the source list, but writing is prohibited.
+ * The [Set] and [Map] wrappers allow reading from the wrapped collection,
+ * but prohibit writing.
  *
- * A non-growable list wrapper allows writing as well, but not changing the
- * list's length.
+ * The [List] wrapper prevents changes to the length of the wrapped list,
+ * but allows changes to the contents.
  */
 library unmodifiable_collection;
 
 export "dart:collection" show UnmodifiableListView;
 
 /**
- * A [List] wrapper that acts as a non-growable list.
+ * A fixed-length list.
  *
- * Writes to the list are written through to the source list, but operations
- * that change the length is not allowed.
+ * A NonGrowableListView contains a [List] object and ensures that
+ * its length does not change.
+ * Methods that would change the length of the list,
+ * such as [add] and [remove], throw an [UnsupportedError].
+ *
+ * This class _does_ allow changes to the contents of the wrapped list.
+ * You can, for example, [sort] the list.
+ * Permitted operations defer to the wrapped list.
  */
 class NonGrowableListView<E> extends _IterableView<E>
                                      implements List<E> {
@@ -65,35 +72,93 @@
   }
 
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   void set length(int newLength) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   void add(E value) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   void addAll(Iterable<E> iterable) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   void insert(int index, E element) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   void insertAll(int index, Iterable<E> iterable) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   bool remove(Object value) { _throw(); }
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   E removeAt(int index) { _throw(); }
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   E removeLast() { _throw(); }
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   void removeWhere(bool test(E element)) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   void retainWhere(bool test(E element)) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   void removeRange(int start, int end) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   void replaceRange(int start, int end, Iterable<E> iterable) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the length of the list are disallowed.
+   */
   void clear() => _throw();
 }
 
 /**
- * A [Set] wrapper that acts as an unmodifiable set.
+ * An unmodifiable set.
+ *
+ * An UnmodifiableSetView contains a [Set] object and ensures 
+ * that it does not change.
+ * Methods that would change the set,
+ * such as [add] and [remove], throw an [UnsupportedError].
+ * Permitted operations defer to the wrapped set.
  */
 class UnmodifiableSetView<E> extends _IterableView<E>
                                       implements Set<E> {
@@ -113,25 +178,63 @@
   Set<E> difference(Set<E> other) => _source.difference(other);
 
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the set are disallowed.
+   */
   void add(E value) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the set are disallowed.
+   */
   void addAll(Iterable<E> elements) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the set are disallowed.
+   */
   bool remove(Object value) { _throw(); }
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the set are disallowed.
+   */
   void removeAll(Iterable elements) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the set are disallowed.
+   */
   void retainAll(Iterable elements) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the set are disallowed.
+   */
   void removeWhere(bool test(E element)) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the set are disallowed.
+   */
   void retainWhere(bool test(E element)) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the set are disallowed.
+   */
   void clear() => _throw();
 }
 
 /**
- * A [Map] wrapper that acts as an unmodifiable map.
+ * An unmodifiable map.
+ *
+ * An UnmodifiableMapView contains a [Map] object and ensures 
+ * that it does not change.
+ * Methods that would change the map,
+ * such as [addAll] and [remove], throw an [UnsupportedError].
+ * Permitted operations defer to the wrapped map.
  */
 class UnmodifiableMapView<K, V> implements Map<K, V> {
   Map<K, V> _source;
@@ -160,14 +263,34 @@
   Iterable<V> get values => _source.values;
 
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the map are disallowed.
+   */
   void operator []=(K key, V value) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the map are disallowed.
+   */
   V putIfAbsent(K key, V ifAbsent()) { _throw(); }
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the map are disallowed.
+   */
   void addAll(Map<K, V> other) => _throw();
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the map are disallowed.
+   */
   V remove(K key) { _throw(); }
 
+  /**
+   * Throws an [UnsupportedError];
+   * operations that change the map are disallowed.
+   */
   void clear() => _throw();
 }
 
diff --git a/pkg/utf/README.md b/pkg/utf/README.md
new file mode 100644
index 0000000..fc68063
--- /dev/null
+++ b/pkg/utf/README.md
@@ -0,0 +1,5 @@
+A Unicode manipulation library for Dart.
+
+The utf package provides common operations for manipulating Unicode sequences.
+In its initial form it is a copy of the `dart:utf` library before that was
+deprecated.
diff --git a/pkg/utf/lib/utf.dart b/pkg/utf/lib/utf.dart
new file mode 100644
index 0000000..164c340
--- /dev/null
+++ b/pkg/utf/lib/utf.dart
@@ -0,0 +1,269 @@
+// Copyright (c) 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.
+
+/**
+ * Support for encoding and decoding Unicode characters in UTF-8, UTF-16, and 
+ * UTF-32.
+ */
+library utf;
+import "dart:async";
+import "dart:collection";
+part "utf_stream.dart";
+part "utf8.dart";
+part "utf16.dart";
+part "utf32.dart";
+
+// TODO(jmesserly): would be nice to have this on String (dartbug.com/6501).
+/**
+ * Provide a list of Unicode codepoints for a given string.
+ */
+List<int> stringToCodepoints(String str) {
+  // Note: str.codeUnits gives us 16-bit code units on all Dart implementations.
+  // So we need to convert.
+  return _utf16CodeUnitsToCodepoints(str.codeUnits);
+}
+
+/**
+ * Generate a string from the provided Unicode codepoints.
+ *
+ * *Deprecated* Use [String.fromCharCodes] instead.
+ */
+String codepointsToString(List<int> codepoints) {
+  return new String.fromCharCodes(codepoints);
+}
+
+/**
+ * Invalid codepoints or encodings may be substituted with the value U+fffd.
+ */
+const int UNICODE_REPLACEMENT_CHARACTER_CODEPOINT = 0xfffd;
+const int UNICODE_BOM = 0xfeff;
+const int UNICODE_UTF_BOM_LO = 0xff;
+const int UNICODE_UTF_BOM_HI = 0xfe;
+
+const int UNICODE_BYTE_ZERO_MASK = 0xff;
+const int UNICODE_BYTE_ONE_MASK = 0xff00;
+const int UNICODE_VALID_RANGE_MAX = 0x10ffff;
+const int UNICODE_PLANE_ONE_MAX = 0xffff;
+const int UNICODE_UTF16_RESERVED_LO = 0xd800;
+const int UNICODE_UTF16_RESERVED_HI = 0xdfff;
+const int UNICODE_UTF16_OFFSET = 0x10000;
+const int UNICODE_UTF16_SURROGATE_UNIT_0_BASE = 0xd800;
+const int UNICODE_UTF16_SURROGATE_UNIT_1_BASE = 0xdc00;
+const int UNICODE_UTF16_HI_MASK = 0xffc00;
+const int UNICODE_UTF16_LO_MASK = 0x3ff;
+
+/**
+ * Encode code points as UTF16 code units.
+ */
+List<int> _codepointsToUtf16CodeUnits(
+    List<int> codepoints,
+    [int offset = 0,
+     int length,
+     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+
+  _ListRange listRange = new _ListRange(codepoints, offset, length);
+  int encodedLength = 0;
+  for (int value in listRange) {
+    if ((value >= 0 && value < UNICODE_UTF16_RESERVED_LO) ||
+        (value > UNICODE_UTF16_RESERVED_HI && value <= UNICODE_PLANE_ONE_MAX)) {
+      encodedLength++;
+    } else if (value > UNICODE_PLANE_ONE_MAX &&
+        value <= UNICODE_VALID_RANGE_MAX) {
+      encodedLength += 2;
+    } else {
+      encodedLength++;
+    }
+  }
+
+  List<int> codeUnitsBuffer = new List<int>(encodedLength);
+  int j = 0;
+  for (int value in listRange) {
+    if ((value >= 0 && value < UNICODE_UTF16_RESERVED_LO) ||
+        (value > UNICODE_UTF16_RESERVED_HI && value <= UNICODE_PLANE_ONE_MAX)) {
+      codeUnitsBuffer[j++] = value;
+    } else if (value > UNICODE_PLANE_ONE_MAX &&
+        value <= UNICODE_VALID_RANGE_MAX) {
+      int base = value - UNICODE_UTF16_OFFSET;
+      codeUnitsBuffer[j++] = UNICODE_UTF16_SURROGATE_UNIT_0_BASE +
+          ((base & UNICODE_UTF16_HI_MASK) >> 10);
+      codeUnitsBuffer[j++] = UNICODE_UTF16_SURROGATE_UNIT_1_BASE +
+          (base & UNICODE_UTF16_LO_MASK);
+    } else if (replacementCodepoint != null) {
+      codeUnitsBuffer[j++] = replacementCodepoint;
+    } else {
+      throw new ArgumentError("Invalid encoding");
+    }
+  }
+  return codeUnitsBuffer;
+}
+
+/**
+ * Decodes the utf16 codeunits to codepoints.
+ */
+List<int> _utf16CodeUnitsToCodepoints(
+    List<int> utf16CodeUnits, [int offset = 0, int length,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  _ListRangeIterator source =
+      (new _ListRange(utf16CodeUnits, offset, length)).iterator;
+  Utf16CodeUnitDecoder decoder = new Utf16CodeUnitDecoder
+      .fromListRangeIterator(source, replacementCodepoint);
+  List<int> codepoints = new List<int>(source.remaining);
+  int i = 0;
+  while (decoder.moveNext()) {
+    codepoints[i++] = decoder.current;
+  }
+  if (i == codepoints.length) {
+    return codepoints;
+  } else {
+    List<int> codepointTrunc = new List<int>(i);
+    codepointTrunc.setRange(0, i, codepoints);
+    return codepointTrunc;
+  }
+}
+
+/**
+ * An Iterator<int> of codepoints built on an Iterator of UTF-16 code units.
+ * The parameters can override the default Unicode replacement character. Set
+ * the replacementCharacter to null to throw an ArgumentError
+ * rather than replace the bad value.
+ */
+class Utf16CodeUnitDecoder implements Iterator<int> {
+  final _ListRangeIterator utf16CodeUnitIterator;
+  final int replacementCodepoint;
+  int _current = null;
+
+  Utf16CodeUnitDecoder(List<int> utf16CodeUnits, [int offset = 0, int length,
+      int this.replacementCodepoint =
+      UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) :
+      utf16CodeUnitIterator =
+          (new _ListRange(utf16CodeUnits, offset, length)).iterator;
+
+  Utf16CodeUnitDecoder.fromListRangeIterator(
+      _ListRangeIterator this.utf16CodeUnitIterator,
+      int this.replacementCodepoint);
+
+  Iterator<int> get iterator => this;
+
+  int get current => _current;
+
+  bool moveNext() {
+    _current = null;
+    if (!utf16CodeUnitIterator.moveNext()) return false;
+
+    int value = utf16CodeUnitIterator.current;
+    if (value < 0) {
+      if (replacementCodepoint != null) {
+        _current = replacementCodepoint;
+      } else {
+        throw new ArgumentError(
+            "Invalid UTF16 at ${utf16CodeUnitIterator.position}");
+      }
+    } else if (value < UNICODE_UTF16_RESERVED_LO ||
+        (value > UNICODE_UTF16_RESERVED_HI && value <= UNICODE_PLANE_ONE_MAX)) {
+      // transfer directly
+      _current = value;
+    } else if (value < UNICODE_UTF16_SURROGATE_UNIT_1_BASE &&
+        utf16CodeUnitIterator.moveNext()) {
+      // merge surrogate pair
+      int nextValue = utf16CodeUnitIterator.current;
+      if (nextValue >= UNICODE_UTF16_SURROGATE_UNIT_1_BASE &&
+          nextValue <= UNICODE_UTF16_RESERVED_HI) {
+        value = (value - UNICODE_UTF16_SURROGATE_UNIT_0_BASE) << 10;
+        value += UNICODE_UTF16_OFFSET +
+            (nextValue - UNICODE_UTF16_SURROGATE_UNIT_1_BASE);
+        _current = value;
+      } else {
+        if (nextValue >= UNICODE_UTF16_SURROGATE_UNIT_0_BASE &&
+           nextValue < UNICODE_UTF16_SURROGATE_UNIT_1_BASE) {
+          utf16CodeUnitIterator.backup();
+        }
+        if (replacementCodepoint != null) {
+          _current = replacementCodepoint;
+        } else {
+          throw new ArgumentError(
+              "Invalid UTF16 at ${utf16CodeUnitIterator.position}");
+        }
+      }
+    } else if (replacementCodepoint != null) {
+      _current = replacementCodepoint;
+    } else {
+      throw new ArgumentError(
+          "Invalid UTF16 at ${utf16CodeUnitIterator.position}");
+    }
+    return true;
+  }
+}
+
+/**
+ * _ListRange in an internal type used to create a lightweight Interable on a
+ * range within a source list. DO NOT MODIFY the underlying list while
+ * iterating over it. The results of doing so are undefined.
+ */
+// TODO(floitsch): Consider removing the extend and switch to implements since
+// that's cheaper to allocate.
+class _ListRange extends IterableBase {
+  final List _source;
+  final int _offset;
+  final int _length;
+
+  _ListRange(source, [offset = 0, length]) :
+      this._source = source,
+      this._offset = offset,
+      this._length = (length == null ? source.length - offset : length) {
+    if (_offset < 0 || _offset > _source.length) {
+      throw new RangeError.value(_offset);
+    }
+    if (_length != null && (_length < 0)) {
+      throw new RangeError.value(_length);
+    }
+    if (_length + _offset > _source.length) {
+      throw new RangeError.value(_length + _offset);
+    }
+  }
+
+  _ListRangeIterator get iterator =>
+      new _ListRangeIteratorImpl(_source, _offset, _offset + _length);
+
+  int get length => _length;
+}
+
+/**
+ * The _ListRangeIterator provides more capabilities than a standard iterator,
+ * including the ability to get the current position, count remaining items,
+ * and move forward/backward within the iterator.
+ */
+abstract class _ListRangeIterator implements Iterator<int> {
+  bool moveNext();
+  int get current;
+  int get position;
+  void backup([by]);
+  int get remaining;
+  void skip([count]);
+}
+
+class _ListRangeIteratorImpl implements _ListRangeIterator {
+  final List<int> _source;
+  int _offset;
+  final int _end;
+
+  _ListRangeIteratorImpl(this._source, int offset, this._end)
+      : _offset = offset - 1;
+
+  int get current => _source[_offset];
+
+  bool moveNext() => ++_offset < _end;
+
+  int get position => _offset;
+
+  void backup([int by = 1]) {
+    _offset -= by;
+  }
+
+  int get remaining => _end - _offset - 1;
+
+  void skip([int count = 1]) {
+    _offset += count;
+  }
+}
+
diff --git a/pkg/utf/lib/utf16.dart b/pkg/utf/lib/utf16.dart
new file mode 100644
index 0000000..3518bbb
--- /dev/null
+++ b/pkg/utf/lib/utf16.dart
@@ -0,0 +1,337 @@
+// Copyright (c) 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 dart.utf;
+
+/**
+ * Decodes the UTF-16 bytes as an iterable. Thus, the consumer can only convert
+ * as much of the input as needed. Determines the byte order from the BOM,
+ * or uses big-endian as a default. This method always strips a leading BOM.
+ * Set the [replacementCodepoint] to null to throw an ArgumentError
+ * rather than replace the bad value. The default value for
+ * [replacementCodepoint] is U+FFFD.
+ */
+IterableUtf16Decoder decodeUtf16AsIterable(List<int> bytes, [int offset = 0,
+    int length, int replacementCodepoint =
+    UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  return new IterableUtf16Decoder._(
+      () => new Utf16BytesToCodeUnitsDecoder(bytes, offset, length,
+      replacementCodepoint), replacementCodepoint);
+}
+
+/**
+ * Decodes the UTF-16BE bytes as an iterable. Thus, the consumer can only
+ * convert as much of the input as needed. This method strips a leading BOM by
+ * default, but can be overridden by setting the optional parameter [stripBom]
+ * to false. Set the [replacementCodepoint] to null to throw an
+ * ArgumentError rather than replace the bad value. The default
+ * value for the [replacementCodepoint] is U+FFFD.
+ */
+IterableUtf16Decoder decodeUtf16beAsIterable(List<int> bytes, [int offset = 0,
+    int length, bool stripBom = true, int replacementCodepoint =
+    UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  return new IterableUtf16Decoder._(
+      () => new Utf16beBytesToCodeUnitsDecoder(bytes, offset, length, stripBom,
+      replacementCodepoint), replacementCodepoint);
+}
+
+/**
+ * Decodes the UTF-16LE bytes as an iterable. Thus, the consumer can only
+ * convert as much of the input as needed. This method strips a leading BOM by
+ * default, but can be overridden by setting the optional parameter [stripBom]
+ * to false. Set the [replacementCodepoint] to null to throw an
+ * ArgumentError rather than replace the bad value. The default
+ * value for the [replacementCodepoint] is U+FFFD.
+ */
+IterableUtf16Decoder decodeUtf16leAsIterable(List<int> bytes, [int offset = 0,
+    int length, bool stripBom = true, int replacementCodepoint =
+    UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  return new IterableUtf16Decoder._(
+      () => new Utf16leBytesToCodeUnitsDecoder(bytes, offset, length, stripBom,
+      replacementCodepoint), replacementCodepoint);
+}
+
+/**
+ * Produce a String from a sequence of UTF-16 encoded bytes. This method always
+ * strips a leading BOM. Set the [replacementCodepoint] to null to throw  an
+ * ArgumentError rather than replace the bad value. The default
+ * value for the [replacementCodepoint] is U+FFFD.
+ */
+String decodeUtf16(List<int> bytes, [int offset = 0, int length,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  Utf16BytesToCodeUnitsDecoder decoder = new Utf16BytesToCodeUnitsDecoder(bytes,
+      offset, length, replacementCodepoint);
+  List<int> codeunits = decoder.decodeRest();
+  return new String.fromCharCodes(
+      _utf16CodeUnitsToCodepoints(codeunits, 0, null, replacementCodepoint));
+}
+
+/**
+ * Produce a String from a sequence of UTF-16BE encoded bytes. This method
+ * strips a leading BOM by default, but can be overridden by setting the
+ * optional parameter [stripBom] to false. Set the [replacementCodepoint] to
+ * null to throw an ArgumentError rather than replace the bad value.
+ * The default value for the [replacementCodepoint] is U+FFFD.
+ */
+String decodeUtf16be(List<int> bytes, [int offset = 0, int length,
+    bool stripBom = true,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  List<int> codeunits = (new Utf16beBytesToCodeUnitsDecoder(bytes, offset,
+      length, stripBom, replacementCodepoint)).decodeRest();
+  return new String.fromCharCodes(
+      _utf16CodeUnitsToCodepoints(codeunits, 0, null, replacementCodepoint));
+}
+
+/**
+ * Produce a String from a sequence of UTF-16LE encoded bytes. This method
+ * strips a leading BOM by default, but can be overridden by setting the
+ * optional parameter [stripBom] to false. Set the [replacementCodepoint] to
+ * null to throw an ArgumentError rather than replace the bad value.
+ * The default value for the [replacementCodepoint] is U+FFFD.
+ */
+String decodeUtf16le(List<int> bytes, [int offset = 0, int length,
+    bool stripBom = true,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  List<int> codeunits = (new Utf16leBytesToCodeUnitsDecoder(bytes, offset,
+      length, stripBom, replacementCodepoint)).decodeRest();
+  return new String.fromCharCodes(
+      _utf16CodeUnitsToCodepoints(codeunits, 0, null, replacementCodepoint));
+}
+
+/**
+ * Produce a list of UTF-16 encoded bytes. This method prefixes the resulting
+ * bytes with a big-endian byte-order-marker.
+ */
+List<int> encodeUtf16(String str) =>
+    encodeUtf16be(str, true);
+
+/**
+ * Produce a list of UTF-16BE encoded bytes. By default, this method produces
+ * UTF-16BE bytes with no BOM.
+ */
+List<int> encodeUtf16be(String str, [bool writeBOM = false]) {
+  List<int> utf16CodeUnits = _stringToUtf16CodeUnits(str);
+  List<int> encoding =
+      new List<int>(2 * utf16CodeUnits.length + (writeBOM ? 2 : 0));
+  int i = 0;
+  if (writeBOM) {
+    encoding[i++] = UNICODE_UTF_BOM_HI;
+    encoding[i++] = UNICODE_UTF_BOM_LO;
+  }
+  for (int unit in utf16CodeUnits) {
+    encoding[i++] = (unit & UNICODE_BYTE_ONE_MASK) >> 8;
+    encoding[i++] = unit & UNICODE_BYTE_ZERO_MASK;
+  }
+  return encoding;
+}
+
+/**
+ * Produce a list of UTF-16LE encoded bytes. By default, this method produces
+ * UTF-16LE bytes with no BOM.
+ */
+List<int> encodeUtf16le(String str, [bool writeBOM = false]) {
+  List<int> utf16CodeUnits = _stringToUtf16CodeUnits(str);
+  List<int> encoding =
+      new List<int>(2 * utf16CodeUnits.length + (writeBOM ? 2 : 0));
+  int i = 0;
+  if (writeBOM) {
+    encoding[i++] = UNICODE_UTF_BOM_LO;
+    encoding[i++] = UNICODE_UTF_BOM_HI;
+  }
+  for (int unit in utf16CodeUnits) {
+    encoding[i++] = unit & UNICODE_BYTE_ZERO_MASK;
+    encoding[i++] = (unit & UNICODE_BYTE_ONE_MASK) >> 8;
+  }
+  return encoding;
+}
+
+/**
+ * Identifies whether a List of bytes starts (based on offset) with a
+ * byte-order marker (BOM).
+ */
+bool hasUtf16Bom(List<int> utf32EncodedBytes, [int offset = 0, int length]) {
+  return hasUtf16beBom(utf32EncodedBytes, offset, length) ||
+      hasUtf16leBom(utf32EncodedBytes, offset, length);
+}
+
+/**
+ * Identifies whether a List of bytes starts (based on offset) with a
+ * big-endian byte-order marker (BOM).
+ */
+bool hasUtf16beBom(List<int> utf16EncodedBytes, [int offset = 0, int length]) {
+  int end = length != null ? offset + length : utf16EncodedBytes.length;
+  return (offset + 2) <= end &&
+      utf16EncodedBytes[offset] == UNICODE_UTF_BOM_HI &&
+      utf16EncodedBytes[offset + 1] == UNICODE_UTF_BOM_LO;
+}
+
+/**
+ * Identifies whether a List of bytes starts (based on offset) with a
+ * little-endian byte-order marker (BOM).
+ */
+bool hasUtf16leBom(List<int> utf16EncodedBytes, [int offset = 0, int length]) {
+  int end = length != null ? offset + length : utf16EncodedBytes.length;
+  return (offset + 2) <= end &&
+      utf16EncodedBytes[offset] == UNICODE_UTF_BOM_LO &&
+      utf16EncodedBytes[offset + 1] == UNICODE_UTF_BOM_HI;
+}
+
+List<int> _stringToUtf16CodeUnits(String str) {
+  return _codepointsToUtf16CodeUnits(str.codeUnits);
+}
+
+typedef _ListRangeIterator _CodeUnitsProvider();
+
+/**
+ * Return type of [decodeUtf16AsIterable] and variants. The Iterable type
+ * provides an iterator on demand and the iterator will only translate bytes
+ * as requested by the user of the iterator. (Note: results are not cached.)
+ */
+// TODO(floitsch): Consider removing the extend and switch to implements since
+// that's cheaper to allocate.
+class IterableUtf16Decoder extends IterableBase<int> {
+  final _CodeUnitsProvider codeunitsProvider;
+  final int replacementCodepoint;
+
+  IterableUtf16Decoder._(this.codeunitsProvider, this.replacementCodepoint);
+
+  Utf16CodeUnitDecoder get iterator =>
+      new Utf16CodeUnitDecoder.fromListRangeIterator(codeunitsProvider(),
+          replacementCodepoint);
+}
+
+/**
+ * Convert UTF-16 encoded bytes to UTF-16 code units by grouping 1-2 bytes
+ * to produce the code unit (0-(2^16)-1). Relies on BOM to determine
+ * endian-ness, and defaults to BE.
+ */
+abstract class Utf16BytesToCodeUnitsDecoder implements _ListRangeIterator {
+  final _ListRangeIterator utf16EncodedBytesIterator;
+  final int replacementCodepoint;
+  int _current = null;
+
+  Utf16BytesToCodeUnitsDecoder._fromListRangeIterator(
+      this.utf16EncodedBytesIterator, this.replacementCodepoint);
+
+  factory Utf16BytesToCodeUnitsDecoder(List<int> utf16EncodedBytes, [
+      int offset = 0, int length,
+      int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+    if (length == null) {
+      length = utf16EncodedBytes.length - offset;
+    }
+    if (hasUtf16beBom(utf16EncodedBytes, offset, length)) {
+      return new Utf16beBytesToCodeUnitsDecoder(utf16EncodedBytes, offset + 2,
+          length - 2, false, replacementCodepoint);
+    } else if (hasUtf16leBom(utf16EncodedBytes, offset, length)) {
+      return new Utf16leBytesToCodeUnitsDecoder(utf16EncodedBytes, offset + 2,
+          length - 2, false, replacementCodepoint);
+    } else {
+      return new Utf16beBytesToCodeUnitsDecoder(utf16EncodedBytes, offset,
+          length, false, replacementCodepoint);
+    }
+  }
+
+  /**
+   * Provides a fast way to decode the rest of the source bytes in a single
+   * call. This method trades memory for improved speed in that it potentially
+   * over-allocates the List containing results.
+   */
+  List<int> decodeRest() {
+    List<int> codeunits = new List<int>(remaining);
+    int i = 0;
+    while (moveNext()) {
+      codeunits[i++] = current;
+    }
+    if (i == codeunits.length) {
+      return codeunits;
+    } else {
+      List<int> truncCodeunits = new List<int>(i);
+      truncCodeunits.setRange(0, i, codeunits);
+      return truncCodeunits;
+    }
+  }
+
+  int get current => _current;
+
+  bool moveNext() {
+    _current = null;
+    if (utf16EncodedBytesIterator.remaining < 2) {
+      utf16EncodedBytesIterator.moveNext();
+      if (replacementCodepoint != null) {
+        _current = replacementCodepoint;
+        return true;
+      } else {
+        throw new ArgumentError(
+            "Invalid UTF16 at ${utf16EncodedBytesIterator.position}");
+      }
+    } else {
+      _current = decode();
+      return true;
+    }
+  }
+
+  int get position => utf16EncodedBytesIterator.position ~/ 2;
+
+  void backup([int by = 1]) {
+    utf16EncodedBytesIterator.backup(2 * by);
+  }
+
+  int get remaining => (utf16EncodedBytesIterator.remaining + 1) ~/ 2;
+
+  void skip([int count = 1]) {
+    utf16EncodedBytesIterator.skip(2 * count);
+  }
+
+  int decode();
+}
+
+/**
+ * Convert UTF-16BE encoded bytes to utf16 code units by grouping 1-2 bytes
+ * to produce the code unit (0-(2^16)-1).
+ */
+class Utf16beBytesToCodeUnitsDecoder extends Utf16BytesToCodeUnitsDecoder {
+  Utf16beBytesToCodeUnitsDecoder(List<int> utf16EncodedBytes, [
+      int offset = 0, int length, bool stripBom = true,
+      int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) :
+      super._fromListRangeIterator(
+          (new _ListRange(utf16EncodedBytes, offset, length)).iterator,
+          replacementCodepoint) {
+    if (stripBom && hasUtf16beBom(utf16EncodedBytes, offset, length)) {
+      skip();
+    }
+  }
+
+  int decode() {
+    utf16EncodedBytesIterator.moveNext();
+    int hi = utf16EncodedBytesIterator.current;
+    utf16EncodedBytesIterator.moveNext();
+    int lo = utf16EncodedBytesIterator.current;
+    return (hi << 8) + lo;
+  }
+}
+
+/**
+ * Convert UTF-16LE encoded bytes to utf16 code units by grouping 1-2 bytes
+ * to produce the code unit (0-(2^16)-1).
+ */
+class Utf16leBytesToCodeUnitsDecoder extends Utf16BytesToCodeUnitsDecoder {
+  Utf16leBytesToCodeUnitsDecoder(List<int> utf16EncodedBytes, [
+      int offset = 0, int length, bool stripBom = true,
+      int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) :
+      super._fromListRangeIterator(
+          (new _ListRange(utf16EncodedBytes, offset, length)).iterator,
+          replacementCodepoint) {
+    if (stripBom && hasUtf16leBom(utf16EncodedBytes, offset, length)) {
+      skip();
+    }
+  }
+
+  int decode() {
+    utf16EncodedBytesIterator.moveNext();
+    int lo = utf16EncodedBytesIterator.current;
+    utf16EncodedBytesIterator.moveNext();
+    int hi = utf16EncodedBytesIterator.current;
+    return (hi << 8) + lo;
+  }
+}
diff --git a/pkg/utf/lib/utf32.dart b/pkg/utf/lib/utf32.dart
new file mode 100644
index 0000000..acd465c
--- /dev/null
+++ b/pkg/utf/lib/utf32.dart
@@ -0,0 +1,338 @@
+// Copyright (c) 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 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,
+ * or uses big-endian as a default. This method always strips a leading BOM.
+ * Set the replacementCharacter to null to throw an ArgumentError
+ * rather than replace the bad value.
+ */
+IterableUtf32Decoder decodeUtf32AsIterable(List<int> bytes, [
+    int offset = 0, int length,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  return new IterableUtf32Decoder._(
+      () => new Utf32BytesDecoder(bytes, offset, length, replacementCodepoint));
+}
+
+/**
+ * Decodes the UTF-32BE bytes as an iterable. Thus, the consumer can only convert
+ * as much of the input as needed. This method strips a leading BOM by default,
+ * but can be overridden by setting the optional parameter [stripBom] to false.
+ * Set the replacementCharacter to null to throw an ArgumentError
+ * rather than replace the bad value.
+ */
+IterableUtf32Decoder decodeUtf32beAsIterable(List<int> bytes, [
+    int offset = 0, int length, bool stripBom = true,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  return new IterableUtf32Decoder._(
+      () => new Utf32beBytesDecoder(bytes, offset, length, stripBom,
+          replacementCodepoint));
+}
+
+/**
+ * Decodes the UTF-32LE bytes as an iterable. Thus, the consumer can only convert
+ * as much of the input as needed. This method strips a leading BOM by default,
+ * but can be overridden by setting the optional parameter [stripBom] to false.
+ * Set the replacementCharacter to null to throw an ArgumentError
+ * rather than replace the bad value.
+ */
+IterableUtf32Decoder decodeUtf32leAsIterable(List<int> bytes, [
+    int offset = 0, int length, bool stripBom = true,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  return new IterableUtf32Decoder._(
+      () => new Utf32leBytesDecoder(bytes, offset, length, stripBom,
+          replacementCodepoint));
+}
+
+/**
+ * Produce a String from a sequence of UTF-32 encoded bytes. The parameters
+ * allow an offset into a list of bytes (as int), limiting the length of the
+ * values be decoded and the ability of override the default Unicode
+ * replacement character. Set the replacementCharacter to null to throw an
+ * ArgumentError rather than replace the bad value.
+ */
+String decodeUtf32(List<int> bytes, [int offset = 0, int length,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  return new String.fromCharCodes((new Utf32BytesDecoder(bytes, offset, length,
+      replacementCodepoint)).decodeRest());
+}
+/**
+ * Produce a String from a sequence of UTF-32BE encoded bytes. The parameters
+ * allow an offset into a list of bytes (as int), limiting the length of the
+ * values be decoded and the ability of override the default Unicode
+ * replacement character. Set the replacementCharacter to null to throw an
+ * ArgumentError rather than replace the bad value.
+ */
+String decodeUtf32be(
+    List<int> bytes, [int offset = 0, int length, bool stripBom = true,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) =>
+  new String.fromCharCodes((new Utf32beBytesDecoder(bytes, offset, length, 
+    stripBom, replacementCodepoint)).decodeRest());
+
+/**
+ * Produce a String from a sequence of UTF-32LE encoded bytes. The parameters
+ * allow an offset into a list of bytes (as int), limiting the length of the
+ * values be decoded and the ability of override the default Unicode
+ * replacement character. Set the replacementCharacter to null to throw an
+ * ArgumentError rather than replace the bad value.
+ */
+String decodeUtf32le(
+    List<int> bytes, [int offset = 0, int length, bool stripBom = true,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) =>
+    new String.fromCharCodes((new Utf32leBytesDecoder(bytes, offset, length,
+      stripBom, replacementCodepoint)).decodeRest());
+
+/**
+ * Produce a list of UTF-32 encoded bytes. This method prefixes the resulting
+ * bytes with a big-endian byte-order-marker.
+ */
+List<int> encodeUtf32(String str) =>
+    encodeUtf32be(str, true);
+
+/**
+ * Produce a list of UTF-32BE encoded bytes. By default, this method produces
+ * UTF-32BE bytes with no BOM.
+ */
+List<int> encodeUtf32be(String str, [bool writeBOM = false]) {
+  List<int> utf32CodeUnits = stringToCodepoints(str);
+  List<int> encoding = new List<int>(4 * utf32CodeUnits.length +
+      (writeBOM ? 4 : 0));
+  int i = 0;
+  if (writeBOM) {
+    encoding[i++] = 0;
+    encoding[i++] = 0;
+    encoding[i++] = UNICODE_UTF_BOM_HI;
+    encoding[i++] = UNICODE_UTF_BOM_LO;
+  }
+  for (int unit in utf32CodeUnits) {
+    encoding[i++] = (unit >> 24) & UNICODE_BYTE_ZERO_MASK;
+    encoding[i++] = (unit >> 16) & UNICODE_BYTE_ZERO_MASK;
+    encoding[i++] = (unit >> 8) & UNICODE_BYTE_ZERO_MASK;
+    encoding[i++] = unit & UNICODE_BYTE_ZERO_MASK;
+  }
+  return encoding;
+}
+
+/**
+ * Produce a list of UTF-32LE encoded bytes. By default, this method produces
+ * UTF-32BE bytes with no BOM.
+ */
+List<int> encodeUtf32le(String str, [bool writeBOM = false]) {
+  List<int> utf32CodeUnits = stringToCodepoints(str);
+  List<int> encoding = new List<int>(4 * utf32CodeUnits.length +
+      (writeBOM ? 4 : 0));
+  int i = 0;
+  if (writeBOM) {
+    encoding[i++] = UNICODE_UTF_BOM_LO;
+    encoding[i++] = UNICODE_UTF_BOM_HI;
+    encoding[i++] = 0;
+    encoding[i++] = 0;
+  }
+  for (int unit in utf32CodeUnits) {
+    encoding[i++] = unit & UNICODE_BYTE_ZERO_MASK;
+    encoding[i++] = (unit >> 8) & UNICODE_BYTE_ZERO_MASK;
+    encoding[i++] = (unit >> 16) & UNICODE_BYTE_ZERO_MASK;
+    encoding[i++] = (unit >> 24) & UNICODE_BYTE_ZERO_MASK;
+  }
+  return encoding;
+}
+
+/**
+ * Identifies whether a List of bytes starts (based on offset) with a
+ * byte-order marker (BOM).
+ */
+bool hasUtf32Bom(
+    List<int> utf32EncodedBytes, [int offset = 0, int length]) {
+  return hasUtf32beBom(utf32EncodedBytes, offset, length) ||
+      hasUtf32leBom(utf32EncodedBytes, offset, length);
+}
+
+/**
+ * Identifies whether a List of bytes starts (based on offset) with a
+ * big-endian byte-order marker (BOM).
+ */
+bool hasUtf32beBom(List<int> utf32EncodedBytes, [int offset = 0, int length]) {
+  int end = length != null ? offset + length : utf32EncodedBytes.length;
+  return (offset + 4) <= end &&
+      utf32EncodedBytes[offset] == 0 && utf32EncodedBytes[offset + 1] == 0 &&
+      utf32EncodedBytes[offset + 2] == UNICODE_UTF_BOM_HI &&
+      utf32EncodedBytes[offset + 3] == UNICODE_UTF_BOM_LO;
+}
+
+/**
+ * Identifies whether a List of bytes starts (based on offset) with a
+ * little-endian byte-order marker (BOM).
+ */
+bool hasUtf32leBom(List<int> utf32EncodedBytes, [int offset = 0, int length]) {
+  int end = length != null ? offset + length : utf32EncodedBytes.length;
+  return (offset + 4) <= end &&
+      utf32EncodedBytes[offset] == UNICODE_UTF_BOM_LO &&
+      utf32EncodedBytes[offset + 1] == UNICODE_UTF_BOM_HI &&
+      utf32EncodedBytes[offset + 2] == 0 && utf32EncodedBytes[offset + 3] == 0;
+}
+
+typedef Utf32BytesDecoder Utf32BytesDecoderProvider();
+
+/**
+ * Return type of [decodeUtf32AsIterable] and variants. The Iterable type
+ * provides an iterator on demand and the iterator will only translate bytes
+ * as requested by the user of the iterator. (Note: results are not cached.)
+ */
+// TODO(floitsch): Consider removing the extend and switch to implements since
+// that's cheaper to allocate.
+class IterableUtf32Decoder extends IterableBase<int> {
+  final Utf32BytesDecoderProvider codeunitsProvider;
+
+  IterableUtf32Decoder._(this.codeunitsProvider);
+
+  Utf32BytesDecoder get iterator => codeunitsProvider();
+}
+
+/**
+ * Abstrace parent class converts encoded bytes to codepoints.
+ */
+abstract class Utf32BytesDecoder implements _ListRangeIterator {
+  final _ListRangeIterator utf32EncodedBytesIterator;
+  final int replacementCodepoint;
+  int _current = null;
+
+  Utf32BytesDecoder._fromListRangeIterator(
+      this.utf32EncodedBytesIterator, this.replacementCodepoint);
+
+  factory Utf32BytesDecoder(List<int> utf32EncodedBytes, [
+      int offset = 0, int length,
+      int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+    if (length == null) {
+      length = utf32EncodedBytes.length - offset;
+    }
+    if (hasUtf32beBom(utf32EncodedBytes, offset, length)) {
+      return new Utf32beBytesDecoder(utf32EncodedBytes, offset + 4, length - 4,
+          false, replacementCodepoint);
+    } else if (hasUtf32leBom(utf32EncodedBytes, offset, length)) {
+      return new Utf32leBytesDecoder(utf32EncodedBytes, offset + 4, length - 4,
+          false, replacementCodepoint);
+    } else {
+      return new Utf32beBytesDecoder(utf32EncodedBytes, offset, length, false,
+          replacementCodepoint);
+    }
+  }
+
+  List<int> decodeRest() {
+    List<int> codeunits = new List<int>(remaining);
+    int i = 0;
+    while (moveNext()) {
+      codeunits[i++] = current;
+    }
+    return codeunits;
+  }
+
+  int get current => _current;
+
+  bool moveNext() {
+    _current = null;
+    if (utf32EncodedBytesIterator.remaining < 4) {
+      utf32EncodedBytesIterator.skip(utf32EncodedBytesIterator.remaining);
+      if (replacementCodepoint != null) {
+          _current = replacementCodepoint;
+          return true;
+      } else {
+        throw new ArgumentError(
+            "Invalid UTF32 at ${utf32EncodedBytesIterator.position}");
+      }
+    } else {
+      int codepoint = decode();
+      if (_validCodepoint(codepoint)) {
+        _current = codepoint;
+        return true;
+      } else if (replacementCodepoint != null) {
+        _current = replacementCodepoint;
+        return true;
+      } else {
+        throw new ArgumentError(
+            "Invalid UTF32 at ${utf32EncodedBytesIterator.position}");
+      }
+    }
+  }
+
+  int get position => utf32EncodedBytesIterator.position ~/ 4;
+
+  void backup([int by = 1]) {
+    utf32EncodedBytesIterator.backup(4 * by);
+  }
+
+  int get remaining => (utf32EncodedBytesIterator.remaining + 3) ~/ 4;
+
+  void skip([int count = 1]) {
+    utf32EncodedBytesIterator.skip(4 * count);
+  }
+
+  int decode();
+}
+
+/**
+ * Convert UTF-32BE encoded bytes to codepoints by grouping 4 bytes
+ * to produce the unicode codepoint.
+ */
+class Utf32beBytesDecoder extends Utf32BytesDecoder {
+  Utf32beBytesDecoder(List<int> utf32EncodedBytes, [int offset = 0,
+      int length, bool stripBom = true,
+      int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) :
+      super._fromListRangeIterator(
+          (new _ListRange(utf32EncodedBytes, offset, length)).iterator,
+          replacementCodepoint) {
+    if (stripBom && hasUtf32beBom(utf32EncodedBytes, offset, length)) {
+      skip();
+    }
+  }
+
+  int decode() {
+    utf32EncodedBytesIterator.moveNext();
+    int value = utf32EncodedBytesIterator.current;
+    utf32EncodedBytesIterator.moveNext();
+    value = (value << 8) + utf32EncodedBytesIterator.current;
+    utf32EncodedBytesIterator.moveNext();
+    value = (value << 8) + utf32EncodedBytesIterator.current;
+    utf32EncodedBytesIterator.moveNext();
+    value = (value << 8) + utf32EncodedBytesIterator.current;
+    return value;
+  }
+}
+
+/**
+ * Convert UTF-32BE encoded bytes to codepoints by grouping 4 bytes
+ * to produce the unicode codepoint.
+ */
+class Utf32leBytesDecoder extends Utf32BytesDecoder {
+  Utf32leBytesDecoder(List<int> utf32EncodedBytes, [int offset = 0,
+      int length, bool stripBom = true,
+      int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) :
+      super._fromListRangeIterator(
+          (new _ListRange(utf32EncodedBytes, offset, length)).iterator,
+          replacementCodepoint) {
+    if (stripBom && hasUtf32leBom(utf32EncodedBytes, offset, length)) {
+      skip();
+    }
+  }
+
+  int decode() {
+    utf32EncodedBytesIterator.moveNext();
+    int value = utf32EncodedBytesIterator.current;
+    utf32EncodedBytesIterator.moveNext();
+    value += (utf32EncodedBytesIterator.current << 8);
+    utf32EncodedBytesIterator.moveNext();
+    value += (utf32EncodedBytesIterator.current << 16);
+    utf32EncodedBytesIterator.moveNext();
+    value += (utf32EncodedBytesIterator.current << 24);
+    return value;
+  }
+}
+
+bool _validCodepoint(int codepoint) {
+  return (codepoint >= 0 && codepoint < UNICODE_UTF16_RESERVED_LO) ||
+      (codepoint > UNICODE_UTF16_RESERVED_HI &&
+      codepoint < UNICODE_VALID_RANGE_MAX);
+}
diff --git a/pkg/utf/lib/utf8.dart b/pkg/utf/lib/utf8.dart
new file mode 100644
index 0000000..7543865
--- /dev/null
+++ b/pkg/utf/lib/utf8.dart
@@ -0,0 +1,275 @@
+// Copyright (c) 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 dart.utf;
+
+const int _UTF8_ONE_BYTE_MAX = 0x7f;
+const int _UTF8_TWO_BYTE_MAX = 0x7ff;
+const int _UTF8_THREE_BYTE_MAX = 0xffff;
+
+const int _UTF8_LO_SIX_BIT_MASK = 0x3f;
+
+const int _UTF8_FIRST_BYTE_OF_TWO_BASE = 0xc0;
+const int _UTF8_FIRST_BYTE_OF_THREE_BASE = 0xe0;
+const int _UTF8_FIRST_BYTE_OF_FOUR_BASE = 0xf0;
+const int _UTF8_FIRST_BYTE_OF_FIVE_BASE = 0xf8;
+const int _UTF8_FIRST_BYTE_OF_SIX_BASE = 0xfc;
+
+const int _UTF8_FIRST_BYTE_OF_TWO_MASK = 0x1f;
+const int _UTF8_FIRST_BYTE_OF_THREE_MASK = 0xf;
+const int _UTF8_FIRST_BYTE_OF_FOUR_MASK = 0x7;
+
+const int _UTF8_FIRST_BYTE_BOUND_EXCL = 0xfe;
+const int _UTF8_SUBSEQUENT_BYTE_BASE = 0x80;
+
+/**
+ * Decodes the UTF-8 bytes as an iterable. Thus, the consumer can only convert
+ * as much of the input as needed. Set the replacementCharacter to null to
+ * throw an ArgumentError rather than replace the bad value.
+ */
+IterableUtf8Decoder decodeUtf8AsIterable(List<int> bytes, [int offset = 0,
+    int length,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  return new IterableUtf8Decoder(bytes, offset, length, replacementCodepoint);
+}
+
+/**
+ * Produce a String from a List of UTF-8 encoded bytes. The parameters
+ * can set an offset into a list of bytes (as int), limit the length of the
+ * values to be decoded, and override the default Unicode replacement character.
+ * Set the replacementCharacter to null to throw an ArgumentError
+ * rather than replace the bad value.
+ */
+String decodeUtf8(List<int> bytes, [int offset = 0, int length,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  return new String.fromCharCodes(
+      (new Utf8Decoder(bytes, offset, length, replacementCodepoint))
+      .decodeRest());
+}
+
+/**
+ * Produce a sequence of UTF-8 encoded bytes from the provided string.
+ */
+List<int> encodeUtf8(String str) =>
+  codepointsToUtf8(stringToCodepoints(str));
+
+int _addToEncoding(int offset, int bytes, int value, List<int> buffer) {
+  while (bytes > 0) {
+    buffer[offset + bytes] = _UTF8_SUBSEQUENT_BYTE_BASE |
+        (value & _UTF8_LO_SIX_BIT_MASK);
+    value = value >> 6;
+    bytes--;
+  }
+  return value;
+}
+
+/**
+ * Encode code points as UTF-8 code units.
+ */
+List<int> codepointsToUtf8(
+    List<int> codepoints, [int offset = 0, int length]) {
+  _ListRange source = new _ListRange(codepoints, offset, length);
+
+  int encodedLength = 0;
+  for (int value in source) {
+    if (value < 0 || value > UNICODE_VALID_RANGE_MAX) {
+      encodedLength += 3;
+    } else if (value <= _UTF8_ONE_BYTE_MAX) {
+      encodedLength++;
+    } else if (value <= _UTF8_TWO_BYTE_MAX) {
+      encodedLength += 2;
+    } else if (value <= _UTF8_THREE_BYTE_MAX) {
+      encodedLength += 3;
+    } else if (value <= UNICODE_VALID_RANGE_MAX) {
+      encodedLength += 4;
+    }
+  }
+
+  List<int> encoded = new List<int>(encodedLength);
+  int insertAt = 0;
+  for (int value in source) {
+    if (value < 0 || value > UNICODE_VALID_RANGE_MAX) {
+      encoded.setRange(insertAt, insertAt + 3, [0xef, 0xbf, 0xbd]);
+      insertAt += 3;
+    } else if (value <= _UTF8_ONE_BYTE_MAX) {
+      encoded[insertAt] = value;
+      insertAt++;
+    } else if (value <= _UTF8_TWO_BYTE_MAX) {
+      encoded[insertAt] = _UTF8_FIRST_BYTE_OF_TWO_BASE | (
+          _UTF8_FIRST_BYTE_OF_TWO_MASK &
+          _addToEncoding(insertAt, 1, value, encoded));
+      insertAt += 2;
+    } else if (value <= _UTF8_THREE_BYTE_MAX) {
+      encoded[insertAt] = _UTF8_FIRST_BYTE_OF_THREE_BASE | (
+          _UTF8_FIRST_BYTE_OF_THREE_MASK &
+          _addToEncoding(insertAt, 2, value, encoded));
+      insertAt += 3;
+    } else if (value <= UNICODE_VALID_RANGE_MAX) {
+      encoded[insertAt] = _UTF8_FIRST_BYTE_OF_FOUR_BASE | (
+          _UTF8_FIRST_BYTE_OF_FOUR_MASK &
+          _addToEncoding(insertAt, 3, value, encoded));
+      insertAt += 4;
+    }
+  }
+  return encoded;
+}
+
+// Because UTF-8 specifies byte order, we do not have to follow the pattern
+// used by UTF-16 & UTF-32 regarding byte order.
+List<int> utf8ToCodepoints(
+    List<int> utf8EncodedBytes, [int offset = 0, int length,
+    int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
+  return new Utf8Decoder(utf8EncodedBytes, offset, length,
+      replacementCodepoint).decodeRest();
+}
+
+/**
+ * Return type of [decodeUtf8AsIterable] and variants. The Iterable type
+ * provides an iterator on demand and the iterator will only translate bytes
+ * as requested by the user of the iterator. (Note: results are not cached.)
+ */
+// TODO(floitsch): Consider removing the extend and switch to implements since
+// that's cheaper to allocate.
+class IterableUtf8Decoder extends IterableBase<int> {
+  final List<int> bytes;
+  final int offset;
+  final int length;
+  final int replacementCodepoint;
+
+  IterableUtf8Decoder(this.bytes, [this.offset = 0, this.length = null,
+      this.replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]);
+
+  Utf8Decoder get iterator =>
+      new Utf8Decoder(bytes, offset, length, replacementCodepoint);
+}
+
+/**
+ * Provides an iterator of Unicode codepoints from UTF-8 encoded bytes. The
+ * parameters can set an offset into a list of bytes (as int), limit the length
+ * of the values to be decoded, and override the default Unicode replacement
+ * character. Set the replacementCharacter to null to throw an
+ * ArgumentError rather than replace the bad value. The return value
+ * from this method can be used as an Iterable (e.g. in a for-loop).
+ */
+class Utf8Decoder implements Iterator<int> {
+  final _ListRangeIterator utf8EncodedBytesIterator;
+  final int replacementCodepoint;
+  int _current = null;
+
+  Utf8Decoder(List<int> utf8EncodedBytes, [int offset = 0, int length,
+      this.replacementCodepoint =
+      UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) :
+      utf8EncodedBytesIterator =
+          (new _ListRange(utf8EncodedBytes, offset, length)).iterator;
+
+
+  Utf8Decoder._fromListRangeIterator(_ListRange source, [
+      this.replacementCodepoint =
+      UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) :
+      utf8EncodedBytesIterator = source.iterator;
+
+  /** Decode the remaininder of the characters in this decoder
+    * into a [List<int>].
+    */
+  List<int> decodeRest() {
+    List<int> codepoints = new List<int>(utf8EncodedBytesIterator.remaining);
+    int i = 0;
+    while (moveNext()) {
+      codepoints[i++] = current;
+    }
+    if (i == codepoints.length) {
+      return codepoints;
+    } else {
+      List<int> truncCodepoints = new List<int>(i);
+      truncCodepoints.setRange(0, i, codepoints);
+      return truncCodepoints;
+    }
+  }
+
+  int get current => _current;
+
+  bool moveNext() {
+    _current = null;
+
+    if (!utf8EncodedBytesIterator.moveNext()) return false;
+
+    int value = utf8EncodedBytesIterator.current;
+    int additionalBytes = 0;
+
+    if (value < 0) {
+      if (replacementCodepoint != null) {
+        _current = replacementCodepoint;
+        return true;
+      } else {
+        throw new ArgumentError(
+            "Invalid UTF8 at ${utf8EncodedBytesIterator.position}");
+      }
+    } else if (value <= _UTF8_ONE_BYTE_MAX) {
+      _current = value;
+      return true;
+    } else if (value < _UTF8_FIRST_BYTE_OF_TWO_BASE) {
+      if (replacementCodepoint != null) {
+        _current = replacementCodepoint;
+        return true;
+      } else {
+        throw new ArgumentError(
+            "Invalid UTF8 at ${utf8EncodedBytesIterator.position}");
+      }
+    } else if (value < _UTF8_FIRST_BYTE_OF_THREE_BASE) {
+      value -= _UTF8_FIRST_BYTE_OF_TWO_BASE;
+      additionalBytes = 1;
+    } else if (value < _UTF8_FIRST_BYTE_OF_FOUR_BASE) {
+      value -= _UTF8_FIRST_BYTE_OF_THREE_BASE;
+      additionalBytes = 2;
+    } else if (value < _UTF8_FIRST_BYTE_OF_FIVE_BASE) {
+      value -= _UTF8_FIRST_BYTE_OF_FOUR_BASE;
+      additionalBytes = 3;
+    } else if (value < _UTF8_FIRST_BYTE_OF_SIX_BASE) {
+      value -= _UTF8_FIRST_BYTE_OF_FIVE_BASE;
+      additionalBytes = 4;
+    } else if (value < _UTF8_FIRST_BYTE_BOUND_EXCL) {
+      value -= _UTF8_FIRST_BYTE_OF_SIX_BASE;
+      additionalBytes = 5;
+    } else if (replacementCodepoint != null) {
+      _current = replacementCodepoint;
+      return true;
+    } else {
+      throw new ArgumentError(
+          "Invalid UTF8 at ${utf8EncodedBytesIterator.position}");
+    }
+    int j = 0;
+    while (j < additionalBytes && utf8EncodedBytesIterator.moveNext()) {
+      int nextValue = utf8EncodedBytesIterator.current;
+      if (nextValue > _UTF8_ONE_BYTE_MAX &&
+          nextValue < _UTF8_FIRST_BYTE_OF_TWO_BASE) {
+        value = ((value << 6) | (nextValue & _UTF8_LO_SIX_BIT_MASK));
+      } else {
+        // if sequence-starting code unit, reposition cursor to start here
+        if (nextValue >= _UTF8_FIRST_BYTE_OF_TWO_BASE) {
+          utf8EncodedBytesIterator.backup();
+        }
+        break;
+      }
+      j++;
+    }
+    bool validSequence = (j == additionalBytes && (
+        value < UNICODE_UTF16_RESERVED_LO ||
+        value > UNICODE_UTF16_RESERVED_HI));
+    bool nonOverlong =
+        (additionalBytes == 1 && value > _UTF8_ONE_BYTE_MAX) ||
+        (additionalBytes == 2 && value > _UTF8_TWO_BYTE_MAX) ||
+        (additionalBytes == 3 && value > _UTF8_THREE_BYTE_MAX);
+    bool inRange = value <= UNICODE_VALID_RANGE_MAX;
+    if (validSequence && nonOverlong && inRange) {
+      _current = value;
+      return true;
+    } else if (replacementCodepoint != null) {
+      _current = replacementCodepoint;
+      return true;
+    } else {
+      throw new ArgumentError(
+          "Invalid UTF8 at ${utf8EncodedBytesIterator.position - j}");
+    }
+  }
+}
diff --git a/pkg/utf/lib/utf_stream.dart b/pkg/utf/lib/utf_stream.dart
new file mode 100644
index 0000000..8440313
--- /dev/null
+++ b/pkg/utf/lib/utf_stream.dart
@@ -0,0 +1,198 @@
+// 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.utf;
+
+abstract class _StringDecoder
+    extends StreamEventTransformer<List<int>, String> {
+  List<int> _carry;
+  List<int> _buffer;
+  int _replacementChar;
+
+  _StringDecoder(int this._replacementChar);
+
+  void handleData(List<int> bytes, EventSink<String> sink) {
+    try {
+      _buffer = <int>[];
+      List<int> carry = _carry;
+      _carry = null;
+      int pos = 0;
+      int available = bytes.length;
+      // If we have carry-over data, start from negative index, indicating carry
+      // index.
+      int goodChars = 0;
+      if (carry != null) pos = -carry.length;
+      while (pos < available) {
+        int currentPos = pos;
+        int getNext() {
+          if (pos < 0) {
+            return carry[pos++ + carry.length];
+          } else if (pos < available) {
+            return bytes[pos++];
+          }
+          return null;
+        }
+        int consumed = _processBytes(getNext);
+        if (consumed > 0) {
+          goodChars = _buffer.length;
+        } else if (consumed == 0) {
+          _buffer.length = goodChars;
+          if (currentPos < 0) {
+            _carry = [];
+            _carry.addAll(carry);
+            _carry.addAll(bytes);
+          } else {
+            _carry = bytes.sublist(currentPos);
+          }
+          break;
+        } else {
+          // Invalid byte at position pos - 1
+          _buffer.length = goodChars;
+          _addChar(-1);
+          goodChars = _buffer.length;
+        }
+      }
+      if (_buffer.length > 0) {
+        // Limit to 'goodChars', if lower than actual charCodes in the buffer.
+        sink.add(new String.fromCharCodes(_buffer));
+      }
+      _buffer = null;
+    } catch (e) {
+      sink.addError(e);
+    }
+  }
+
+  void handleDone(EventSink<String> sink) {
+    if (_carry != null) {
+      if (_replacementChar != null) {
+        sink.add(new String.fromCharCodes(
+            new List.filled(_carry.length, _replacementChar)));
+      } else {
+        throw new ArgumentError('Invalid codepoint');
+      }
+    }
+    sink.close();
+  }
+
+  int _processBytes(int getNext());
+
+  void _addChar(int char) {
+    void error() {
+      if (_replacementChar != null) {
+        char = _replacementChar;
+      } else {
+        throw new ArgumentError('Invalid codepoint');
+      }
+    }
+    if (char < 0) error();
+    if (char >= 0xD800 && char <= 0xDFFF) error();
+    if (char > 0x10FFFF) error();
+    _buffer.add(char);
+  }
+}
+
+/**
+ * StringTransformer that decodes a stream of UTF-8 encoded bytes.
+ */
+class Utf8DecoderTransformer extends _StringDecoder {
+  Utf8DecoderTransformer(
+      [int replacementChar = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT])
+    : super(replacementChar);
+
+  int _processBytes(int getNext()) {
+    int value = getNext();
+    if ((value & 0xFF) != value) return -1;  // Not a byte.
+    if ((value & 0x80) == 0x80) {
+      int additionalBytes;
+      int min;
+      if ((value & 0xe0) == 0xc0) {  // 110xxxxx
+        value = value & 0x1F;
+        additionalBytes = 1;
+        min = 0x80;
+      } else if ((value & 0xf0) == 0xe0) {  // 1110xxxx
+        value = value & 0x0F;
+        additionalBytes = 2;
+        min = 0x800;
+      } else if ((value & 0xf8) == 0xf0) {  // 11110xxx
+        value = value & 0x07;
+        additionalBytes = 3;
+        min = 0x10000;
+      } else if ((value & 0xfc) == 0xf8) {  // 111110xx
+        value = value & 0x03;
+        additionalBytes = 4;
+        min = 0x200000;
+      } else if ((value & 0xfe) == 0xfc) {  // 1111110x
+        value = value & 0x01;
+        additionalBytes = 5;
+        min = 0x4000000;
+      } else {
+        return -1;
+      }
+      for (int i = 0; i < additionalBytes; i++) {
+        int next = getNext();
+        if (next == null) return 0;  // Not enough chars, reset.
+        if ((next & 0xc0) != 0x80 || (next & 0xff) != next) return -1;
+        value = value << 6 | (next & 0x3f);
+        if (additionalBytes >= 3 && i == 0 && value << 12 > 0x10FFFF) {
+          _addChar(-1);
+        }
+      }
+      // Invalid charCode if less then minimum expected.
+      if (value < min) value = -1;
+      _addChar(value);
+      return 1 + additionalBytes;
+    }
+    _addChar(value);
+    return 1;
+  }
+}
+
+
+abstract class _StringEncoder
+    extends StreamEventTransformer<String, List<int>> {
+
+  void handleData(String data, EventSink<List<int>> sink) {
+    sink.add(_processString(data));
+  }
+
+  List<int> _processString(String string);
+}
+
+/**
+ * StringTransformer that UTF-8 encodes a stream of strings.
+ */
+class Utf8EncoderTransformer extends _StringEncoder {
+  List<int> _processString(String string) {
+    var bytes = [];
+    int pos = 0;
+    List<int> codepoints = _utf16CodeUnitsToCodepoints(string.codeUnits);
+    int length = codepoints.length;
+    for (int i = 0; i < length; i++) {
+      int additionalBytes;
+      int charCode = codepoints[i];
+      if (charCode <= 0x007F) {
+        additionalBytes = 0;
+        bytes.add(charCode);
+      } else if (charCode <= 0x07FF) {
+        // 110xxxxx (xxxxx is top 5 bits).
+        bytes.add(((charCode >> 6) & 0x1F) | 0xC0);
+        additionalBytes = 1;
+      } else if (charCode <= 0xFFFF) {
+        // 1110xxxx (xxxx is top 4 bits)
+        bytes.add(((charCode >> 12) & 0x0F)| 0xE0);
+        additionalBytes = 2;
+      } else {
+        // 11110xxx (xxx is top 3 bits)
+        bytes.add(((charCode >> 18) & 0x07) | 0xF0);
+        additionalBytes = 3;
+      }
+      for (int i = additionalBytes; i > 0; i--) {
+        // 10xxxxxx (xxxxxx is next 6 bits from the top).
+        bytes.add(((charCode >> (6 * (i - 1))) & 0x3F) | 0x80);
+      }
+      pos += additionalBytes + 1;
+    }
+    return bytes;
+  }
+}
diff --git a/pkg/utf/pubspec.yaml b/pkg/utf/pubspec.yaml
new file mode 100644
index 0000000..707be03
--- /dev/null
+++ b/pkg/utf/pubspec.yaml
@@ -0,0 +1,9 @@
+name: utf
+author: Dart Team <misc@dartlang.org>
+description: >
+ A Unicode library. Intended for advanced use where the built-in facilities
+ are too limiting.
+homepage: http://www.dartlang.org
+documentation: http://api.dartlang.org/docs/pkg/utf
+dev_dependencies:
+  unittest: any
diff --git a/pkg/utf/test/utf8_test.dart b/pkg/utf/test/utf8_test.dart
new file mode 100644
index 0000000..af46557
--- /dev/null
+++ b/pkg/utf/test/utf8_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 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 utf8_test;
+import "package:expect/expect.dart";
+import "package:utf/utf.dart";
+
+String decode(List<int> bytes) => decodeUtf8(bytes);
+
+main() {
+  // Google favorite: "Îñţérñåţîöñåļîžåţîờñ".
+  String string = decode([0xc3, 0x8e, 0xc3, 0xb1, 0xc5, 0xa3, 0xc3, 0xa9, 0x72,
+                          0xc3, 0xb1, 0xc3, 0xa5, 0xc5, 0xa3, 0xc3, 0xae, 0xc3,
+                          0xb6, 0xc3, 0xb1, 0xc3, 0xa5, 0xc4, 0xbc, 0xc3, 0xae,
+                          0xc5, 0xbe, 0xc3, 0xa5, 0xc5, 0xa3, 0xc3, 0xae, 0xe1,
+                          0xbb, 0x9d, 0xc3, 0xb1]);
+  Expect.stringEquals("Îñţérñåţîöñåļîžåţîờñ", string);
+
+  // Blueberry porridge in Danish: "blåbærgrød".
+  string = decode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6, 0x72, 0x67, 0x72,
+                   0xc3, 0xb8, 0x64]);
+  Expect.stringEquals("blåbærgrød", string);
+
+  // "சிவா அணாமாைல", that is "Siva Annamalai" in Tamil.
+  string = decode([0xe0, 0xae, 0x9a, 0xe0, 0xae, 0xbf, 0xe0, 0xae, 0xb5, 0xe0,
+                   0xae, 0xbe, 0x20, 0xe0, 0xae, 0x85, 0xe0, 0xae, 0xa3, 0xe0,
+                   0xae, 0xbe, 0xe0, 0xae, 0xae, 0xe0, 0xae, 0xbe, 0xe0, 0xaf,
+                   0x88, 0xe0, 0xae, 0xb2]);
+  Expect.stringEquals("சிவா அணாமாைல", string);
+
+  // "िसवा अणामालै", that is "Siva Annamalai" in Devanagari.
+  string = decode([0xe0, 0xa4, 0xbf, 0xe0, 0xa4, 0xb8, 0xe0, 0xa4, 0xb5, 0xe0,
+                   0xa4, 0xbe, 0x20, 0xe0, 0xa4, 0x85, 0xe0, 0xa4, 0xa3, 0xe0,
+                   0xa4, 0xbe, 0xe0, 0xa4, 0xae, 0xe0, 0xa4, 0xbe, 0xe0, 0xa4,
+                   0xb2, 0xe0, 0xa5, 0x88]);
+  Expect.stringEquals("िसवा अणामालै", string);
+
+  // DESERET CAPITAL LETTER BEE, unicode 0x10412(0xD801+0xDC12)
+  // UTF-8: F0 90 90 92
+  string = decode([0xf0, 0x90, 0x90, 0x92]);
+  Expect.equals(string.length, 2);
+  Expect.equals("𐐒".length, 2);
+  Expect.stringEquals("𐐒", string);
+
+  // TODO(ahe): Add tests of bad input.
+}
diff --git a/pkg/utf/test/utf_test.dart b/pkg/utf/test/utf_test.dart
new file mode 100644
index 0000000..c4a1e94
--- /dev/null
+++ b/pkg/utf/test/utf_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 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 utf_test;
+import "package:expect/expect.dart";
+import "package:utf/utf.dart";
+
+main() {
+  String str = new String.fromCharCodes([0x1d537]);
+  // String.codeUnits gives 16-bit code units, but stringToCodepoints gives
+  // back the original code points.
+  Expect.listEquals([0xd835, 0xdd37], str.codeUnits);
+  Expect.listEquals([0x1d537], stringToCodepoints(str));
+}
diff --git a/pkg/watcher/test/utils.dart b/pkg/watcher/test/utils.dart
index 3bbe0e1..656ddf8 100644
--- a/pkg/watcher/test/utils.dart
+++ b/pkg/watcher/test/utils.dart
@@ -38,6 +38,7 @@
 
 void initConfig() {
   useCompactVMConfiguration();
+  filterStacks = true;
 }
 
 /// Creates the sandbox directory the other functions in this library use and
diff --git a/runtime/bin/dbg_message.cc b/runtime/bin/dbg_message.cc
index 36cfeba..aaf4f90 100644
--- a/runtime/bin/dbg_message.cc
+++ b/runtime/bin/dbg_message.cc
@@ -111,8 +111,7 @@
   }
   intptr_t buflen = pr.ValueLen() + 1;
   char* param_chars = reinterpret_cast<char*>(malloc(buflen));
-  pr.GetValueChars(param_chars, buflen);
-  // TODO(hausner): Decode escape sequences.
+  pr.GetDecodedValueChars(param_chars, buflen);
   return param_chars;
 }
 
@@ -653,9 +652,8 @@
                            "libararyId evaluation target not supported");
     return false;
   } else if (msg_parser.HasParam("classId")) {
-    in_msg->SendErrorReply(msg_id,
-                           "classId evaluation target not supported");
-    return false;
+    intptr_t cls_id = msg_parser.GetIntParam("classId");
+    target = Dart_GetClassFromId(cls_id);
   } else if (msg_parser.HasParam("objectId")) {
     intptr_t obj_id = msg_parser.GetIntParam("objectId");
     target = Dart_GetCachedObject(obj_id);
diff --git a/runtime/bin/filter.cc b/runtime/bin/filter.cc
index 0babea9..3ea389d 100644
--- a/runtime/bin/filter.cc
+++ b/runtime/bin/filter.cc
@@ -82,8 +82,8 @@
   Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
   Filter* filter = GetFilter(filter_obj);
   Dart_Handle data_obj = Dart_GetNativeArgument(args, 1);
-  intptr_t start = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2));
-  intptr_t end = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3));
+  intptr_t start = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
+  intptr_t end = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
   intptr_t chunk_length = end - start;
   intptr_t length;
   Dart_TypedData_Type type;
diff --git a/runtime/bin/process.cc b/runtime/bin/process.cc
index 84cc360..f3ed86a 100644
--- a/runtime/bin/process.cc
+++ b/runtime/bin/process.cc
@@ -201,7 +201,7 @@
   Dart_Handle process = Dart_GetNativeArgument(args, 1);
   intptr_t pid = -1;
   Process::GetProcessIdNativeField(process, &pid);
-  int signal = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2));
+  intptr_t signal = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
   bool success = Process::Kill(pid, signal);
   Dart_SetReturnValue(args, Dart_NewBoolean(success));
 }
diff --git a/runtime/bin/process_android.cc b/runtime/bin/process_android.cc
index 30a488b..4395076 100644
--- a/runtime/bin/process_android.cc
+++ b/runtime/bin/process_android.cc
@@ -22,6 +22,9 @@
 #include "bin/thread.h"
 
 
+extern char **environ;
+
+
 namespace dart {
 namespace bin {
 
@@ -332,7 +335,7 @@
   if (!initialized) {
     SetChildOsErrorMessage(os_error_message);
     Log::PrintErr("Error initializing exit code handler: %s\n",
-                 *os_error_message);
+                  *os_error_message);
     return errno;
   }
 
@@ -465,15 +468,13 @@
       ReportChildError(exec_control[1]);
     }
 
-    if (environment != NULL) {
-      TEMP_FAILURE_RETRY(
-          execve(path,
-                 const_cast<char* const*>(program_arguments),
-                 program_environment));
-    } else {
-      TEMP_FAILURE_RETRY(
-          execvp(path, const_cast<char* const*>(program_arguments)));
+    if (program_environment != NULL) {
+      environ = program_environment;
     }
+
+    TEMP_FAILURE_RETRY(
+        execvp(path, const_cast<char* const*>(program_arguments)));
+
     ReportChildError(exec_control[1]);
   }
 
@@ -568,15 +569,128 @@
 }
 
 
-bool Process::Kill(intptr_t id, int signal) {
-  int result = TEMP_FAILURE_RETRY(kill(id, signal));
-  if (result == -1) {
-    return false;
+class BufferList: public BufferListBase {
+ public:
+  bool Read(int fd, intptr_t available) {
+    // Read all available bytes.
+    while (available > 0) {
+      if (free_size_ == 0) Allocate();
+      ASSERT(free_size_ > 0);
+      ASSERT(free_size_ <= kBufferSize);
+      intptr_t block_size = dart::Utils::Minimum(free_size_, available);
+      intptr_t bytes = TEMP_FAILURE_RETRY(read(
+          fd,
+          reinterpret_cast<void*>(FreeSpaceAddress()),
+          block_size));
+      if (bytes < 0) return false;
+      data_size_ += bytes;
+      free_size_ -= bytes;
+      available -= bytes;
+    }
+    return true;
   }
+};
+
+
+static bool CloseProcessBuffers(struct pollfd fds[3]) {
+  int e = errno;
+  VOID_TEMP_FAILURE_RETRY(close(fds[0].fd));
+  VOID_TEMP_FAILURE_RETRY(close(fds[1].fd));
+  VOID_TEMP_FAILURE_RETRY(close(fds[2].fd));
+  errno = e;
+  return false;
+}
+
+
+bool Process::Wait(intptr_t pid,
+                   intptr_t in,
+                   intptr_t out,
+                   intptr_t err,
+                   intptr_t exit_event,
+                   ProcessResult* result) {
+  // Close input to the process right away.
+  VOID_TEMP_FAILURE_RETRY(close(in));
+
+  // There is no return from this function using Dart_PropagateError
+  // as memory used by the buffer lists is freed through their
+  // destructors.
+  BufferList out_data;
+  BufferList err_data;
+  union {
+    uint8_t bytes[8];
+    int32_t ints[2];
+  } exit_code_data;
+
+  struct pollfd fds[3];
+  fds[0].fd = out;
+  fds[1].fd = err;
+  fds[2].fd = exit_event;
+
+  for (int i = 0; i < 3; i++) {
+    fds[i].events = POLLIN;
+  }
+
+  int alive = 3;
+  while (alive > 0) {
+    // Blocking call waiting for events from the child process.
+    if (TEMP_FAILURE_RETRY(poll(fds, alive, -1)) <= 0) {
+      return CloseProcessBuffers(fds);
+    }
+
+    // Process incoming data.
+    int current_alive = alive;
+    for (int i = 0; i < current_alive; i++) {
+      if (fds[i].revents & POLLIN) {
+        intptr_t avail = FDUtils::AvailableBytes(fds[i].fd);
+        if (fds[i].fd == out) {
+          if (!out_data.Read(out, avail)) {
+            return CloseProcessBuffers(fds);
+          }
+        } else if (fds[i].fd == err) {
+          if (!err_data.Read(err, avail)) {
+            return CloseProcessBuffers(fds);
+          }
+        } else if (fds[i].fd == exit_event) {
+          if (avail == 8) {
+            intptr_t b = TEMP_FAILURE_RETRY(read(exit_event,
+                                                 exit_code_data.bytes, 8));
+            if (b != 8) {
+              return CloseProcessBuffers(fds);
+            }
+          }
+        } else {
+          UNREACHABLE();
+        }
+      }
+      if (fds[i].revents & POLLHUP) {
+        VOID_TEMP_FAILURE_RETRY(close(fds[i].fd));
+        alive--;
+        if (i < alive) {
+          fds[i] = fds[alive];
+        }
+      }
+    }
+  }
+
+  // All handles closed and all data read.
+  result->set_stdout_data(out_data.GetData());
+  result->set_stderr_data(err_data.GetData());
+
+  // Calculate the exit code.
+  intptr_t exit_code = exit_code_data.ints[0];
+  intptr_t negative = exit_code_data.ints[1];
+  if (negative) exit_code = -exit_code;
+  result->set_exit_code(exit_code);
+
   return true;
 }
 
 
+bool Process::Kill(intptr_t id, int signal) {
+  return (TEMP_FAILURE_RETRY(kill(id, signal)) != -1);
+}
+
+
 void Process::TerminateExitCodeHandler() {
   ExitCodeHandler::TerminateExitCodeThread();
 }
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 5e7e838..3ab2072 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -333,9 +333,8 @@
   bool initialized = ExitCodeHandler::EnsureInitialized();
   if (!initialized) {
     SetChildOsErrorMessage(os_error_message);
-    Log::PrintErr(
-            "Error initializing exit code handler: %s\n",
-            *os_error_message);
+    Log::PrintErr("Error initializing exit code handler: %s\n",
+                  *os_error_message);
     return errno;
   }
 
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 13467af..cd582eb 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -186,9 +186,9 @@
   Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
   ASSERT(Dart_IsList(buffer_obj));
   intptr_t offset =
-      DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2));
+      DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
   intptr_t length =
-      DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3));
+      DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
   if (short_socket_writes) {
     length = (length + 1) / 2;
   }
@@ -276,7 +276,7 @@
 void FUNCTION_NAME(Socket_GetStdioHandle)(Dart_NativeArguments args) {
   Dart_Handle socket_obj = Dart_GetNativeArgument(args, 0);
   intptr_t num =
-      DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
+      DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
   ASSERT(num == 0 || num == 1 || num == 2);
   intptr_t socket = Socket::GetStdioHandle(num);
   Dart_Handle err = Socket::SetSocketIdNativeField(socket_obj, socket);
diff --git a/runtime/bin/vmservice/vmservice.dart b/runtime/bin/vmservice/vmservice.dart
index a9790f1..042d467 100644
--- a/runtime/bin/vmservice/vmservice.dart
+++ b/runtime/bin/vmservice/vmservice.dart
@@ -8,7 +8,6 @@
 import 'dart:json' as JSON;
 import 'dart:isolate';
 import 'dart:typed_data';
-import 'dart:utf' as UTF;
 
 part 'constants.dart';
 part 'resources.dart';
diff --git a/runtime/include/dart_debugger_api.h b/runtime/include/dart_debugger_api.h
index b847a91..13b19ac 100755
--- a/runtime/include/dart_debugger_api.h
+++ b/runtime/include/dart_debugger_api.h
@@ -480,7 +480,9 @@
  * The expression is evaluated in the context of \target.
  * If \target is a Dart object, the expression is evaluated as if
  * it were an instance method of the class of the object.
- * TODO(hausner): add other execution contexts, e.g. library and class.
+ * If \target is a Class, the expression is evaluated as if it
+ * were a static method of that class.
+ * TODO(hausner): add 'library' execution context.
  * 
  * \return A handle to the computed value, or an error object if
  * the compilation of the expression fails, or if the evaluation throws
@@ -533,6 +535,16 @@
 
 
 /**
+ * Returns handle to class with class id \class_id.
+ *
+ * Requires there to be a current isolate.
+ *
+ * \return A handle to the class if no error occurs.
+ */
+DART_EXPORT Dart_Handle Dart_GetClassFromId(intptr_t class_id);
+
+
+/**
  * Returns info about the given class \cls_id.
  *
  * \param class_name receives handle to class name (string) if non-null.
diff --git a/runtime/lib/convert_patch.dart b/runtime/lib/convert_patch.dart
new file mode 100644
index 0000000..3ba4f7e
--- /dev/null
+++ b/runtime/lib/convert_patch.dart
@@ -0,0 +1,556 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// JSON conversion.
+
+patch _parseJson(String json, reviver(var key, var value)) {
+  _BuildJsonListener listener;
+  if (reviver == null) {
+    listener = new _BuildJsonListener();
+  } else {
+    listener = new _ReviverJsonListener(reviver);
+  }
+  new _JsonParser(json, listener).parse();
+  return listener.result;
+}
+
+//// Implementation ///////////////////////////////////////////////////////////
+
+// Simple API for JSON parsing.
+
+abstract class _JsonListener {
+  void handleString(String value) {}
+  void handleNumber(num value) {}
+  void handleBool(bool value) {}
+  void handleNull() {}
+  void beginObject() {}
+  void propertyName() {}
+  void propertyValue() {}
+  void endObject() {}
+  void beginArray() {}
+  void arrayElement() {}
+  void endArray() {}
+  /** Called on failure to parse [source]. */
+  void fail(String source, int position, String message) {}
+}
+
+/**
+ * A [JsonListener] that builds data objects from the parser events.
+ *
+ * This is a simple stack-based object builder. It keeps the most recently
+ * seen value in a variable, and uses it depending on the following event.
+ */
+class _BuildJsonListener extends _JsonListener {
+  /**
+   * Stack used to handle nested containers.
+   *
+   * The current container is pushed on the stack when a new one is
+   * started. If the container is a [Map], there is also a current [key]
+   * which is also stored on the stack.
+   */
+  List stack = [];
+  /** The current [Map] or [List] being built. */
+  var currentContainer;
+  /** The most recently read property key. */
+  String key;
+  /** The most recently read value. */
+  var value;
+
+  /** Pushes the currently active container (and key, if a [Map]). */
+  void pushContainer() {
+    if (currentContainer is Map) stack.add(key);
+    stack.add(currentContainer);
+  }
+
+  /** Pops the top container from the [stack], including a key if applicable. */
+  void popContainer() {
+    value = currentContainer;
+    currentContainer = stack.removeLast();
+    if (currentContainer is Map) key = stack.removeLast();
+  }
+
+  void handleString(String value) { this.value = value; }
+  void handleNumber(num value) { this.value = value; }
+  void handleBool(bool value) { this.value = value; }
+  void handleNull() { this.value = null; }
+
+  void beginObject() {
+    pushContainer();
+    currentContainer = {};
+  }
+
+  void propertyName() {
+    key = value;
+    value = null;
+  }
+
+  void propertyValue() {
+    Map map = currentContainer;
+    map[key] = value;
+    key = value = null;
+  }
+
+  void endObject() {
+    popContainer();
+  }
+
+  void beginArray() {
+    pushContainer();
+    currentContainer = [];
+  }
+
+  void arrayElement() {
+    List list = currentContainer;
+    currentContainer.add(value);
+    value = null;
+  }
+
+  void endArray() {
+    popContainer();
+  }
+
+  /** Read out the final result of parsing a JSON string. */
+  get result {
+    assert(currentContainer == null);
+    return value;
+  }
+}
+
+class _ReviverJsonListener extends _BuildJsonListener {
+  final _Reviver reviver;
+  _ReviverJsonListener(reviver(key, value)) : this.reviver = reviver;
+
+  void arrayElement() {
+    List list = currentContainer;
+    value = reviver(list.length, value);
+    super.arrayElement();
+  }
+
+  void propertyValue() {
+    value = reviver(key, value);
+    super.propertyValue();
+  }
+
+  get result {
+    return reviver(null, value);
+  }
+}
+
+class _JsonParser {
+  // A simple non-recursive state-based parser for JSON.
+  //
+  // Literal values accepted in states ARRAY_EMPTY, ARRAY_COMMA, OBJECT_COLON
+  // and strings also in OBJECT_EMPTY, OBJECT_COMMA.
+  //               VALUE  STRING  :  ,  }  ]        Transitions to
+  // EMPTY            X      X                   -> END
+  // ARRAY_EMPTY      X      X             @     -> ARRAY_VALUE / pop
+  // ARRAY_VALUE                     @     @     -> ARRAY_COMMA / pop
+  // ARRAY_COMMA      X      X                   -> ARRAY_VALUE
+  // OBJECT_EMPTY            X          @        -> OBJECT_KEY / pop
+  // OBJECT_KEY                   @              -> OBJECT_COLON
+  // OBJECT_COLON     X      X                   -> OBJECT_VALUE
+  // OBJECT_VALUE                    @  @        -> OBJECT_COMMA / pop
+  // OBJECT_COMMA            X                   -> OBJECT_KEY
+  // END
+  // Starting a new array or object will push the current state. The "pop"
+  // above means restoring this state and then marking it as an ended value.
+  // X means generic handling, @ means special handling for just that
+  // state - that is, values are handled generically, only punctuation
+  // cares about the current state.
+  // Values for states are chosen so bits 0 and 1 tell whether
+  // a string/value is allowed, and setting bits 0 through 2 after a value
+  // gets to the next state (not empty, doesn't allow a value).
+
+  // State building-block constants.
+  static const int INSIDE_ARRAY = 1;
+  static const int INSIDE_OBJECT = 2;
+  static const int AFTER_COLON = 3;  // Always inside object.
+
+  static const int ALLOW_STRING_MASK = 8;  // Allowed if zero.
+  static const int ALLOW_VALUE_MASK = 4;  // Allowed if zero.
+  static const int ALLOW_VALUE = 0;
+  static const int STRING_ONLY = 4;
+  static const int NO_VALUES = 12;
+
+  // Objects and arrays are "empty" until their first property/element.
+  static const int EMPTY = 0;
+  static const int NON_EMPTY = 16;
+  static const int EMPTY_MASK = 16;  // Empty if zero.
+
+
+  static const int VALUE_READ_BITS = NO_VALUES | NON_EMPTY;
+
+  // Actual states.
+  static const int STATE_INITIAL      = EMPTY | ALLOW_VALUE;
+  static const int STATE_END          = NON_EMPTY | NO_VALUES;
+
+  static const int STATE_ARRAY_EMPTY  = INSIDE_ARRAY | EMPTY | ALLOW_VALUE;
+  static const int STATE_ARRAY_VALUE  = INSIDE_ARRAY | NON_EMPTY | NO_VALUES;
+  static const int STATE_ARRAY_COMMA  = INSIDE_ARRAY | NON_EMPTY | ALLOW_VALUE;
+
+  static const int STATE_OBJECT_EMPTY = INSIDE_OBJECT | EMPTY | STRING_ONLY;
+  static const int STATE_OBJECT_KEY   = INSIDE_OBJECT | NON_EMPTY | NO_VALUES;
+  static const int STATE_OBJECT_COLON = AFTER_COLON | NON_EMPTY | ALLOW_VALUE;
+  static const int STATE_OBJECT_VALUE = AFTER_COLON | NON_EMPTY | NO_VALUES;
+  static const int STATE_OBJECT_COMMA = INSIDE_OBJECT | NON_EMPTY | STRING_ONLY;
+
+  // Character code constants.
+  static const int BACKSPACE       = 0x08;
+  static const int TAB             = 0x09;
+  static const int NEWLINE         = 0x0a;
+  static const int CARRIAGE_RETURN = 0x0d;
+  static const int FORM_FEED       = 0x0c;
+  static const int SPACE           = 0x20;
+  static const int QUOTE           = 0x22;
+  static const int PLUS            = 0x2b;
+  static const int COMMA           = 0x2c;
+  static const int MINUS           = 0x2d;
+  static const int DECIMALPOINT    = 0x2e;
+  static const int SLASH           = 0x2f;
+  static const int CHAR_0          = 0x30;
+  static const int CHAR_9          = 0x39;
+  static const int COLON           = 0x3a;
+  static const int CHAR_E          = 0x45;
+  static const int LBRACKET        = 0x5b;
+  static const int BACKSLASH       = 0x5c;
+  static const int RBRACKET        = 0x5d;
+  static const int CHAR_a          = 0x61;
+  static const int CHAR_b          = 0x62;
+  static const int CHAR_e          = 0x65;
+  static const int CHAR_f          = 0x66;
+  static const int CHAR_l          = 0x6c;
+  static const int CHAR_n          = 0x6e;
+  static const int CHAR_r          = 0x72;
+  static const int CHAR_s          = 0x73;
+  static const int CHAR_t          = 0x74;
+  static const int CHAR_u          = 0x75;
+  static const int LBRACE          = 0x7b;
+  static const int RBRACE          = 0x7d;
+
+  final String source;
+  final _JsonListener listener;
+  _JsonParser(this.source, this.listener);
+
+  /** Parses [source], or throws if it fails. */
+  void parse() {
+    final List<int> states = <int>[];
+    int state = STATE_INITIAL;
+    int position = 0;
+    int length = source.length;
+    while (position < length) {
+      int char = source.codeUnitAt(position);
+      switch (char) {
+        case SPACE:
+        case CARRIAGE_RETURN:
+        case NEWLINE:
+        case TAB:
+          position++;
+          break;
+        case QUOTE:
+          if ((state & ALLOW_STRING_MASK) != 0) fail(position);
+          position = parseString(position + 1);
+          state |= VALUE_READ_BITS;
+          break;
+        case LBRACKET:
+          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+          listener.beginArray();
+          states.add(state);
+          state = STATE_ARRAY_EMPTY;
+          position++;
+          break;
+        case LBRACE:
+          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+          listener.beginObject();
+          states.add(state);
+          state = STATE_OBJECT_EMPTY;
+          position++;
+          break;
+        case CHAR_n:
+          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+          position = parseNull(position);
+          state |= VALUE_READ_BITS;
+          break;
+        case CHAR_f:
+          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+          position = parseFalse(position);
+          state |= VALUE_READ_BITS;
+          break;
+        case CHAR_t:
+          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+          position = parseTrue(position);
+          state |= VALUE_READ_BITS;
+          break;
+        case COLON:
+          if (state != STATE_OBJECT_KEY) fail(position);
+          listener.propertyName();
+          state = STATE_OBJECT_COLON;
+          position++;
+          break;
+        case COMMA:
+          if (state == STATE_OBJECT_VALUE) {
+            listener.propertyValue();
+            state = STATE_OBJECT_COMMA;
+            position++;
+          } else if (state == STATE_ARRAY_VALUE) {
+            listener.arrayElement();
+            state = STATE_ARRAY_COMMA;
+            position++;
+          } else {
+            fail(position);
+          }
+          break;
+        case RBRACKET:
+          if (state == STATE_ARRAY_EMPTY) {
+            listener.endArray();
+          } else if (state == STATE_ARRAY_VALUE) {
+            listener.arrayElement();
+            listener.endArray();
+          } else {
+            fail(position);
+          }
+          state = states.removeLast() | VALUE_READ_BITS;
+          position++;
+          break;
+        case RBRACE:
+          if (state == STATE_OBJECT_EMPTY) {
+            listener.endObject();
+          } else if (state == STATE_OBJECT_VALUE) {
+            listener.propertyValue();
+            listener.endObject();
+          } else {
+            fail(position);
+          }
+          state = states.removeLast() | VALUE_READ_BITS;
+          position++;
+          break;
+        default:
+          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
+          position = parseNumber(char, position);
+          state |= VALUE_READ_BITS;
+          break;
+      }
+    }
+    if (state != STATE_END) fail(position);
+  }
+
+  /**
+   * Parses a "true" literal starting at [position].
+   *
+   * [:source[position]:] must be "t".
+   */
+  int parseTrue(int position) {
+    assert(source.codeUnitAt(position) == CHAR_t);
+    if (source.length < position + 4) fail(position, "Unexpected identifier");
+    if (source.codeUnitAt(position + 1) != CHAR_r ||
+        source.codeUnitAt(position + 2) != CHAR_u ||
+        source.codeUnitAt(position + 3) != CHAR_e) {
+      fail(position);
+    }
+    listener.handleBool(true);
+    return position + 4;
+  }
+
+  /**
+   * Parses a "false" literal starting at [position].
+   *
+   * [:source[position]:] must be "f".
+   */
+  int parseFalse(int position) {
+    assert(source.codeUnitAt(position) == CHAR_f);
+    if (source.length < position + 5) fail(position, "Unexpected identifier");
+    if (source.codeUnitAt(position + 1) != CHAR_a ||
+        source.codeUnitAt(position + 2) != CHAR_l ||
+        source.codeUnitAt(position + 3) != CHAR_s ||
+        source.codeUnitAt(position + 4) != CHAR_e) {
+      fail(position);
+    }
+    listener.handleBool(false);
+    return position + 5;
+  }
+
+  /** Parses a "null" literal starting at [position].
+   *
+   * [:source[position]:] must be "n".
+   */
+  int parseNull(int position) {
+    assert(source.codeUnitAt(position) == CHAR_n);
+    if (source.length < position + 4) fail(position, "Unexpected identifier");
+    if (source.codeUnitAt(position + 1) != CHAR_u ||
+        source.codeUnitAt(position + 2) != CHAR_l ||
+        source.codeUnitAt(position + 3) != CHAR_l) {
+      fail(position);
+    }
+    listener.handleNull();
+    return position + 4;
+  }
+
+  int parseString(int position) {
+    // Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"'
+    // Initial position is right after first '"'.
+    int start = position;
+    int char;
+    do {
+      if (position == source.length) {
+        fail(start - 1, "Unterminated string");
+      }
+      char = source.codeUnitAt(position);
+      if (char == QUOTE) {
+        listener.handleString(source.substring(start, position));
+        return position + 1;
+      }
+      if (char < SPACE) {
+        fail(position, "Control character in string");
+      }
+      position++;
+    } while (char != BACKSLASH);
+    // Backslash escape detected. Collect character codes for rest of string.
+    int firstEscape = position - 1;
+    List<int> chars = <int>[];
+    while (true) {
+      if (position == source.length) {
+        fail(start - 1, "Unterminated string");
+      }
+      char = source.codeUnitAt(position);
+      switch (char) {
+        case CHAR_b: char = BACKSPACE; break;
+        case CHAR_f: char = FORM_FEED; break;
+        case CHAR_n: char = NEWLINE; break;
+        case CHAR_r: char = CARRIAGE_RETURN; break;
+        case CHAR_t: char = TAB; break;
+        case SLASH:
+        case BACKSLASH:
+        case QUOTE:
+          break;
+        case CHAR_u:
+          int hexStart = position - 1;
+          int value = 0;
+          for (int i = 0; i < 4; i++) {
+            position++;
+            if (position == source.length) {
+              fail(start - 1, "Unterminated string");
+            }
+            char = source.codeUnitAt(position);
+            char -= 0x30;
+            if (char < 0) fail(hexStart, "Invalid unicode escape");
+            if (char < 10) {
+              value = value * 16 + char;
+            } else {
+              char = (char | 0x20) - 0x31;
+              if (char < 0 || char > 5) {
+                fail(hexStart, "Invalid unicode escape");
+              }
+              value = value * 16 + char + 10;
+            }
+          }
+          char = value;
+          break;
+        default:
+          if (char < SPACE) fail(position, "Control character in string");
+          fail(position, "Unrecognized string escape");
+      }
+      do {
+        chars.add(char);
+        position++;
+        if (position == source.length) fail(start - 1, "Unterminated string");
+        char = source.codeUnitAt(position);
+        if (char == QUOTE) {
+          String result = new String.fromCharCodes(chars);
+          if (start < firstEscape) {
+            result = "${source.substring(start, firstEscape)}$result";
+          }
+          listener.handleString(result);
+          return position + 1;
+        }
+        if (char < SPACE) {
+          fail(position, "Control character in string");
+        }
+      } while (char != BACKSLASH);
+      position++;
+    }
+  }
+
+  int _handleLiteral(start, position, isDouble) {
+    String literal = source.substring(start, position);
+    // This correctly creates -0 for doubles.
+    num value = (isDouble ? double.parse(literal) : int.parse(literal));
+    listener.handleNumber(value);
+    return position;
+  }
+
+  int parseNumber(int char, int position) {
+    // Format:
+    //  '-'?('0'|[1-9][0-9]*)('.'[0-9]+)?([eE][+-]?[0-9]+)?
+    int start = position;
+    int length = source.length;
+    bool isDouble = false;
+    if (char == MINUS) {
+      position++;
+      if (position == length) fail(position, "Missing expected digit");
+      char = source.codeUnitAt(position);
+    }
+    if (char < CHAR_0 || char > CHAR_9) {
+      fail(position, "Missing expected digit");
+    }
+    if (char == CHAR_0) {
+      position++;
+      if (position == length) return _handleLiteral(start, position, false);
+      char = source.codeUnitAt(position);
+      if (CHAR_0 <= char && char <= CHAR_9) {
+        fail(position);
+      }
+    } else {
+      do {
+        position++;
+        if (position == length) return _handleLiteral(start, position, false);
+        char = source.codeUnitAt(position);
+      } while (CHAR_0 <= char && char <= CHAR_9);
+    }
+    if (char == DECIMALPOINT) {
+      isDouble = true;
+      position++;
+      if (position == length) fail(position, "Missing expected digit");
+      char = source.codeUnitAt(position);
+      if (char < CHAR_0 || char > CHAR_9) fail(position);
+      do {
+        position++;
+        if (position == length) return _handleLiteral(start, position, true);
+        char = source.codeUnitAt(position);
+      } while (CHAR_0 <= char && char <= CHAR_9);
+    }
+    if (char == CHAR_e || char == CHAR_E) {
+      isDouble = true;
+      position++;
+      if (position == length) fail(position, "Missing expected digit");
+      char = source.codeUnitAt(position);
+      if (char == PLUS || char == MINUS) {
+        position++;
+        if (position == length) fail(position, "Missing expected digit");
+        char = source.codeUnitAt(position);
+      }
+      if (char < CHAR_0 || char > CHAR_9) {
+        fail(position, "Missing expected digit");
+      }
+      do {
+        position++;
+        if (position == length) return _handleLiteral(start, position, true);
+        char = source.codeUnitAt(position);
+      } while (CHAR_0 <= char && char <= CHAR_9);
+    }
+    return _handleLiteral(start, position, isDouble);
+  }
+
+  void fail(int position, [String message]) {
+    if (message == null) message = "Unexpected character";
+    listener.fail(source, position, message);
+    // If the listener didn't throw, do it here.
+    String slice;
+    int sliceEnd = position + 20;
+    if (sliceEnd > source.length) {
+      slice = "'${source.substring(position)}'";
+    } else {
+      slice = "'${source.substring(position, sliceEnd)}...'";
+    }
+    throw new FormatException("Unexpected character at $position: $slice");
+  }
+}
diff --git a/runtime/lib/json_sources.gypi b/runtime/lib/convert_sources.gypi
similarity index 90%
rename from runtime/lib/json_sources.gypi
rename to runtime/lib/convert_sources.gypi
index 1622f7b..0f3b46b 100644
--- a/runtime/lib/json_sources.gypi
+++ b/runtime/lib/convert_sources.gypi
@@ -4,6 +4,6 @@
 
 {
   'sources': [
-    'json_patch.dart',
+    'convert_patch.dart',
   ],
 }
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index f69e963..b37c526 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -120,14 +120,14 @@
     OS::Print("Double_greaterThan %s > %s\n",
         left.ToCString(), right.ToCString());
   }
-  return Bool::Get(result);
+  return Bool::Get(result).raw();
 }
 
 
 DEFINE_NATIVE_ENTRY(Double_greaterThanFromInteger, 2) {
   const Double& right = Double::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
-  return Bool::Get(left.AsDoubleValue() > right.value());
+  return Bool::Get(left.AsDoubleValue() > right.value()).raw();
 }
 
 
@@ -139,14 +139,14 @@
     OS::Print("Double_equal %s == %s\n",
         left.ToCString(), right.ToCString());
   }
-  return Bool::Get(result);
+  return Bool::Get(result).raw();
 }
 
 
 DEFINE_NATIVE_ENTRY(Double_equalToInteger, 2) {
   const Double& left = Double::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1));
-  return Bool::Get(left.value() == right.AsDoubleValue());
+  return Bool::Get(left.value() == right.AsDoubleValue()).raw();
 }
 
 
@@ -265,20 +265,20 @@
 
 DEFINE_NATIVE_ENTRY(Double_getIsInfinite, 1) {
   const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
-  return Bool::Get(isinf(arg.value()));
+  return Bool::Get(isinf(arg.value())).raw();
 }
 
 
 DEFINE_NATIVE_ENTRY(Double_getIsNaN, 1) {
   const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
-  return Bool::Get(isnan(arg.value()));
+  return Bool::Get(isnan(arg.value())).raw();
 }
 
 
 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) {
   const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
   // Include negative zero, infinity.
-  return Bool::Get(signbit(arg.value()) && !isnan(arg.value()));
+  return Bool::Get(signbit(arg.value()) && !isnan(arg.value())).raw();
 }
 
 // Add here only functions using/referring to old-style casts.
diff --git a/runtime/lib/identical.cc b/runtime/lib/identical.cc
index 4dc8bac..7508f03 100644
--- a/runtime/lib/identical.cc
+++ b/runtime/lib/identical.cc
@@ -13,7 +13,7 @@
   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));
+    return Bool::Get(a.Equals(b)).raw();
   }
   if (a.IsDouble() && b.IsDouble()) {
     if (a.Equals(b)) return Bool::True().raw();
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index fa87faf..4962ac9 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -165,7 +165,7 @@
     OS::Print("Integer_greaterThanFromInteger %s > %s\n",
         left.ToCString(), right.ToCString());
   }
-  return Bool::Get(left.CompareWith(right) == 1);
+  return Bool::Get(left.CompareWith(right) == 1).raw();
 }
 
 
@@ -178,7 +178,7 @@
     OS::Print("Integer_equalToInteger %s == %s\n",
         left.ToCString(), right.ToCString());
   }
-  return Bool::Get(left.CompareWith(right) == 0);
+  return Bool::Get(left.CompareWith(right) == 0).raw();
 }
 
 
diff --git a/runtime/lib/invocation_mirror_patch.dart b/runtime/lib/invocation_mirror_patch.dart
index cce75f4..9669626 100644
--- a/runtime/lib/invocation_mirror_patch.dart
+++ b/runtime/lib/invocation_mirror_patch.dart
@@ -60,6 +60,10 @@
   List get positionalArguments {
     if (_positionalArguments == null) {
       int numPositionalArguments = _argumentsDescriptor[1];
+      // Don't count receiver.
+      if (numPositionalArguments == 1) {
+        return _positionalArguments = const [];
+      }
       // Exclude receiver.
       _positionalArguments = _arguments.sublist(1, numPositionalArguments);
     }
@@ -68,10 +72,13 @@
 
   Map<Symbol, dynamic> get namedArguments {
     if (_namedArguments == null) {
-      _namedArguments = new Map<Symbol, dynamic>();
       int numArguments = _argumentsDescriptor[0] - 1;  // Exclude receiver.
       int numPositionalArguments = _argumentsDescriptor[1] - 1;
       int numNamedArguments = numArguments - numPositionalArguments;
+      if (numNamedArguments == 0) {
+        return _namedArguments = const <Symbol, dynamic>{};
+      }
+      _namedArguments = new Map<Symbol, dynamic>();
       for (int i = 0; i < numNamedArguments; i++) {
         String arg_name = _argumentsDescriptor[2 + 2*i];
         var arg_value = _arguments[_argumentsDescriptor[3 + 2*i]];
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index ed78b7b..e897ab5 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -8,6 +8,7 @@
 #include "vm/dart_entry.h"
 #include "vm/exceptions.h"
 #include "vm/object_store.h"
+#include "vm/parser.h"
 #include "vm/port.h"
 #include "vm/symbols.h"
 
@@ -28,6 +29,74 @@
 }
 
 
+// Note a "raw type" is not the same as a RawType.
+static RawAbstractType* RawTypeOfClass(const Class& cls) {
+  Type& type = Type::Handle(Type::New(cls,
+                                      Object::null_abstract_type_arguments(),
+                                      Scanner::kDummyTokenIndex));
+  return ClassFinalizer::FinalizeType(cls, type, ClassFinalizer::kCanonicalize);
+}
+
+
+static void ThrowMirroredCompilationError(const String& message) {
+  Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, message);
+
+  Exceptions::ThrowByType(Exceptions::kMirroredCompilationError, args);
+  UNREACHABLE();
+}
+
+
+static void ThrowInvokeError(const Error& error) {
+  if (error.IsLanguageError()) {
+    // A compilation error that was delayed by lazy compilation.
+    const LanguageError& compilation_error = LanguageError::Cast(error);
+    String& message = String::Handle(compilation_error.message());
+    ThrowMirroredCompilationError(message);
+    UNREACHABLE();
+  }
+  Exceptions::PropagateError(error);
+  UNREACHABLE();
+}
+
+
+// Conventions:
+// * For throwing a NSM in a class klass we use its runtime type as receiver,
+//   i.e., RawTypeOfClass(klass).
+// * For throwing a NSM in a library, we just pass the null instance as
+//   receiver.
+static void ThrowNoSuchMethod(const Instance& receiver,
+                              const String& function_name,
+                              const Function& function,
+                              const InvocationMirror::Call call,
+                              const InvocationMirror::Type type) {
+  const Smi& invocation_type = Smi::Handle(Smi::New(
+      InvocationMirror::EncodeType(call, type)));
+
+  const Array& args = Array::Handle(Array::New(6));
+  args.SetAt(0, receiver);
+  args.SetAt(1, function_name);
+  args.SetAt(2, invocation_type);
+  // Parameter 3 (actual arguments): We omit this parameter to get the same
+  // error message as one would get by invoking the function non-reflectively.
+  // Parameter 4 (named arguments): We omit this parameters since we cannot
+  // invoke functions with named parameters reflectively (using mirrors).
+  if (!function.IsNull()) {
+    const int total_num_parameters = function.NumParameters();
+    const Array& array = Array::Handle(Array::New(total_num_parameters));
+    String& param_name = String::Handle();
+    for (int i = 0; i < total_num_parameters; i++) {
+      param_name = function.ParameterNameAt(i);
+      array.SetAt(i, param_name);
+    }
+    args.SetAt(5, array);
+  }
+
+  Exceptions::ThrowByType(Exceptions::kNoSuchMethod, args);
+  UNREACHABLE();
+}
+
+
 DEFINE_NATIVE_ENTRY(Mirrors_isLocalPort, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, port, arguments->NativeArgAt(0));
 
@@ -41,7 +110,7 @@
   Integer& id = Integer::Handle();
   id ^= id_obj.raw();
   Dart_Port port_id = static_cast<Dart_Port>(id.AsInt64Value());
-  return Bool::Get(PortMap::IsLocalPort(port_id));
+  return Bool::Get(PortMap::IsLocalPort(port_id)).raw();
 }
 
 
@@ -56,21 +125,51 @@
   const intptr_t index_of_first_named_param =
       non_implicit_param_count - func.NumOptionalNamedParameters();
   const Array& results = Array::Handle(Array::New(non_implicit_param_count));
-  const Array& args = Array::Handle(Array::New(6));
-  args.SetAt(0, MirrorReference::Handle(MirrorReference::New(func)));
-  args.SetAt(2, owner_mirror);
+  const Array& args = Array::Handle(Array::New(8));
+
+  // Return for synthetic functions and getters.
+  if (func.IsGetterFunction() ||
+      func.IsImplicitConstructor() ||
+      func.IsImplicitGetterFunction() ||
+      func.IsImplicitSetterFunction()) {
+    return results.raw();
+  }
+
   Smi& pos = Smi::Handle();
   String& name = String::Handle();
   Instance& param = Instance::Handle();
+  Bool& is_final = Bool::Handle();
+  Object& default_value = Object::Handle();
+
+  // Reparse the function for the following information:
+  // * The default value of a parameter.
+  // * Whether a parameters has been deflared as final.
+  const Object& result = Object::Handle(Parser::ParseFunctionParameters(func));
+  if (result.IsError()) {
+    ThrowInvokeError(Error::Cast(result));
+    UNREACHABLE();
+  }
+
+  args.SetAt(0, MirrorReference::Handle(MirrorReference::New(func)));
+  args.SetAt(2, owner_mirror);
+
+  const Array& param_descriptor = Array::Cast(result);
+  ASSERT(param_descriptor.Length() == (2 * non_implicit_param_count));
   for (intptr_t i = 0; i < non_implicit_param_count; i++) {
     pos ^= Smi::New(i);
     name ^= func.ParameterNameAt(implicit_param_count + i);
+    is_final ^= param_descriptor.At(i * 2);
+    default_value = param_descriptor.At(i * 2 + 1);
+    ASSERT(default_value.IsNull() || default_value.IsInstance());
+
+    // Arguments 0 (referent) and 2 (owner) are the same for all parameters. See
+    // above.
     args.SetAt(1, name);
     args.SetAt(3, pos);
-    args.SetAt(4, (i >= index_of_first_optional_param) ?
-        Bool::True() : Bool::False());
-    args.SetAt(5, (i >= index_of_first_named_param) ?
-        Bool::True() : Bool::False());
+    args.SetAt(4, Bool::Get(i >= index_of_first_optional_param));
+    args.SetAt(5, Bool::Get(i >= index_of_first_named_param));
+    args.SetAt(6, is_final);
+    args.SetAt(7, default_value);
     param ^= CreateMirror(Symbols::_LocalParameterMirrorImpl(), args);
     results.SetAt(i, param);
   }
@@ -135,11 +234,11 @@
   args.SetAt(0, MirrorReference::Handle(MirrorReference::New(func)));
   args.SetAt(1, String::Handle(func.UserVisibleName()));
   args.SetAt(2, owner_mirror);
-  args.SetAt(3, func.is_static() ? Bool::True() : Bool::False());
-  args.SetAt(4, func.is_abstract() ? Bool::True() : Bool::False());
-  args.SetAt(5, func.IsGetterFunction() ? Bool::True() : Bool::False());
-  args.SetAt(6, func.IsSetterFunction() ? Bool::True() : Bool::False());
-  args.SetAt(7, func.IsConstructor() ? Bool::True() : Bool::False());
+  args.SetAt(3, Bool::Get(func.is_static()));
+  args.SetAt(4, Bool::Get(func.is_abstract()));
+  args.SetAt(5, Bool::Get(func.IsGetterFunction()));
+  args.SetAt(6, Bool::Get(func.IsSetterFunction()));
+  args.SetAt(7, Bool::Get(func.IsConstructor()));
   // TODO(mlippautz): Implement different constructor kinds.
   args.SetAt(8, Bool::False());
   args.SetAt(9, Bool::False());
@@ -161,8 +260,8 @@
   args.SetAt(1, name);
   args.SetAt(2, owner_mirror);
   args.SetAt(3, Instance::Handle());  // Null for type.
-  args.SetAt(4, field.is_static() ? Bool::True() : Bool::False());
-  args.SetAt(5, field.is_final()  ? Bool::True() : Bool::False());
+  args.SetAt(4, Bool::Get(field.is_static()));
+  args.SetAt(5, Bool::Get(field.is_final()));
 
   return CreateMirror(Symbols::_LocalVariableMirrorImpl(), args);
 }
@@ -199,8 +298,7 @@
     }
   }
 
-  const Bool& is_generic =
-      (cls.NumTypeParameters() == 0) ? Bool::False() : Bool::True();
+  const Bool& is_generic = Bool::Get(cls.NumTypeParameters() != 0);
 
   const Array& args = Array::Handle(Array::New(4));
   args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
@@ -211,15 +309,6 @@
 }
 
 
-// Note a "raw type" is not the same as a RawType.
-static RawAbstractType* RawTypeOfClass(const Class& cls) {
-  Type& type = Type::Handle(Type::New(cls,
-                                      Object::null_abstract_type_arguments(),
-                                      Scanner::kDummyTokenIndex));
-  return ClassFinalizer::FinalizeType(cls, type, ClassFinalizer::kCanonicalize);
-}
-
-
 static RawInstance* CreateLibraryMirror(const Library& lib) {
   const Array& args = Array::Handle(Array::New(3));
   args.SetAt(0, MirrorReference::Handle(MirrorReference::New(lib)));
@@ -332,32 +421,10 @@
 }
 
 
-static void ThrowMirroredCompilationError(const String& message) {
-  Array& args = Array::Handle(Array::New(1));
-  args.SetAt(0, message);
-
-  Exceptions::ThrowByType(Exceptions::kMirroredCompilationError, args);
-  UNREACHABLE();
-}
-
-
-static void ThrowInvokeError(const Error& error) {
-  if (error.IsLanguageError()) {
-    // A compilation error that was delayed by lazy compilation.
-    const LanguageError& compilation_error = LanguageError::Cast(error);
-    String& message = String::Handle(compilation_error.message());
-    ThrowMirroredCompilationError(message);
-    UNREACHABLE();
-  }
-  Exceptions::PropagateError(error);
-  UNREACHABLE();
-}
-
-
 DEFINE_NATIVE_ENTRY(MirrorReference_equals, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, a, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, b, arguments->NativeArgAt(1));
-  return Bool::Get(a.referent() == b.referent());
+  return Bool::Get(a.referent() == b.referent()).raw();
 }
 
 
@@ -849,64 +916,6 @@
 }
 
 
-static void ThrowNoSuchMethod(const Instance& receiver,
-                              const String& function_name,
-                              const Function& function,
-                              const InvocationMirror::Call call,
-                              const InvocationMirror::Type type) {
-  const Smi& invocation_type = Smi::Handle(Smi::New(
-      InvocationMirror::EncodeType(call, type)));
-
-  const Array& args = Array::Handle(Array::New(6));
-  args.SetAt(0, receiver);
-  args.SetAt(1, function_name);
-  args.SetAt(2, invocation_type);
-  if (!function.IsNull()) {
-    const int total_num_parameters = function.NumParameters();
-    const Array& array = Array::Handle(Array::New(total_num_parameters));
-    String& param_name = String::Handle();
-    for (int i = 0; i < total_num_parameters; i++) {
-      param_name = function.ParameterNameAt(i);
-      array.SetAt(i, param_name);
-    }
-    args.SetAt(5, array);
-  }
-
-  Exceptions::ThrowByType(Exceptions::kNoSuchMethod, args);
-  UNREACHABLE();
-}
-
-
-static void ThrowNoSuchMethod(const Class& klass,
-                              const String& function_name,
-                              const Function& function,
-                              const InvocationMirror::Call call,
-                              const InvocationMirror::Type type) {
-  AbstractType& runtime_type = AbstractType::Handle(RawTypeOfClass(klass));
-
-  ThrowNoSuchMethod(runtime_type,
-                    function_name,
-                    function,
-                    call,
-                    type);
-  UNREACHABLE();
-}
-
-
-static void ThrowNoSuchMethod(const Library& library,
-                              const String& function_name,
-                              const Function& function,
-                              const InvocationMirror::Call call,
-                              const InvocationMirror::Type type) {
-  ThrowNoSuchMethod(Instance::null_instance(),
-                    function_name,
-                    function,
-                    call,
-                    type);
-  UNREACHABLE();
-}
-
-
 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 4) {
   // Argument 0 is the mirror, which is unused by the native. It exists
   // because this native is an instance method in order to be polymorphic
@@ -928,7 +937,7 @@
                                        /* named_args */ 0,
                                        NULL) ||
       !function.is_visible()) {
-    ThrowNoSuchMethod(klass,
+    ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)),
                       function_name,
                       function,
                       InvocationMirror::kStatic,
@@ -963,7 +972,7 @@
         klass.LookupStaticFunctionAllowPrivate(internal_getter_name));
 
     if (getter.IsNull() || !getter.is_visible()) {
-      ThrowNoSuchMethod(klass,
+      ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)),
                         getter_name,
                         getter,
                         InvocationMirror::kStatic,
@@ -1002,7 +1011,7 @@
       klass.LookupStaticFunctionAllowPrivate(internal_setter_name));
 
     if (setter.IsNull() || !setter.is_visible()) {
-      ThrowNoSuchMethod(klass,
+      ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)),
                         setter_name,
                         setter,
                         InvocationMirror::kStatic,
@@ -1073,7 +1082,7 @@
     // Pretend we didn't find the constructor at all when the arity is wrong
     // so as to produce the same NoSuchMethodError as the non-reflective case.
     constructor = Function::null();
-    ThrowNoSuchMethod(klass,
+    ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)),
                       internal_constructor_name,
                       constructor,
                       InvocationMirror::kConstructor,
@@ -1122,7 +1131,7 @@
                                       0,
                                       NULL) ||
      !function.is_visible()) {
-    ThrowNoSuchMethod(library,
+    ThrowNoSuchMethod(Instance::null_instance(),
                       function_name,
                       function,
                       InvocationMirror::kTopLevel,
@@ -1183,7 +1192,7 @@
     return field.value();
   }
   if (ambiguity_error_msg.IsNull()) {
-    ThrowNoSuchMethod(library,
+    ThrowNoSuchMethod(Instance::null_instance(),
                       getter_name,
                       getter,
                       InvocationMirror::kTopLevel,
@@ -1220,7 +1229,7 @@
                                            &ambiguity_error_msg));
     if (setter.IsNull() || !setter.is_visible()) {
       if (ambiguity_error_msg.IsNull()) {
-        ThrowNoSuchMethod(library,
+        ThrowNoSuchMethod(Instance::null_instance(),
                           setter_name,
                           setter,
                           InvocationMirror::kTopLevel,
@@ -1292,6 +1301,35 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(MethodMirror_source, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
+  const Function& func = Function::Handle(ref.GetFunctionReferent());
+  const Script& script = Script::Handle(func.script());
+  const TokenStream& stream = TokenStream::Handle(script.tokens());
+  const TokenStream::Iterator tkit(stream, func.end_token_pos());
+  intptr_t from_line;
+  intptr_t from_col;
+  intptr_t to_line;
+  intptr_t to_col;
+  script.GetTokenLocation(func.token_pos(), &from_line, &from_col);
+  script.GetTokenLocation(func.end_token_pos(), &to_line, &to_col);
+  intptr_t last_tok_len = String::Handle(tkit.CurrentLiteral()).Length();
+  // Handle special cases for end tokens of closures (where we exclude the last
+  // token):
+  // (1) "foo(() => null, bar);": End token is `,', but we don't print it.
+  // (2) "foo(() => null);": End token is ')`, but we don't print it.
+  // (3) "var foo = () => null;": End token is `;', but in this case the token
+  // semicolon belongs to the assignment so we skip it.
+  if ((tkit.CurrentTokenKind() == Token::kCOMMA) ||                   // Case 1.
+      (tkit.CurrentTokenKind() == Token::kRPAREN) ||                  // Case 2.
+      (tkit.CurrentTokenKind() == Token::kSEMICOLON &&
+       String::Handle(func.name()).Equals("<anonymous closure>"))) {  // Case 3.
+    last_tok_len = 0;
+  }
+  return script.GetSnippet(from_line, from_col, to_line, to_col + last_tok_len);
+}
+
+
 DEFINE_NATIVE_ENTRY(TypedefMirror_referent, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
   const Class& cls = Class::Handle(ref.GetClassReferent());
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index ea63f90..4d211ec 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -1016,6 +1016,15 @@
     return _constructorName;
   }
 
+  String _source = null;
+  String get source {
+    if (_source == null) {
+      _source = _MethodMirror_source(_reflectee);
+      assert(_source != null);
+    }
+    return _source;
+  }
+
   String toString() => "MethodMirror on '${_n(simpleName)}'";
 
   static dynamic _MethodMirror_owner(reflectee)
@@ -1026,6 +1035,9 @@
 
   List<ParameterMirror> _MethodMirror_parameters(reflectee)
       native "MethodMirror_parameters";
+
+  static String _MethodMirror_source(reflectee)
+      native "MethodMirror_source";
 }
 
 class _LocalVariableMirrorImpl extends _LocalDeclarationMirrorImpl
@@ -1077,27 +1089,33 @@
                             DeclarationMirror owner,
                             this._position,
                             this.isOptional,
-                            this.isNamed)
+                            this.isNamed,
+                            bool isFinal,
+                            this._defaultValueReflectee)
       : super(reflectee,
               simpleName,
               owner,
               null,  // We override the type.
               false, // isStatic does not apply.
-              false);  // TODO(12196): Not yet implemented.
+              isFinal);
 
   final int _position;
   final bool isOptional;
   final bool isNamed;
 
-  String get defaultValue {
-    throw new UnimplementedError(
-        'ParameterMirror.defaultValue is not implemented');
+  Object _defaultValueReflectee;
+  InstanceMirror _defaultValue;
+  InstanceMirror get defaultValue {
+    if (!isOptional) {
+      return null;
+    }
+    if (_defaultValue == null) {
+      _defaultValue = reflect(_defaultValueReflectee);
+    }
+    return _defaultValue;
   }
 
-  bool get hasDefaultValue {
-    throw new UnimplementedError(
-        'ParameterMirror.hasDefaultValue is not implemented');
-  }
+  bool get hasDefaultValue => _defaultValueReflectee != null;
 
   // TODO(11418): Implement.
   List<InstanceMirror> get metadata {
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 086198a..de01c97 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -139,7 +139,7 @@
         Symbols::Empty(), malformed_error_message);
     UNREACHABLE();
   }
-  return Bool::Get(negate.value() ? !is_instance_of : is_instance_of);
+  return Bool::Get(negate.value() ? !is_instance_of : is_instance_of).raw();
 }
 
 
diff --git a/runtime/lib/regexp.cc b/runtime/lib/regexp.cc
index 3416698..9ac59da 100644
--- a/runtime/lib/regexp.cc
+++ b/runtime/lib/regexp.cc
@@ -36,14 +36,14 @@
 DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_getIsMultiLine, 1) {
   const JSRegExp& regexp = JSRegExp::CheckedHandle(arguments->NativeArgAt(0));
   ASSERT(!regexp.IsNull());
-  return Bool::Get(regexp.is_multi_line());
+  return Bool::Get(regexp.is_multi_line()).raw();
 }
 
 
 DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_getIsCaseSensitive, 1) {
   const JSRegExp& regexp = JSRegExp::CheckedHandle(arguments->NativeArgAt(0));
   ASSERT(!regexp.IsNull());
-  return Bool::Get(!regexp.is_ignore_case());
+  return Bool::Get(!regexp.is_ignore_case()).raw();
 }
 
 
diff --git a/runtime/lib/simd128.cc b/runtime/lib/simd128.cc
index 1d4d551..d128e83 100644
--- a/runtime/lib/simd128.cc
+++ b/runtime/lib/simd128.cc
@@ -591,28 +591,28 @@
 DEFINE_NATIVE_ENTRY(Uint32x4_getFlagX, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
   uint32_t value = self.x();
-  return value != 0 ? Bool::True().raw() : Bool::False().raw();
+  return Bool::Get(value != 0).raw();
 }
 
 
 DEFINE_NATIVE_ENTRY(Uint32x4_getFlagY, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
   uint32_t value = self.y();
-  return value != 0 ? Bool::True().raw() : Bool::False().raw();
+  return Bool::Get(value != 0).raw();
 }
 
 
 DEFINE_NATIVE_ENTRY(Uint32x4_getFlagZ, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
   uint32_t value = self.z();
-  return value != 0 ? Bool::True().raw() : Bool::False().raw();
+  return Bool::Get(value != 0).raw();
 }
 
 
 DEFINE_NATIVE_ENTRY(Uint32x4_getFlagW, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
   uint32_t value = self.w();
-  return value != 0 ? Bool::True().raw() : Bool::False().raw();
+  return Bool::Get(value != 0).raw();
 }
 
 
diff --git a/runtime/platform/json.cc b/runtime/platform/json.cc
index 0823d0a..6f731f8 100644
--- a/runtime/platform/json.cc
+++ b/runtime/platform/json.cc
@@ -398,7 +398,7 @@
 }
 
 
-void JSONReader::GetValueChars(char* buf, intptr_t buflen) const {
+void JSONReader::GetRawValueChars(char* buf, intptr_t buflen) const {
   if (Type() == kNone) {
     return;
   }
@@ -415,6 +415,72 @@
 }
 
 
+void JSONReader::GetDecodedValueChars(char* buf, intptr_t buflen) const {
+  if (Type() == kNone) {
+    return;
+  }
+  const intptr_t last_idx = buflen - 1;
+  const intptr_t value_len = ValueLen();
+  const char* val = ValueChars();
+  intptr_t buf_idx = 0;
+  intptr_t val_idx = 0;
+  while ((buf_idx < last_idx) && (val_idx < value_len)) {
+    char ch = val[val_idx];
+    val_idx++;
+    buf[buf_idx] = ch;
+    if ((ch == '\\') && (val_idx < value_len)) {
+      switch (val[val_idx]) {
+        case '"':
+        case '\\':
+        case '/':
+          buf[buf_idx] = val[val_idx];
+          val_idx++;
+          break;
+        case 'b':
+          buf[buf_idx] = '\b';
+          val_idx++;
+          break;
+        case 'f':
+          buf[buf_idx] = '\f';
+          val_idx++;
+          break;
+        case 'n':
+          buf[buf_idx] = '\n';
+          val_idx++;
+          break;
+        case 'r':
+          buf[buf_idx] = '\r';
+          val_idx++;
+          break;
+        case 't':
+          buf[buf_idx] = '\t';
+          val_idx++;
+          break;
+        case 'u':
+          // \u00XX
+          // If the value is malformed or > 255, ignore and copy the
+          // encoded characters.
+          if ((val_idx < value_len - 4) &&
+              (val[val_idx + 1] == '0') && (val[val_idx + 2] == '0') &&
+              Utils::IsHexDigit(val[val_idx + 3]) &&
+              Utils::IsHexDigit(val[val_idx + 4])) {
+            buf[buf_idx] = 16 * Utils::HexDigitToInt(val[val_idx + 3]) +
+                Utils::HexDigitToInt(val[val_idx + 4]);
+            val_idx += 5;
+          }
+          break;
+        default:
+          // Nothing. Copy the character after the backslash
+          // in the next loop iteration.
+          break;
+      }
+    }
+    buf_idx++;
+  }
+  buf[buf_idx] = '\0';
+}
+
+
 TextBuffer::TextBuffer(intptr_t buf_size) {
   ASSERT(buf_size > 0);
   buf_ = reinterpret_cast<char*>(malloc(buf_size));
diff --git a/runtime/platform/json.h b/runtime/platform/json.h
index 5ab5909..a793cb8 100644
--- a/runtime/platform/json.h
+++ b/runtime/platform/json.h
@@ -88,7 +88,8 @@
   int ValueLen() const {
     return (Type() != kNone) ? scanner_.TokenLen() : 0;
   }
-  void GetValueChars(char* buf, intptr_t buflen) const;
+  void GetRawValueChars(char* buf, intptr_t buflen) const;
+  void GetDecodedValueChars(char* buf, intptr_t buflen) const;
   bool IsStringLiteral(const char* literal) const {
     return scanner_.IsStringLiteral(literal);
   }
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index dbcefa0..6add296 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -44,12 +44,6 @@
 # minifying they can be renamed, which is issue 7953.
 dart/inline_stack_frame_test: Fail
 
-[ $runtime == ff || $runtime == ie9 ]
-dart/inline_stack_frame_test: Skip
-
-[ $runtime == safari ]
-dart/inline_stack_frame_test: Fail # Issue: 7414
-
 [ $compiler == dart2dart ]
 # Skip until we stabilize language tests.
 *: Skip
@@ -67,9 +61,9 @@
 
 # TODO(ajohnsen): Fix this as part of library changes.
 [ $compiler == none ]
-cc/CustomIsolates: Skip # Bug 6890
-cc/NewNativePort: Skip # Bug 6890
-cc/RunLoop_ExceptionParent: Skip # Bug 6890
+cc/CustomIsolates: Fail, Crash # Bug 6890
+cc/NewNativePort: Fail # Bug 6890
+cc/RunLoop_ExceptionParent: Fail # Bug 6890
 
 [ $compiler == dartanalyzer ]
 # has compilation error, as designed
diff --git a/runtime/tools/create_snapshot_bin.py b/runtime/tools/create_snapshot_bin.py
index 27eb5c4..7a05456 100755
--- a/runtime/tools/create_snapshot_bin.py
+++ b/runtime/tools/create_snapshot_bin.py
@@ -73,7 +73,7 @@
     return 1
 
   # Setup arguments to the snapshot generator binary.
-  script_args = ["--error_on_malformed_type", "--error_on_bad_override"]
+  script_args = ["--error_on_bad_type", "--error_on_bad_override"]
 
   # First setup the snapshot output filename.
   script_args.append(''.join([ "--snapshot=", options.output_bin ]))
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index a4a773d..babc9a9 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -362,6 +362,7 @@
   virtual const char* Name() const;
 
   virtual const Instance* EvalConstExpr() const {
+    // TODO(regis): What if the type is malbounded?
     if (!type_.IsInstantiated() || type_.IsMalformed()) {
       return NULL;
     }
diff --git a/runtime/vm/block_scheduler.cc b/runtime/vm/block_scheduler.cc
new file mode 100644
index 0000000..2594e8a
--- /dev/null
+++ b/runtime/vm/block_scheduler.cc
@@ -0,0 +1,217 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/block_scheduler.h"
+
+#include "vm/allocation.h"
+#include "vm/flow_graph.h"
+
+namespace dart {
+
+// Compute the edge count at the deopt id of a TargetEntry or Goto.
+static intptr_t ComputeEdgeCount(const Code& unoptimized_code,
+                                 intptr_t deopt_id) {
+  ASSERT(deopt_id != Isolate::kNoDeoptId);
+
+  // Intrinsified functions do not have edge counts, so give all edges equal
+  // weights.
+  if (unoptimized_code.pointer_offsets_length() == 0) return 1;
+
+  uword pc = unoptimized_code.GetPcForDeoptId(deopt_id, PcDescriptors::kDeopt);
+  Array& array = Array::Handle();
+  // Pointer offsets are sorted in decreasing order.  Find the first one
+  // after the deopt id's pc.
+  // TODO(kmillikin): Use a more reliable way to find the counter.
+  for (intptr_t j = unoptimized_code.pointer_offsets_length() - 1;
+       j >= 0;
+       --j) {
+    uword addr =
+        unoptimized_code.GetPointerOffsetAt(j) + unoptimized_code.EntryPoint();
+    if (addr > pc) {
+      array ^= *reinterpret_cast<RawObject**>(addr);
+      break;
+    }
+  }
+  ASSERT(!array.IsNull());
+  return Smi::Value(Smi::RawCast(array.At(0)));
+}
+
+
+// There is an edge from instruction->successor.  Set its weight (edge count
+// per function entry).
+static void SetEdgeWeight(Instruction* instruction,
+                          BlockEntryInstr* successor,
+                          const Code& unoptimized_code,
+                          intptr_t entry_count) {
+  TargetEntryInstr* target = successor->AsTargetEntry();
+  if (target != NULL) {
+    intptr_t count = ComputeEdgeCount(unoptimized_code, target->deopt_id());
+    if ((count >= 0) && (entry_count != 0)) {
+      double weight =
+          static_cast<double>(count) / static_cast<double>(entry_count);
+      target->set_edge_weight(weight);
+    }
+  } else {
+    GotoInstr* jump = instruction->AsGoto();
+    if (jump != NULL) {
+      intptr_t count = ComputeEdgeCount(unoptimized_code, jump->deopt_id());
+      if ((count >= 0) && (entry_count != 0)) {
+        double weight =
+            static_cast<double>(count) / static_cast<double>(entry_count);
+        jump->set_edge_weight(weight);
+      }
+    }
+  }
+}
+
+
+void BlockScheduler::AssignEdgeWeights() const {
+  const Code& unoptimized_code = Code::Handle(
+      flow_graph()->parsed_function().function().unoptimized_code());
+
+  intptr_t entry_count =
+      ComputeEdgeCount(unoptimized_code,
+                       flow_graph()->graph_entry()->normal_entry()->deopt_id());
+  flow_graph()->graph_entry()->set_entry_count(entry_count);
+
+  for (BlockIterator it = flow_graph()->reverse_postorder_iterator();
+       !it.Done();
+       it.Advance()) {
+    BlockEntryInstr* block = it.Current();
+    Instruction* last = block->last_instruction();
+    for (intptr_t i = 0; i < last->SuccessorCount(); ++i) {
+      BlockEntryInstr* succ = last->SuccessorAt(i);
+      SetEdgeWeight(last, succ, unoptimized_code, entry_count);
+    }
+  }
+}
+
+
+// A weighted control-flow graph edge.
+struct Edge {
+  Edge(BlockEntryInstr* source, BlockEntryInstr* target, double weight)
+      : source(source), target(target), weight(weight) { }
+
+  static int LowestWeightFirst(const Edge* a, const Edge* b);
+
+  BlockEntryInstr* source;
+  BlockEntryInstr* target;
+  double weight;
+};
+
+
+// A linked list node in a chain of blocks.
+struct Link : public ZoneAllocated {
+  Link(BlockEntryInstr* block, Link* next) : block(block), next(next) { }
+
+  BlockEntryInstr* block;
+  Link* next;
+};
+
+
+// A chain of blocks with first and last pointers for fast concatenation and
+// a length to support adding a shorter chain's links to a longer chain.
+struct Chain : public ZoneAllocated {
+  explicit Chain(BlockEntryInstr* block)
+      : first(new Link(block, NULL)), last(first), length(1) { }
+
+  Link* first;
+  Link* last;
+  intptr_t length;
+};
+
+
+int Edge::LowestWeightFirst(const Edge* a, const Edge* b) {
+  return (a->weight < b->weight) ? -1 : (a->weight > b->weight);
+}
+
+
+// Combine two chains by adding the shorter chain's links to the longer
+// chain.
+static void Union(GrowableArray<Chain*>* chains,
+                  Chain* source_chain,
+                  Chain* target_chain) {
+  if (source_chain->length < target_chain->length) {
+    for (Link* link = source_chain->first; link != NULL; link = link->next) {
+      (*chains)[link->block->postorder_number()] = target_chain;
+    }
+    // Link the chains.
+    source_chain->last->next = target_chain->first;
+    // Update the state of the longer chain.
+    target_chain->first = source_chain->first;
+    target_chain->length += source_chain->length;
+  } else {
+    for (Link* link = target_chain->first; link != NULL; link = link->next) {
+      (*chains)[link->block->postorder_number()] = source_chain;
+    }
+    source_chain->last->next = target_chain->first;
+    source_chain->last = target_chain->last;
+    source_chain->length += target_chain->length;
+  }
+}
+
+
+void BlockScheduler::ReorderBlocks() const {
+  // Add every block to a chain of length 1 and compute a list of edges
+  // sorted by weight.
+  intptr_t block_count = flow_graph()->preorder().length();
+  GrowableArray<Edge> edges(2 * block_count);
+
+  // A map from a block's postorder number to the chain it is in.  Used to
+  // implement a simple (ordered) union-find data structure.  Chains are
+  // stored by pointer so that they are aliased (mutating one mutates all
+  // shared ones).  Find(n) is simply chains[n].
+  GrowableArray<Chain*> chains(block_count);
+
+  for (BlockIterator it = flow_graph()->postorder_iterator();
+       !it.Done();
+       it.Advance()) {
+    BlockEntryInstr* block = it.Current();
+    chains.Add(new Chain(block));
+
+    Instruction* last = block->last_instruction();
+    for (intptr_t i = 0; i < last->SuccessorCount(); ++i) {
+      BlockEntryInstr* succ = last->SuccessorAt(i);
+      double weight = 0.0;
+      if (succ->IsTargetEntry()) {
+        weight = succ->AsTargetEntry()->edge_weight();
+      } else if (last->IsGoto()) {
+        weight = last->AsGoto()->edge_weight();
+      }
+      edges.Add(Edge(block, succ, weight));
+    }
+  }
+
+  // Handle each edge in turn.  The edges are sorted by increasing weight.
+  edges.Sort(Edge::LowestWeightFirst);
+  while (!edges.is_empty()) {
+    Edge edge = edges.RemoveLast();
+    Chain* source_chain = chains[edge.source->postorder_number()];
+    Chain* target_chain = chains[edge.target->postorder_number()];
+
+    // If the source and target are already in the same chain or if the
+    // edge's source or target is not exposed at the appropriate end of a
+    // chain skip this edge.
+    if ((source_chain == target_chain) ||
+        (edge.source != source_chain->last->block) ||
+        (edge.target != target_chain->first->block)) {
+      continue;
+    }
+
+    Union(&chains, source_chain, target_chain);
+  }
+
+  // Build a new block order.  Emit each chain when its first block occurs
+  // in the original reverse postorder ordering (which gives a topological
+  // sort of the blocks).
+  for (intptr_t i = block_count - 1; i >= 0; --i) {
+    if (chains[i]->first->block == flow_graph()->postorder()[i]) {
+      for (Link* link = chains[i]->first; link != NULL; link = link->next) {
+        flow_graph()->codegen_block_order(true)->Add(link->block);
+      }
+    }
+  }
+}
+
+}  // namespace dart
diff --git a/runtime/vm/block_scheduler.h b/runtime/vm/block_scheduler.h
new file mode 100644
index 0000000..911bb14
--- /dev/null
+++ b/runtime/vm/block_scheduler.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_BLOCK_SCHEDULER_H_
+#define VM_BLOCK_SCHEDULER_H_
+
+#include "vm/allocation.h"
+
+namespace dart {
+
+class FlowGraph;
+
+class BlockScheduler : public ValueObject {
+ public:
+  explicit BlockScheduler(FlowGraph* flow_graph) : flow_graph_(flow_graph) { }
+
+  FlowGraph* flow_graph() const { return flow_graph_; }
+
+  void AssignEdgeWeights() const;
+
+  void ReorderBlocks() const;
+
+ private:
+  FlowGraph* const flow_graph_;
+};
+
+}  // namespace dart
+
+#endif  // VM_BLOCK_SCHEDULER_H_
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 4c8aee0..c6ab494 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -41,7 +41,7 @@
   INIT_LIBRARY(ObjectStore::kConvert,
                convert,
                Bootstrap::convert_source_paths_,
-               NULL),
+               Bootstrap::convert_patch_paths_),
   INIT_LIBRARY(ObjectStore::kCollection,
                collection,
                Bootstrap::collection_source_paths_,
@@ -57,7 +57,7 @@
   INIT_LIBRARY(ObjectStore::kJson,
                json,
                Bootstrap::json_source_paths_,
-               Bootstrap::json_patch_paths_),
+               NULL),
   INIT_LIBRARY(ObjectStore::kMath,
                math,
                Bootstrap::math_source_paths_,
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index 8d77617..6ebc812 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -37,8 +37,8 @@
   static const char* corelib_patch_paths_[];
   static const char* collection_patch_paths_[];
   static const char* collection_dev_patch_paths_[];
+  static const char* convert_patch_paths_[];
   static const char* isolate_patch_paths_[];
-  static const char* json_patch_paths_[];
   static const char* math_patch_paths_[];
   static const char* mirrors_patch_paths_[];
   static const char* typed_data_patch_paths_[];
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index e4e2127..8e01bd5 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -283,6 +283,7 @@
   V(MethodMirror_owner, 1)                                                     \
   V(MethodMirror_parameters, 2)                                                \
   V(MethodMirror_return_type, 1)                                               \
+  V(MethodMirror_source, 1)                                                    \
   V(ParameterMirror_type, 2)                                                   \
   V(TypedefMirror_referent, 1)                                                 \
   V(VariableMirror_type, 1)                                                    \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 84a3e37..cc07f5a 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -16,7 +16,7 @@
 
 DEFINE_FLAG(bool, error_on_bad_override, false,
             "Report error for bad overrides.");
-DEFINE_FLAG(bool, error_on_malformed_type, false,
+DEFINE_FLAG(bool, error_on_bad_type, false,
             "Report error for malformed types.");
 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes.");
 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization.");
@@ -98,8 +98,7 @@
     ASSERT(!cls.is_finalized());
     super_type = cls.super_type();
     if (!super_type.IsNull()) {
-      if (!super_type.IsMalformed() &&
-          super_type.HasResolvedTypeClass()) {
+      if (!super_type.IsMalformed() && super_type.HasResolvedTypeClass()) {
         cls ^= super_type.type_class();
         if (cls.is_finalized()) {
           AddSuperType(super_type, finalized_super_classes);
@@ -476,7 +475,7 @@
     const Type& parameterized_type = Type::Cast(type);
     if (type_class.IsNull()) {
       if ((finalization == kCanonicalizeWellFormed) ||
-          FLAG_error_on_malformed_type) {
+          FLAG_error_on_bad_type) {
         // The type class could not be resolved. The type is malformed.
         FinalizeMalformedType(
             ambiguous_error,  // May be null.
@@ -798,7 +797,7 @@
   // However, type parameter bounds are checked below, even for a raw type.
   if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
     // Wrong number of type arguments. The type is malformed.
-    if (FLAG_error_on_malformed_type) {
+    if (FLAG_error_on_bad_type) {
       const Script& script = Script::Handle(cls.script());
       const String& type_class_name = String::Handle(type_class.Name());
       ReportError(Error::Handle(),  // No previous error.
@@ -1142,7 +1141,7 @@
            !const_value.IsInstanceOf(type,
                                      AbstractTypeArguments::Handle(),
                                      &malformed_error))) {
-        if (FLAG_error_on_malformed_type) {
+        if (FLAG_error_on_bad_type) {
           const AbstractType& const_value_type = AbstractType::Handle(
               const_value.GetType());
           const String& const_value_type_name = String::Handle(
@@ -2186,7 +2185,7 @@
     error ^= Parser::FormatErrorWithAppend(
         prev_error, script, type.token_pos(), "Error", format, args);
   }
-  if (FLAG_error_on_malformed_type) {
+  if (FLAG_error_on_bad_type) {
     ReportError(error);
   }
   type.set_malformed_error(error);
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index a5a597f..b80d822 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -565,9 +565,9 @@
   ASSERT(type.IsFinalized());
   Error& malformed_error = Error::Handle();
   const Bool& result =
-      instance.IsInstanceOf(type,
-                            instantiator_type_arguments,
-                            &malformed_error) ? Bool::True() : Bool::False();
+      Bool::Get(instance.IsInstanceOf(type,
+                                      instantiator_type_arguments,
+                                      &malformed_error));
   if (FLAG_trace_type_checks) {
     PrintTypeCheck("InstanceOf",
         instance, type, instantiator_type_arguments, result);
@@ -611,6 +611,7 @@
       SubtypeTestCache::CheckedHandle(arguments.ArgAt(5));
   ASSERT(!dst_type.IsDynamicType());  // No need to check assignment.
   ASSERT(!dst_type.IsMalformed());  // Already checked in code generator.
+  ASSERT(!dst_type.IsMalbounded());  // Already checked in code generator.
   ASSERT(!src_instance.IsNull());  // Already checked in inlined code.
 
   Error& malformed_error = Error::Handle();
@@ -620,7 +621,7 @@
   if (FLAG_trace_type_checks) {
     PrintTypeCheck("TypeCheck",
                    src_instance, dst_type, instantiator_type_arguments,
-                   is_instance_of ? Bool::True() : Bool::False());
+                   Bool::Get(is_instance_of));
   }
   if (!is_instance_of) {
     // Throw a dynamic type error.
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 9864e56..a50bf18 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -7,6 +7,7 @@
 #include "vm/assembler.h"
 
 #include "vm/ast_printer.h"
+#include "vm/block_scheduler.h"
 #include "vm/code_generator.h"
 #include "vm/code_patcher.h"
 #include "vm/dart_entry.h"
@@ -52,6 +53,7 @@
     "How many times we allow deoptimization before we disable LICM.");
 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining");
 DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis");
+DEFINE_FLAG(bool, reorder_basic_blocks, true, "Enable basic-block reordering.");
 DEFINE_FLAG(bool, verify_compiler, false,
     "Enable compiler verification assertions");
 DECLARE_FLAG(bool, print_flow_graph);
@@ -305,6 +307,11 @@
         }
       }
 
+      BlockScheduler block_scheduler(flow_graph);
+      if (optimized && FLAG_reorder_basic_blocks) {
+        block_scheduler.AssignEdgeWeights();
+      }
+
       if (optimized) {
         TimerScope timer(FLAG_compiler_stats,
                          &CompilerStats::ssa_timer,
@@ -317,7 +324,6 @@
         }
       }
 
-
       // Collect all instance fields that are loaded in the graph and
       // have non-generic type feedback attached to them that can
       // potentially affect optimizations.
@@ -504,6 +510,7 @@
         // Perform register allocation on the SSA graph.
         FlowGraphAllocator allocator(*flow_graph);
         allocator.AllocateRegisters();
+        if (FLAG_reorder_basic_blocks) block_scheduler.ReorderBlocks();
 
         if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
           FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
@@ -511,9 +518,7 @@
       }
 
       Assembler assembler(use_far_branches);
-      FlowGraphCompiler graph_compiler(&assembler,
-                                       *flow_graph,
-                                       optimized);
+      FlowGraphCompiler graph_compiler(&assembler, flow_graph, optimized);
       {
         TimerScope timer(FLAG_compiler_stats,
                          &CompilerStats::graphcompiler_timer,
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index b55b5b2..3e23ce47 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -3821,7 +3821,7 @@
 DART_EXPORT void Dart_SetBooleanReturnValue(Dart_NativeArguments args,
                                             bool retval) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
-  arguments->SetReturn(retval ? Bool::True() : Bool::False());
+  arguments->SetReturn(Bool::Get(retval));
 }
 
 
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index ff19e46..fae125c 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -535,17 +535,28 @@
     intptr_t level_diff = frame_ctx_level - var_ctx_level;
     intptr_t ctx_slot = var_info.index;
     if (level_diff == 0) {
-      *value = ctx_.At(ctx_slot);
+      // TODO(12767) : Need to ensure that we end up with the correct context
+      // here so that this check can be an assert.
+      if ((ctx_slot < ctx_.num_variables()) && (ctx_slot >= 0)) {
+        *value = ctx_.At(ctx_slot);
+      } else {
+        *value = Symbols::New("<unknown>");
+      }
     } else {
       ASSERT(level_diff > 0);
       Context& ctx = Context::Handle(ctx_.raw());
-      while (level_diff > 0) {
-        ASSERT(!ctx.IsNull());
+      while (level_diff > 0 && !ctx.IsNull()) {
         level_diff--;
         ctx = ctx.parent();
       }
-      ASSERT(!ctx.IsNull());
-      *value = ctx.At(ctx_slot);
+      // TODO(12767) : Need to ensure that we end up with the correct context
+      // here so that this check can be assert.
+      if (!ctx.IsNull() &&
+          ((ctx_slot < ctx_.num_variables()) && (ctx_slot >= 0))) {
+        *value = ctx.At(ctx_slot);
+      } else {
+        *value = Symbols::New("<unknown>");
+      }
     }
   }
 }
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 0df495b..114de52 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -465,7 +465,7 @@
   } else if (obj.IsClass()) {
     cls = Class::Cast(obj).raw();
   } else {
-    return Api::NewError("%s expects argument 'target' to be a type.",
+    return Api::NewError("%s expects argument 'target' to be a type",
                          CURRENT_FUNC);
   }
   return Api::NewHandle(isolate, isolate->debugger()->GetStaticFields(cls));
@@ -498,13 +498,24 @@
 }
 
 
-DART_EXPORT Dart_Handle Dart_EvaluateExpr(Dart_Handle target,
+DART_EXPORT Dart_Handle Dart_EvaluateExpr(Dart_Handle target_in,
                                           Dart_Handle expr_in) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
-  UNWRAP_AND_CHECK_PARAM(Instance, obj, target);
+
+  const Object& target = Object::Handle(isolate, Api::UnwrapHandle(target_in));
+  if (target.IsError()) return target_in;
+  if (target.IsNull()) {
+    return Api::NewError("%s expects argument 'target' to be non-null",
+                         CURRENT_FUNC);
+  }
   UNWRAP_AND_CHECK_PARAM(String, expr, expr_in);
-  return Api::NewHandle(isolate, obj.Evaluate(expr));
+  if (target.IsInstance()) {
+    return Api::NewHandle(isolate, Instance::Cast(target).Evaluate(expr));
+  } else if (target.IsClass()) {
+    return Api::NewHandle(isolate, Class::Cast(target).Evaluate(expr));
+  }
+  return Api::NewError("%s: unsupported target type", CURRENT_FUNC);
 }
 
 
@@ -527,6 +538,17 @@
 }
 
 
+DART_EXPORT Dart_Handle Dart_GetClassFromId(intptr_t class_id) {
+  Isolate* isolate = Isolate::Current();
+  DARTSCOPE(isolate);
+  if (!isolate->class_table()->IsValidIndex(class_id)) {
+    return Api::NewError("%s: %" Pd " is not a valid class id",
+                         CURRENT_FUNC, class_id);
+  }
+  return Api::NewHandle(isolate, isolate->class_table()->At(class_id));
+}
+
+
 DART_EXPORT Dart_Handle Dart_GetSuperclass(Dart_Handle cls_in) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index 2cec246..4b4b458 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -1526,10 +1526,13 @@
       "main() {                          \n"
       "  var p = new Point(3, 4);        \n"
       "  l = [1, 2, 3];        /*BP*/    \n"
+      "  m = {'\"': 'quote' ,            \n"
+      "       \"\t\": 'tab' };           \n"
       "  return p;                       \n"
       "}                                 \n"
       "var _factor = 2;                  \n"
       "var l;                            \n"
+      "var m;                            \n"
       "class Point {                     \n"
       "  var x, y;                       \n"
       "  Point(this.x, this.y);          \n"
@@ -1559,6 +1562,18 @@
   EXPECT_VALID(len);
   EXPECT(Dart_IsNumber(len));
   EXPECT_EQ(3, ToInt64(len));
+
+  Dart_Handle point_class = Dart_GetClass(script_lib, NewString("Point"));
+  EXPECT_VALID(point_class);
+  Dart_Handle elem = Dart_EvaluateExpr(point_class, NewString("m['\"']"));
+  EXPECT_VALID(elem);
+  EXPECT(Dart_IsString(elem));
+  EXPECT_STREQ("quote", ToCString(elem));
+
+  elem = Dart_EvaluateExpr(point_class, NewString("m[\"\\t\"]"));
+  EXPECT_VALID(elem);
+  EXPECT(Dart_IsString(elem));
+  EXPECT_STREQ("tab", ToCString(elem));
 }
 
 
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index f374053..1db657e 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -744,7 +744,7 @@
   ASSERT(instr->kind() == kRetAddress);
   DeoptRetAddressInstr* ret_address_instr =
       static_cast<DeoptRetAddressInstr*>(instr);
-  // TODO(regis): The following assert may trigger when displaying a backtrace
+  // The following assert may trigger when displaying a backtrace
   // from the simulator.
   ASSERT(Isolate::IsDeoptAfter(ret_address_instr->deopt_id()));
   ASSERT(!object_table.IsNull());
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 7cabc29..36c148d 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -31,6 +31,7 @@
     preorder_(),
     postorder_(),
     reverse_postorder_(),
+    optimized_block_order_(),
     block_effects_(NULL),
     licm_allowed_(true),
     use_far_branches_(false),
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index 57fe60f..4a84196 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -78,6 +78,9 @@
   const GrowableArray<BlockEntryInstr*>& reverse_postorder() const {
     return reverse_postorder_;
   }
+  GrowableArray<BlockEntryInstr*>* codegen_block_order(bool is_optimized) {
+    return is_optimized ? &optimized_block_order_ : &reverse_postorder_;
+  }
 
   // Iterators.
   BlockIterator reverse_postorder_iterator() const {
@@ -249,6 +252,7 @@
   GrowableArray<BlockEntryInstr*> preorder_;
   GrowableArray<BlockEntryInstr*> postorder_;
   GrowableArray<BlockEntryInstr*> reverse_postorder_;
+  GrowableArray<BlockEntryInstr*> optimized_block_order_;
   ConstantInstr* constant_null_;
 
   BlockEffects* block_effects_;
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 2ff3dc1..ce28a04 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -81,18 +81,28 @@
       callee_graph->max_virtual_register_number());
 
   // Attach the outer environment on each instruction in the callee graph.
+  ASSERT(call_->env() != NULL);
+  // Scale the edge weights by the call count for the inlined function.
+  double scale_factor = static_cast<double>(call_->CallCount())
+      / static_cast<double>(caller_graph_->graph_entry()->entry_count());
   for (BlockIterator block_it = callee_graph->postorder_iterator();
        !block_it.Done();
        block_it.Advance()) {
-    for (ForwardInstructionIterator it(block_it.Current());
-         !it.Done();
-         it.Advance()) {
-      Instruction* instr = it.Current();
+    BlockEntryInstr* block = block_it.Current();
+    if (block->IsTargetEntry()) {
+      block->AsTargetEntry()->adjust_edge_weight(scale_factor);
+    }
+    Instruction* instr = block;
+    for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
+      instr = it.Current();
       // TODO(zerny): Avoid creating unnecessary environments. Note that some
       // optimizations need deoptimization info for non-deoptable instructions,
       // eg, LICM on GOTOs.
       if (instr->env() != NULL) call_->env()->DeepCopyToOuter(instr);
     }
+    if (instr->IsGoto()) {
+      instr->AsGoto()->adjust_edge_weight(scale_factor);
+    }
   }
 }
 
@@ -852,7 +862,7 @@
 
 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) {
   const AbstractType& type = node->type();
-  ASSERT(type.IsFinalized() && !type.IsMalformed());
+  ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
   if (type.IsInstantiated()) {
     ReturnDefinition(new ConstantInstr(type));
   } else {
@@ -876,9 +886,9 @@
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
 
-  // If the destination type is malformed, a dynamic type error must be thrown
-  // at run time.
-  if (dst_type.IsMalformed()) {
+  // If the destination type is malformed or malbounded, a dynamic type error
+  // must be thrown at run time.
+  if (dst_type.IsMalformed() || dst_type.IsMalbounded()) {
     return false;
   }
 
@@ -1203,7 +1213,7 @@
 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) {
   ASSERT(Token::IsTypeTestOperator(node->kind()));
   const AbstractType& type = node->right()->AsTypeNode()->type();
-  ASSERT(type.IsFinalized() && !type.IsMalformed());
+  ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
   const bool negate_result = (node->kind() == Token::kISNOT);
   // All objects are instances of type T if Object type is a subtype of type T.
   const Type& object_type = Type::Handle(Type::ObjectType());
@@ -1212,8 +1222,7 @@
     EffectGraphVisitor for_left_value(owner(), temp_index());
     node->left()->Visit(&for_left_value);
     Append(for_left_value);
-    ReturnDefinition(new ConstantInstr(negate_result ?
-                                       Bool::False() : Bool::True()));
+    ReturnDefinition(new ConstantInstr(Bool::Get(!negate_result)));
     return;
   }
 
@@ -1228,11 +1237,9 @@
     if (literal_value.IsInstanceOf(type,
                                    TypeArguments::Handle(),
                                    &malformed_error)) {
-      result = new ConstantInstr(negate_result ?
-                                 Bool::False() : Bool::True());
+      result = new ConstantInstr(Bool::Get(!negate_result));
     } else {
-      result = new ConstantInstr(negate_result ?
-                                 Bool::True() : Bool::False());
+      result = new ConstantInstr(Bool::Get(negate_result));
     }
     ASSERT(malformed_error.IsNull());
 
@@ -1263,8 +1270,7 @@
   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();
+  const Bool& negate = Bool::Get(node->kind() == Token::kISNOT);
   Value* negate_arg = Bind(new ConstantInstr(negate));
   arguments->Add(PushArgument(negate_arg));
   const intptr_t kNumArgsChecked = 1;
@@ -1306,7 +1312,7 @@
   Append(for_value);
   const String& dst_name = String::ZoneHandle(
       Symbols::New(Exceptions::kCastErrorDstName));
-  if (type.IsMalformed()) {
+  if (type.IsMalformed() || type.IsMalbounded()) {
     ReturnValue(BuildAssignableValue(node->token_pos(),
                                      for_value.value(),
                                      type,
@@ -2467,7 +2473,7 @@
         Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew));
     type ^= ClassFinalizer::FinalizeType(
         instantiator_class, type, ClassFinalizer::kFinalize);
-    ASSERT(!type.IsMalformed());
+    ASSERT(!type.IsMalformed() && !type.IsMalbounded());
     type_arguments = type.arguments();
     type_arguments = type_arguments.Canonicalize();
     return Bind(new ConstantInstr(type_arguments));
@@ -3731,7 +3737,7 @@
 void FlowGraphBuilder::PruneUnreachable() {
   ASSERT(osr_id_ != Isolate::kNoDeoptId);
   BitVector* block_marks = new BitVector(last_used_block_id_ + 1);
-  bool found = graph_entry_->PruneUnreachable(this, graph_entry_, osr_id_,
+  bool found = graph_entry_->PruneUnreachable(this, graph_entry_, NULL, osr_id_,
                                               block_marks);
   ASSERT(found);
 }
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 353cc8b..84ba8c0 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -20,8 +20,8 @@
 // (factory-name-symbol, result-cid, fingerprint).
 // TODO(srdjan): Store the values in the snapshot instead.
 #define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
-  V(ObjectArrayFactory, kArrayCid, 712468799)                                  \
-  V(GrowableObjectArrayWithData, kGrowableObjectArrayCid, 917195627)           \
+  V(ObjectArrayFactory, kArrayCid, 1930677134)                                 \
+  V(GrowableObjectArrayWithData, kGrowableObjectArrayCid, 1012992871)          \
   V(GrowableObjectArrayFactory, kGrowableObjectArrayCid, 1707369421)           \
   V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 1340298556)                     \
   V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1775618642)                   \
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 13516a1..f8b752a 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -64,12 +64,12 @@
 
 
 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler,
-                                     const FlowGraph& flow_graph,
+                                     FlowGraph* flow_graph,
                                      bool is_optimizing)
     : assembler_(assembler),
-      parsed_function_(flow_graph.parsed_function()),
-      flow_graph_(flow_graph),
-      block_order_(flow_graph.reverse_postorder()),
+      parsed_function_(flow_graph->parsed_function()),
+      flow_graph_(*flow_graph),
+      block_order_(*flow_graph->codegen_block_order(is_optimizing)),
       current_block_(NULL),
       exception_handlers_list_(NULL),
       pc_descriptors_list_(NULL),
@@ -502,8 +502,8 @@
 
 // Returns 'true' if code generation for this function is complete, i.e.,
 // no fall-through to regular code is needed.
-bool FlowGraphCompiler::TryIntrinsify() {
-  if (!CanOptimizeFunction()) return false;
+void FlowGraphCompiler::TryIntrinsify() {
+  if (!CanOptimizeFunction()) return;
   // Intrinsification skips arguments checks, therefore disable if in checked
   // mode.
   if (FLAG_intrinsify && !FLAG_enable_type_checks) {
@@ -517,7 +517,7 @@
       const LoadInstanceFieldNode& load_node =
           *return_node.value()->AsLoadInstanceFieldNode();
       GenerateInlinedGetter(load_node.field().Offset());
-      return true;
+      return;
     }
     if (parsed_function().function().kind() == RawFunction::kImplicitSetter) {
       // An implicit setter must have a specific AST structure.
@@ -530,7 +530,7 @@
           *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode();
       if (store_node.field().guarded_cid() == kDynamicCid) {
         GenerateInlinedSetter(store_node.field().Offset());
-        return true;
+        return;
       }
     }
   }
@@ -1098,7 +1098,7 @@
 
 // Returns true if checking against this type is a direct class id comparison.
 bool FlowGraphCompiler::TypeCheckAsClassEquality(const AbstractType& type) {
-  ASSERT(type.IsFinalized() && !type.IsMalformed());
+  ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
   // Requires CHA, which can be applied in optimized code only,
   if (!FLAG_use_cha || !is_optimizing()) return false;
   if (!type.IsInstantiated()) return false;
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index e9b2b37..8847f8c 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -235,7 +235,7 @@
 
  public:
   FlowGraphCompiler(Assembler* assembler,
-                    const FlowGraph& flow_graph,
+                    FlowGraph* flow_graph,
                     bool is_optimizing);
 
   ~FlowGraphCompiler();
@@ -280,9 +280,7 @@
   // Bail out of the flow graph compiler. Does not return to the caller.
   void Bailout(const char* reason);
 
-  // Returns 'true' if code generation for this function is complete, i.e.,
-  // no fall-through to regular code is needed.
-  bool TryIntrinsify();
+  void TryIntrinsify();
 
   void GenerateCallRuntime(intptr_t token_pos,
                            intptr_t deopt_id,
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index c155fe3..b8a6025 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -158,7 +158,6 @@
 
   __ BranchLink(&StubCode::DeoptimizeLabel());
   set_pc_offset(assem->CodeSize());
-  __ bkpt(0);  // TODO(regis): Remove breakpoint to save space.
 #undef __
 }
 
@@ -566,7 +565,7 @@
                                            const AbstractType& type,
                                            bool negate_result,
                                            LocationSummary* locs) {
-  ASSERT(type.IsFinalized() && !type.IsMalformed());
+  ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
 
   // Preserve instantiator (R2) and its type arguments (R1).
   __ PushList((1 << R1) | (1 << R2));
@@ -620,11 +619,11 @@
     __ b(&done);
   }
   __ Bind(&is_not_instance);
-  __ LoadObject(R0, negate_result ? Bool::True() : Bool::False());
+  __ LoadObject(R0, Bool::Get(negate_result));
   __ b(&done);
 
   __ Bind(&is_instance);
-  __ LoadObject(R0, negate_result ? Bool::False() : Bool::True());
+  __ LoadObject(R0, Bool::Get(!negate_result));
   __ Bind(&done);
   // Remove instantiator (R2) and its type arguments (R1).
   __ Drop(2);
@@ -652,7 +651,7 @@
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
-  ASSERT(dst_type.IsMalformed() ||
+  ASSERT(dst_type.IsMalformed() || dst_type.IsMalbounded() ||
          (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
   // Preserve instantiator (R2) and its type arguments (R1).
   __ PushList((1 << R1) | (1 << R2));
@@ -668,9 +667,15 @@
     __ b(&is_assignable, EQ);
   }
 
-  // Generate throw new TypeError() if the type is malformed.
-  if (dst_type.IsMalformed()) {
-    const Error& error = Error::Handle(dst_type.malformed_error());
+  // Generate throw new TypeError() if the type is malformed or malbounded.
+  if (dst_type.IsMalformed() || dst_type.IsMalbounded()) {
+    Error& error = Error::Handle();
+    if (dst_type.IsMalformed()) {
+      error = dst_type.malformed_error();
+    } else {
+      const bool is_malbounded = dst_type.IsMalboundedWithError(&error);
+      ASSERT(is_malbounded);
+    }
     const String& error_message = String::ZoneHandle(
         Symbols::New(error.ToErrorCString()));
     __ PushObject(Object::ZoneHandle());  // Make room for the result.
@@ -1118,14 +1123,8 @@
 //   R4: arguments descriptor array.
 void FlowGraphCompiler::CompileGraph() {
   InitCompiler();
-  if (TryIntrinsify()) {
-    // Although this intrinsified code will never be patched, it must satisfy
-    // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum
-    // code size.
-    __ bkpt(0);
-    __ Branch(&StubCode::FixCallersTargetLabel());
-    return;
-  }
+
+  TryIntrinsify();
 
   EmitFrameEntry();
 
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 924ade9..4eb2ea1 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -576,7 +576,7 @@
                                            const AbstractType& type,
                                            bool negate_result,
                                            LocationSummary* locs) {
-  ASSERT(type.IsFinalized() && !type.IsMalformed());
+  ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
 
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
@@ -634,11 +634,11 @@
     __ jmp(&done, Assembler::kNearJump);
   }
   __ Bind(&is_not_instance);
-  __ LoadObject(EAX, negate_result ? Bool::True() : Bool::False());
+  __ LoadObject(EAX, Bool::Get(negate_result));
   __ jmp(&done, Assembler::kNearJump);
 
   __ Bind(&is_instance);
-  __ LoadObject(EAX, negate_result ? Bool::False() : Bool::True());
+  __ LoadObject(EAX, Bool::Get(!negate_result));
   __ Bind(&done);
   __ popl(EDX);  // Remove pushed instantiator type arguments.
   __ popl(ECX);  // Remove pushed instantiator.
@@ -666,7 +666,7 @@
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
-  ASSERT(dst_type.IsMalformed() ||
+  ASSERT(dst_type.IsMalformed() || dst_type.IsMalbounded() ||
          (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
   __ pushl(ECX);  // Store instantiator.
   __ pushl(EDX);  // Store instantiator type arguments.
@@ -687,9 +687,15 @@
     __ j(EQUAL, &is_assignable);
   }
 
-  // Generate throw new TypeError() if the type is malformed.
-  if (dst_type.IsMalformed()) {
-    const Error& error = Error::Handle(dst_type.malformed_error());
+  // Generate throw new TypeError() if the type is malformed or malbounded.
+  if (dst_type.IsMalformed() || dst_type.IsMalbounded()) {
+    Error& error = Error::Handle();
+    if (dst_type.IsMalformed()) {
+      error = dst_type.malformed_error();
+    } else {
+      const bool is_malbounded = dst_type.IsMalboundedWithError(&error);
+      ASSERT(is_malbounded);
+    }
     const String& error_message = String::ZoneHandle(
         Symbols::New(error.ToErrorCString()));
     __ PushObject(Object::ZoneHandle());  // Make room for the result.
@@ -1120,14 +1126,8 @@
 
 void FlowGraphCompiler::CompileGraph() {
   InitCompiler();
-  if (TryIntrinsify()) {
-    // Although this intrinsified code will never be patched, it must satisfy
-    // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum
-    // code size.
-    __ int3();
-    __ jmp(&StubCode::FixCallersTargetLabel());
-    return;
-  }
+
+  TryIntrinsify();
 
   EmitFrameEntry();
 
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 49e8c3a..c428d74 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -158,7 +158,6 @@
 
   __ BranchLink(&StubCode::DeoptimizeLabel());
   set_pc_offset(assem->CodeSize());
-  __ break_(0);  // TODO(regis): Remove breakpoint to save space.
 #undef __
 }
 
@@ -563,7 +562,7 @@
                                            const AbstractType& type,
                                            bool negate_result,
                                            LocationSummary* locs) {
-  ASSERT(type.IsFinalized() && !type.IsMalformed());
+  ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
 
   // Preserve instantiator (A2) and its type arguments (A1).
   __ addiu(SP, SP, Immediate(-2 * kWordSize));
@@ -623,11 +622,11 @@
     __ b(&done);
   }
   __ Bind(&is_not_instance);
-  __ LoadObject(V0, negate_result ? Bool::True() : Bool::False());
+  __ LoadObject(V0, Bool::Get(negate_result));
   __ b(&done);
 
   __ Bind(&is_instance);
-  __ LoadObject(V0, negate_result ? Bool::False() : Bool::True());
+  __ LoadObject(V0, Bool::Get(!negate_result));
   __ Bind(&done);
   // Remove instantiator (A2) and its type arguments (A1).
   __ Drop(2);
@@ -657,7 +656,7 @@
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
-  ASSERT(dst_type.IsMalformed() ||
+  ASSERT(dst_type.IsMalformed() || dst_type.IsMalbounded() ||
          (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
   // Preserve instantiator and its type arguments.
   __ addiu(SP, SP, Immediate(-2 * kWordSize));
@@ -675,9 +674,15 @@
     __ BranchEqual(A0, Object::transition_sentinel(), &is_assignable);
   }
 
-  // Generate throw new TypeError() if the type is malformed.
-  if (dst_type.IsMalformed()) {
-    const Error& error = Error::Handle(dst_type.malformed_error());
+  // Generate throw new TypeError() if the type is malformed or malbounded.
+  if (dst_type.IsMalformed() || dst_type.IsMalbounded()) {
+    Error& error = Error::Handle();
+    if (dst_type.IsMalformed()) {
+      error = dst_type.malformed_error();
+    } else {
+      const bool is_malbounded = dst_type.IsMalboundedWithError(&error);
+      ASSERT(is_malbounded);
+    }
     const String& error_message = String::ZoneHandle(
         Symbols::New(error.ToErrorCString()));
 
@@ -764,9 +769,6 @@
 }
 
 
-// TODO(regis): Pass an offset instead of an Address to avoid addressing
-// mode restrictions and remove Operand::Equals() on IA32/X64 and
-// Address::Equals() on ARM/MIPS.
 void FlowGraphCompiler::EmitTrySyncMove(intptr_t dest_offset,
                                         Location loc,
                                         bool* push_emitted) {
@@ -1161,14 +1163,8 @@
 //   S4: arguments descriptor array.
 void FlowGraphCompiler::CompileGraph() {
   InitCompiler();
-  if (TryIntrinsify()) {
-    // Although this intrinsified code will never be patched, it must satisfy
-    // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum
-    // code size.
-    __ break_(0);
-    __ Branch(&StubCode::FixCallersTargetLabel());
-    return;
-  }
+
+  TryIntrinsify();
 
   EmitFrameEntry();
 
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 398fe3a..71d8a9c 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -573,7 +573,7 @@
                                            const AbstractType& type,
                                            bool negate_result,
                                            LocationSummary* locs) {
-  ASSERT(type.IsFinalized() && !type.IsMalformed());
+  ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
 
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
@@ -631,11 +631,11 @@
     __ jmp(&done, Assembler::kNearJump);
   }
   __ Bind(&is_not_instance);
-  __ LoadObject(RAX, negate_result ? Bool::True() : Bool::False());
+  __ LoadObject(RAX, Bool::Get(negate_result));
   __ jmp(&done, Assembler::kNearJump);
 
   __ Bind(&is_instance);
-  __ LoadObject(RAX, negate_result ? Bool::False() : Bool::True());
+  __ LoadObject(RAX, Bool::Get(!negate_result));
   __ Bind(&done);
   __ popq(RDX);  // Remove pushed instantiator type arguments.
   __ popq(RCX);  // Remove pushed instantiator.
@@ -663,7 +663,7 @@
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
-  ASSERT(dst_type.IsMalformed() ||
+  ASSERT(dst_type.IsMalformed() || dst_type.IsMalbounded() ||
          (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
   __ pushq(RCX);  // Store instantiator.
   __ pushq(RDX);  // Store instantiator type arguments.
@@ -681,9 +681,15 @@
     __ j(EQUAL, &is_assignable);
   }
 
-  // Generate throw new TypeError() if the type is malformed.
-  if (dst_type.IsMalformed()) {
-    const Error& error = Error::Handle(dst_type.malformed_error());
+  // Generate throw new TypeError() if the type is malformed or malbounded.
+  if (dst_type.IsMalformed() || dst_type.IsMalbounded()) {
+    Error& error = Error::Handle();
+    if (dst_type.IsMalformed()) {
+      error = dst_type.malformed_error();
+    } else {
+      const bool is_malbounded = dst_type.IsMalboundedWithError(&error);
+      ASSERT(is_malbounded);
+    }
     const String& error_message = String::ZoneHandle(
         Symbols::New(error.ToErrorCString()));
     __ PushObject(Object::ZoneHandle());  // Make room for the result.
@@ -1115,15 +1121,8 @@
 
 void FlowGraphCompiler::CompileGraph() {
   InitCompiler();
-  if (TryIntrinsify()) {
-    // Although this intrinsified code will never be patched, it must satisfy
-    // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum
-    // code size, and nop(2) increases the minimum code size appropriately.
-    __ nop(2);
-    __ int3();
-    __ jmp(&StubCode::FixCallersTargetLabel());
-    return;
-  }
+
+  TryIntrinsify();
 
   EmitFrameEntry();
 
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 15e6df8..4558352 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -4,6 +4,7 @@
 
 #include "vm/flow_graph_inliner.h"
 
+#include "vm/block_scheduler.h"
 #include "vm/compiler.h"
 #include "vm/flags.h"
 #include "vm/flow_graph.h"
@@ -592,6 +593,9 @@
       ASSERT(arguments->length() == function.NumParameters());
       ASSERT(param_stubs->length() == callee_graph->parameter_count());
 
+      BlockScheduler block_scheduler(callee_graph);
+      block_scheduler.AssignEdgeWeights();
+
       {
         TimerScope timer(FLAG_compiler_stats,
                          &CompilerStats::graphinliner_ssa_timer,
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index ba9a4d9..ff732c0 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -770,24 +770,52 @@
                call->env(),
                Definition::kEffect);
 
-  // Insert array length load and bounds check.
-  const bool is_immutable =
-      CheckArrayBoundInstr::IsFixedLengthArrayType(class_id);
-  LoadFieldInstr* length =
-      new LoadFieldInstr(new Value(*array),
-                         CheckArrayBoundInstr::LengthOffsetFor(class_id),
-                         Type::ZoneHandle(Type::SmiType()),
-                         is_immutable);
-  length->set_result_cid(kSmiCid);
-  length->set_recognized_kind(
-      LoadFieldInstr::RecognizedKindFromArrayCid(class_id));
-  InsertBefore(call, length, NULL, Definition::kValue);
-  InsertBefore(call,
-               new CheckArrayBoundInstr(new Value(length),
-                                        new Value(*index),
-                                        call->deopt_id()),
-               call->env(),
-               Definition::kEffect);
+  bool emit_bounds_check = true;
+  // Get the field for the array.
+  const Field* field = NULL;
+  if ((*array)->IsLoadField()) {
+    LoadFieldInstr* load_field_instr = (*array)->AsLoadField();
+    field = load_field_instr->field();
+  }
+  // Extract the guarded array length.
+  intptr_t guarded_array_length = -1;
+  if (field != NULL) {
+    if (field->guarded_list_length() >= 0) {
+      guarded_array_length = field->guarded_list_length();
+    }
+  }
+  Definition* i = *index;
+  // Check if we can skip emitting the bounds check.
+  if (i->IsConstant() && guarded_array_length >= 0) {
+    ConstantInstr* constant = i->AsConstant();
+    ASSERT(constant != NULL);
+    intptr_t ci = Smi::Cast(constant->value()).Value();
+    if (ci < guarded_array_length) {
+      emit_bounds_check = false;
+    }
+  }
+
+  if (emit_bounds_check) {
+    // Insert array length load and bounds check.
+    const bool is_immutable =
+        CheckArrayBoundInstr::IsFixedLengthArrayType(class_id);
+    LoadFieldInstr* length =
+        new LoadFieldInstr(new Value(*array),
+                           CheckArrayBoundInstr::LengthOffsetFor(class_id),
+                           Type::ZoneHandle(Type::SmiType()),
+                           is_immutable);
+    length->set_result_cid(kSmiCid);
+    length->set_recognized_kind(
+        LoadFieldInstr::RecognizedKindFromArrayCid(class_id));
+    InsertBefore(call, length, NULL, Definition::kValue);
+    InsertBefore(call,
+                 new CheckArrayBoundInstr(new Value(length),
+                                          new Value(*index),
+                                          call->deopt_id()),
+                 call->env(),
+                 Definition::kEffect);
+  }
+
 
   if (class_id == kGrowableObjectArrayCid) {
     // Insert data elements load.
@@ -2484,7 +2512,9 @@
 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();
+  if (!type.IsInstantiated() || type.IsMalformed() || type.IsMalbounded()) {
+    return Bool::null();
+  }
   const Class& type_class = Class::Handle(type.type_class());
   if (type_class.HasTypeArguments()) {
     // Only raw types can be directly compared, thus disregarding type
@@ -2509,7 +2539,7 @@
                                             TypeArguments::Handle(),
                                             NULL);
     if (prev.IsNull()) {
-      prev = is_subtype ? Bool::True().raw() : Bool::False().raw();
+      prev = Bool::Get(is_subtype).raw();
     } else {
       if (is_subtype != prev.value()) return Bool::null();
     }
@@ -2535,7 +2565,7 @@
     if (!as_bool.IsNull()) {
       AddReceiverCheck(call);
       if (negate) {
-        as_bool = Bool::Get(!as_bool.value());
+        as_bool = Bool::Get(!as_bool.value()).raw();
       }
       ConstantInstr* bool_const = flow_graph()->GetConstant(as_bool);
       for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
@@ -2568,7 +2598,7 @@
   Definition* type_args = call->ArgumentAt(2);
   const AbstractType& type =
       AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value());
-  ASSERT(!type.IsMalformed());
+  ASSERT(!type.IsMalformed() && !type.IsMalbounded());
   const ICData& unary_checks =
       ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks());
   if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) {
@@ -5968,10 +5998,7 @@
 
   if (instr->left()->definition() == instr->right()->definition()) {
     // Fold x === x, and x !== x to true/false.
-    SetValue(instr,
-             (instr->kind() == Token::kEQ_STRICT)
-               ? Bool::True()
-               : Bool::False());
+    SetValue(instr, Bool::Get(instr->kind() == Token::kEQ_STRICT));
     return;
   }
 
@@ -5982,14 +6009,14 @@
       bool result = left.IsNull() ? instr->right()->Type()->IsNull()
                                   : instr->left()->Type()->IsNull();
       if (instr->kind() == Token::kNE_STRICT) result = !result;
-      SetValue(instr, result ? Bool::True() : Bool::False());
+      SetValue(instr, Bool::Get(result));
     } 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, result ? Bool::True() : Bool::False());
+    SetValue(instr, Bool::Get(result));
   }
 }
 
@@ -6021,10 +6048,7 @@
     // comparisons.
     if (instr->IsCheckedStrictEqual() ||
         RawObject::IsIntegerClassId(instr->operation_cid())) {
-      return SetValue(instr,
-                      (instr->kind() == Token::kEQ)
-                        ? Bool::True()
-                        : Bool::False());
+      return SetValue(instr, Bool::Get(instr->kind() == Token::kEQ));
     }
   }
 
@@ -6035,7 +6059,10 @@
       const bool result = CompareIntegers(instr->kind(),
                                           Integer::Cast(left),
                                           Integer::Cast(right));
-      SetValue(instr, result ? Bool::True() : Bool::False());
+      SetValue(instr, Bool::Get(result));
+    } else if (left.IsString() && right.IsString()) {
+      const bool result = String::Cast(left).Equals(String::Cast(right));
+      SetValue(instr, Bool::Get((instr->kind() == Token::kEQ) == result));
     } else {
       SetValue(instr, non_constant_);
     }
@@ -6053,7 +6080,7 @@
       const bool result = CompareIntegers(instr->kind(),
                                           Integer::Cast(left),
                                           Integer::Cast(right));
-      SetValue(instr, result ? Bool::True() : Bool::False());
+      SetValue(instr, Bool::Get(result));
     } else {
       SetValue(instr, non_constant_);
     }
@@ -6113,7 +6140,7 @@
     SetValue(instr, non_constant_);
   } else if (IsConstant(value)) {
     bool val = value.raw() != Bool::True().raw();
-    SetValue(instr, val ? Bool::True() : Bool::False());
+    SetValue(instr, Bool::Get(val));
   }
 }
 
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index ba39000..e26e690 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -359,6 +359,7 @@
   if ((assert == NULL) || (assert == kStrengthenedAssertMarker)) {
     return;
   }
+  ASSERT(assert->env() != NULL);
 
   Instruction* check_clone = NULL;
   if (check->IsCheckSmi()) {
@@ -552,8 +553,8 @@
                                          bool is_nullable,
                                          bool* is_instance) {
   ASSERT(is_instance != NULL);
-  // We cannot give an answer if the given type is malformed.
-  if (type.IsMalformed()) {
+  // We cannot give an answer if the given type is malformed or malbounded.
+  if (type.IsMalformed() || type.IsMalbounded()) {
     return false;
   }
 
@@ -568,7 +569,7 @@
 
   // Consider the compile type of the value.
   const AbstractType& compile_type = *ToAbstractType();
-  if (compile_type.IsMalformed()) {
+  if (compile_type.IsMalformed() || compile_type.IsMalbounded()) {
     return false;
   }
 
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 06c3d3a..cb7946f 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -274,6 +274,7 @@
       catch_entries_(),
       initial_definitions_(),
       osr_id_(osr_id),
+      entry_count_(0),
       spill_slot_count_(0),
       fixed_slot_count_(0) {
 }
@@ -674,6 +675,7 @@
 
 
 void BranchInstr::InheritDeoptTarget(Instruction* other) {
+  ASSERT(env() == NULL);
   Instruction::InheritDeoptTarget(other);
   comparison()->SetDeoptId(GetDeoptId());
 }
@@ -835,6 +837,7 @@
 
 bool BlockEntryInstr::PruneUnreachable(FlowGraphBuilder* builder,
                                        GraphEntryInstr* graph_entry,
+                                       Instruction* parent,
                                        intptr_t osr_id,
                                        BitVector* block_marks) {
   // Search for the instruction with the OSR id.  Use a depth first search
@@ -861,7 +864,7 @@
       ASSERT(instr->previous() == this);
 
       GotoInstr* goto_join = new GotoInstr(AsJoinEntry());
-      goto_join->deopt_id_ = deopt_id_;
+      goto_join->deopt_id_ = parent->deopt_id_;
       graph_entry->normal_entry()->LinkTo(goto_join);
       return true;
     }
@@ -871,6 +874,7 @@
   for (intptr_t i = instr->SuccessorCount() - 1; i >= 0; --i) {
     if (instr->SuccessorAt(i)->PruneUnreachable(builder,
                                                 graph_entry,
+                                                instr,
                                                 osr_id,
                                                 block_marks)) {
       return true;
@@ -1353,6 +1357,7 @@
 
 
 Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) {
+  if (!HasUses()) return NULL;
   if (!IsImmutableLengthLoad()) return this;
 
   // For fixed length arrays if the array is the result of a known constructor
@@ -1636,19 +1641,6 @@
 }
 
 
-void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  __ Bind(compiler->GetJumpLabel(this));
-  if (!compiler->is_optimizing()) {
-    compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
-                                   deopt_id_,
-                                   Scanner::kDummyTokenIndex);
-  }
-  if (HasParallelMove()) {
-    compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
-  }
-}
-
-
 LocationSummary* PhiInstr::MakeLocationSummary() const {
   UNREACHABLE();
   return NULL;
@@ -1883,20 +1875,14 @@
 }
 
 
-Environment* Environment::DeepCopy() const {
-  return (this == NULL) ? NULL : DeepCopy(Length());
-}
-
-
 Environment* Environment::DeepCopy(intptr_t length) const {
   ASSERT(length <= values_.length());
-  if (this == NULL) return NULL;
   Environment* copy =
       new Environment(length,
                       fixed_parameter_count_,
                       deopt_id_,
                       function_,
-                      outer_->DeepCopy());
+                      (outer_ == NULL) ? NULL : outer_->DeepCopy());
   for (intptr_t i = 0; i < length; ++i) {
     copy->values_.Add(values_[i]->Copy());
   }
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 644cb99..0c5b53b 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -38,48 +38,48 @@
 // (class-name, function-name, recognized enum, fingerprint).
 // See intrinsifier for fingerprint computation.
 #define RECOGNIZED_LIST(V)                                                     \
-  V(::, identical, ObjectIdentical, 101186973)                                 \
+  V(::, identical, ObjectIdentical, 496869842)                                 \
   V(Object, Object., ObjectConstructor, 1058525712)                            \
-  V(Object, get:_cid, ObjectCid, 2099568593)                                   \
-  V(_ObjectArray, get:length, ObjectArrayLength, 1441000484)                   \
-  V(_ImmutableArray, get:length, ImmutableArrayLength, 1430953867)             \
-  V(_TypedList, get:length, TypedDataLength, 117589485)                        \
-  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 788387678)                     \
-  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 1137892349)                  \
-  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 464167270)                   \
-  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 673378812)                 \
-  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 1230275232)                  \
-  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 976951843)                 \
-  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 215932309)               \
-  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 450032954)               \
-  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1602836552)          \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 250049637)                     \
-  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 1792593311)                  \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 1958159284)                  \
-  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 1244907090)                \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 1058956549)                  \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1054500835)                \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1426038329)              \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 1289924817)              \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 370513644)           \
-  V(_GrowableObjectArray, get:length, GrowableArrayLength, 767561362)          \
-  V(_GrowableObjectArray, get:_capacity, GrowableArrayCapacity, 874559046)     \
-  V(_GrowableObjectArray, _setData, GrowableArraySetData, 1302055339)          \
-  V(_GrowableObjectArray, _setLength, GrowableArraySetLength, 1016226171)      \
-  V(_StringBase, get:length, StringBaseLength, 1158042795)                     \
+  V(Object, get:_cid, ObjectCid, 1498661928)                                   \
+  V(_ObjectArray, get:length, ObjectArrayLength, 259323113)                    \
+  V(_ImmutableArray, get:length, ImmutableArrayLength, 1341942416)             \
+  V(_TypedList, get:length, TypedDataLength, 26556746)                         \
+  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 272598802)                     \
+  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 831354841)                   \
+  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 1832126257)                  \
+  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 1762714698)                \
+  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 48785449)                    \
+  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 1392579206)                \
+  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 185163470)               \
+  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 1356392173)              \
+  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1239681356)          \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 742201367)                     \
+  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 1163140155)                  \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 1106354531)                  \
+  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 545390027)                 \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 1963924310)                  \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 724748139)                 \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 756330666)               \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 1495546688)              \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 560495357)           \
+  V(_GrowableObjectArray, get:length, GrowableArrayLength, 1160357614)         \
+  V(_GrowableObjectArray, get:_capacity, GrowableArrayCapacity, 1509781988)    \
+  V(_GrowableObjectArray, _setData, GrowableArraySetData, 236295352)           \
+  V(_GrowableObjectArray, _setLength, GrowableArraySetLength, 1922121178)      \
+  V(_StringBase, get:length, StringBaseLength, 1483460481)                     \
   V(_StringBase, get:isEmpty, StringBaseIsEmpty, 1588094430)                   \
-  V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 1452213966)                 \
-  V(_StringBase, [], StringBaseCharAt, 924930519)                              \
-  V(_OneByteString, _setAt, OneByteStringSetAt, 456985263)                     \
+  V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 1958436584)                 \
+  V(_StringBase, [], StringBaseCharAt, 539412735)                              \
+  V(_OneByteString, _setAt, OneByteStringSetAt, 1754827784)                    \
   V(_IntegerImplementation, toDouble, IntegerToDouble, 2141284842)             \
   V(_IntegerImplementation, _leftShiftWithMask32, IntegerLeftShiftWithMask32,  \
-      964472615)                                                               \
-  V(_Double, toInt, DoubleToInteger, 1580473283)                               \
-  V(_Double, truncateToDouble, DoubleTruncate, 849350203)                      \
-  V(_Double, roundToDouble, DoubleRound, 500368418)                            \
-  V(_Double, floorToDouble, DoubleFloor, 763548522)                            \
-  V(_Double, ceilToDouble, DoubleCeil, 976697019)                              \
-  V(_Double, _modulo, DoubleMod, 1850917533)                                   \
+      2095943661)                                                              \
+  V(_Double, toInt, DoubleToInteger, 1328149975)                               \
+  V(_Double, truncateToDouble, DoubleTruncate, 615732263)                      \
+  V(_Double, roundToDouble, DoubleRound, 622146406)                            \
+  V(_Double, floorToDouble, DoubleFloor, 1614014643)                           \
+  V(_Double, ceilToDouble, DoubleCeil, 277859570)                              \
+  V(_Double, _modulo, DoubleMod, 1443289156)                                   \
   V(::, sqrt, MathSqrt, 465520247)                                             \
   V(::, sin, MathSin, 730107143)                                               \
   V(::, cos, MathCos, 1282146521)                                              \
@@ -89,58 +89,58 @@
   V(Float32x4, Float32x4., Float32x4Constructor, 1876089990)                   \
   V(Float32x4, Float32x4.zero, Float32x4Zero, 1903586222)                      \
   V(Float32x4, Float32x4.splat, Float32x4Splat, 38462589)                      \
-  V(_Float32x4, shuffle, Float32x4Shuffle, 713523911)                          \
-  V(_Float32x4, get:x, Float32x4ShuffleX, 1019523296)                          \
-  V(_Float32x4, get:y, Float32x4ShuffleY, 710282243)                           \
-  V(_Float32x4, get:z, Float32x4ShuffleZ, 1612806041)                          \
-  V(_Float32x4, get:w, Float32x4ShuffleW, 1113701403)                          \
-  V(_Float32x4, get:signMask, Float32x4GetSignMask, 465347632)                 \
-  V(_Float32x4, _cmpequal, Float32x4Equal, 1559121703)                         \
-  V(_Float32x4, _cmpgt, Float32x4GreaterThan, 1959692892)                      \
-  V(_Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, 2128251808)              \
-  V(_Float32x4, _cmplt, Float32x4LessThan, 405464198)                          \
-  V(_Float32x4, _cmplte, Float32x4LessThanOrEqual, 1217836152)                 \
-  V(_Float32x4, _cmpnequal, Float32x4NotEqual, 498820440)                      \
-  V(_Float32x4, _min, Float32x4Min, 1354880316)                                \
-  V(_Float32x4, _max, Float32x4Max, 171574145)                                 \
-  V(_Float32x4, _scale, Float32x4Scale, 1553559438)                            \
-  V(_Float32x4, _sqrt, Float32x4Sqrt, 612006112)                               \
-  V(_Float32x4, _reciprocalSqrt, Float32x4ReciprocalSqrt, 606139302)           \
-  V(_Float32x4, _reciprocal, Float32x4Reciprocal, 606284658)                   \
-  V(_Float32x4, _negate, Float32x4Negate, 1391098465)                          \
-  V(_Float32x4, _abs, Float32x4Absolute, 1255666131)                           \
-  V(_Float32x4, _clamp, Float32x4Clamp, 736513790)                             \
-  V(_Float32x4, withX, Float32x4WithX, 1812990172)                             \
-  V(_Float32x4, withY, Float32x4WithY, 870795583)                              \
-  V(_Float32x4, withZ, Float32x4WithZ, 784227740)                              \
-  V(_Float32x4, withW, Float32x4WithW, 868173303)                              \
-  V(_Float32x4, _toUint32x4, Float32x4ToUint32x4, 147627074)                   \
-  V(_Float32x4, withZWInXY, Float32x4WithZWInXY, 1850941421)                   \
-  V(_Float32x4, interleaveXY, Float32x4InterleaveXY, 1789523505)               \
-  V(_Float32x4, interleaveZW, Float32x4InterleaveZW, 1137302773)               \
-  V(_Float32x4, interleaveXYPairs, Float32x4InterleaveXYPairs, 2138669236)     \
-  V(_Float32x4, interleaveZWPairs, Float32x4InterleaveZWPairs, 1541966446)     \
+  V(_Float32x4, shuffle, Float32x4Shuffle, 1178727105)                         \
+  V(_Float32x4, get:x, Float32x4ShuffleX, 1351658256)                          \
+  V(_Float32x4, get:y, Float32x4ShuffleY, 217326828)                           \
+  V(_Float32x4, get:z, Float32x4ShuffleZ, 2144864139)                          \
+  V(_Float32x4, get:w, Float32x4ShuffleW, 1447639537)                          \
+  V(_Float32x4, get:signMask, Float32x4GetSignMask, 1198789765)                \
+  V(_Float32x4, _cmpequal, Float32x4Equal, 2141256163)                         \
+  V(_Float32x4, _cmpgt, Float32x4GreaterThan, 696292270)                       \
+  V(_Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, 1199333164)              \
+  V(_Float32x4, _cmplt, Float32x4LessThan, 943396590)                          \
+  V(_Float32x4, _cmplte, Float32x4LessThanOrEqual, 57211241)                   \
+  V(_Float32x4, _cmpnequal, Float32x4NotEqual, 1234888884)                     \
+  V(_Float32x4, _min, Float32x4Min, 1166664658)                                \
+  V(_Float32x4, _max, Float32x4Max, 343968921)                                 \
+  V(_Float32x4, _scale, Float32x4Scale, 803505531)                             \
+  V(_Float32x4, _sqrt, Float32x4Sqrt, 2092250151)                              \
+  V(_Float32x4, _reciprocalSqrt, Float32x4ReciprocalSqrt, 965252704)           \
+  V(_Float32x4, _reciprocal, Float32x4Reciprocal, 1262202915)                  \
+  V(_Float32x4, _negate, Float32x4Negate, 1203192635)                          \
+  V(_Float32x4, _abs, Float32x4Absolute, 386324188)                            \
+  V(_Float32x4, _clamp, Float32x4Clamp, 1454612345)                            \
+  V(_Float32x4, withX, Float32x4WithX, 795284225)                              \
+  V(_Float32x4, withY, Float32x4WithY, 1806065938)                             \
+  V(_Float32x4, withZ, Float32x4WithZ, 320659034)                              \
+  V(_Float32x4, withW, Float32x4WithW, 1108437255)                             \
+  V(_Float32x4, _toUint32x4, Float32x4ToUint32x4, 754564339)                   \
+  V(_Float32x4, withZWInXY, Float32x4WithZWInXY, 1198101679)                   \
+  V(_Float32x4, interleaveXY, Float32x4InterleaveXY, 2001324072)               \
+  V(_Float32x4, interleaveZW, Float32x4InterleaveZW, 928280031)                \
+  V(_Float32x4, interleaveXYPairs, Float32x4InterleaveXYPairs, 1046078993)     \
+  V(_Float32x4, interleaveZWPairs, Float32x4InterleaveZWPairs, 1001751955)     \
   V(Uint32x4, Uint32x4.bool, Uint32x4BoolConstructor, 733327933)               \
-  V(_Uint32x4, get:flagX, Uint32x4GetFlagX, 765894409)                         \
-  V(_Uint32x4, get:flagY, Uint32x4GetFlagY, 1226233321)                        \
-  V(_Uint32x4, get:flagZ, Uint32x4GetFlagZ, 1455452476)                        \
-  V(_Uint32x4, get:flagW, Uint32x4GetFlagW, 1608549245)                        \
-  V(_Uint32x4, get:signMask, Uint32x4GetSignMask, 231202664)                   \
+  V(_Uint32x4, get:flagX, Uint32x4GetFlagX, 1674637210)                        \
+  V(_Uint32x4, get:flagY, Uint32x4GetFlagY, 2013140570)                        \
+  V(_Uint32x4, get:flagZ, Uint32x4GetFlagZ, 944674353)                         \
+  V(_Uint32x4, get:flagW, Uint32x4GetFlagW, 22686587)                          \
+  V(_Uint32x4, get:signMask, Uint32x4GetSignMask, 1858084501)                  \
   V(_Uint32x4, select, Uint32x4Select, 881590808)                              \
-  V(_Uint32x4, withFlagX, Uint32x4WithFlagX, 1987921054)                       \
-  V(_Uint32x4, withFlagY, Uint32x4WithFlagY, 831632614)                        \
-  V(_Uint32x4, withFlagZ, Uint32x4WithFlagZ, 465765612)                        \
-  V(_Uint32x4, withFlagW, Uint32x4WithFlagW, 1545009993)                       \
-  V(_Uint32x4, _toFloat32x4, Uint32x4ToUint32x4, 1545735523)                   \
+  V(_Uint32x4, withFlagX, Uint32x4WithFlagX, 1475542073)                       \
+  V(_Uint32x4, withFlagY, Uint32x4WithFlagY, 830610988)                        \
+  V(_Uint32x4, withFlagZ, Uint32x4WithFlagZ, 1714792414)                       \
+  V(_Uint32x4, withFlagW, Uint32x4WithFlagW, 1516924162)                       \
+  V(_Uint32x4, _toFloat32x4, Uint32x4ToUint32x4, 2054503505)                   \
 
 
 // A list of core function that should always be inlined.
 #define INLINE_WHITE_LIST(V)                                                   \
-  V(_ObjectArray, get:length, ObjectArrayLength, 1441000484)                   \
-  V(_ImmutableArray, get:length, ImmutableArrayLength, 1430953867)             \
-  V(_TypedList, get:length, TypedDataLength, 117589485)                        \
-  V(_GrowableObjectArray, get:length, GrowableArrayLength, 767561362)          \
-  V(_StringBase, get:length, StringBaseLength, 1158042795)                     \
+  V(_ObjectArray, get:length, ObjectArrayLength, 259323113)                    \
+  V(_ImmutableArray, get:length, ImmutableArrayLength, 1341942416)             \
+  V(_TypedList, get:length, TypedDataLength, 26556746)                         \
+  V(_GrowableObjectArray, get:length, GrowableArrayLength, 1160357614)         \
+  V(_StringBase, get:length, StringBaseLength, 1483460481)                     \
   V(ListIterator, moveNext, ListIteratorMoveNext, 657540761)                   \
   V(_GrowableObjectArray, get:iterator, GrowableArrayIterator, 281980741)      \
   V(_GrowableObjectArray, forEach, GrowableArrayForEach, 334448248)
@@ -1184,6 +1184,7 @@
   // entry point.
   bool PruneUnreachable(FlowGraphBuilder* builder,
                         GraphEntryInstr* graph_entry,
+                        Instruction* parent,
                         intptr_t osr_id,
                         BitVector* block_marks);
 
@@ -1349,6 +1350,9 @@
 
   bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; }
 
+  intptr_t entry_count() const { return entry_count_; }
+  void set_entry_count(intptr_t count) { entry_count_ = count; }
+
   intptr_t spill_slot_count() const { return spill_slot_count_; }
   void set_spill_slot_count(intptr_t count) {
     ASSERT(count >= 0);
@@ -1384,6 +1388,7 @@
   GrowableArray<CatchBlockEntryInstr*> catch_entries_;
   GrowableArray<Definition*> initial_definitions_;
   const intptr_t osr_id_;
+  intptr_t entry_count_;
   intptr_t spill_slot_count_;
   intptr_t fixed_slot_count_;  // For try-catch in optimized code.
 
@@ -1467,10 +1472,17 @@
 class TargetEntryInstr : public BlockEntryInstr {
  public:
   TargetEntryInstr(intptr_t block_id, intptr_t try_index)
-      : BlockEntryInstr(block_id, try_index), predecessor_(NULL) { }
+      : BlockEntryInstr(block_id, try_index),
+        predecessor_(NULL),
+        edge_weight_(0.0) {
+  }
 
   DECLARE_INSTRUCTION(TargetEntry)
 
+  double edge_weight() const { return edge_weight_; }
+  void set_edge_weight(double weight) { edge_weight_ = weight; }
+  void adjust_edge_weight(double scale_factor) { edge_weight_ *= scale_factor; }
+
   virtual intptr_t PredecessorCount() const {
     return (predecessor_ == NULL) ? 0 : 1;
   }
@@ -1491,6 +1503,7 @@
   }
 
   BlockEntryInstr* predecessor_;
+  double edge_weight_;
 
   DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
 };
@@ -1570,6 +1583,12 @@
   // Overridden by definitions that push arguments.
   virtual intptr_t ArgumentCount() const { return 0; }
 
+  // Overridden by definitions that have call counts.
+  virtual intptr_t CallCount() const {
+    UNREACHABLE();
+    return -1;
+  }
+
   intptr_t temp_index() const { return temp_index_; }
   void set_temp_index(intptr_t index) { temp_index_ = index; }
   void ClearTempIndex() { temp_index_ = -1; }
@@ -1987,7 +2006,9 @@
  public:
   explicit GotoInstr(JoinEntryInstr* entry)
     : successor_(entry),
-      parallel_move_(NULL) { }
+      edge_weight_(0.0),
+      parallel_move_(NULL) {
+  }
 
   DECLARE_INSTRUCTION(Goto)
 
@@ -1998,6 +2019,10 @@
   virtual intptr_t SuccessorCount() const;
   virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
 
+  double edge_weight() const { return edge_weight_; }
+  void set_edge_weight(double weight) { edge_weight_ = weight; }
+  void adjust_edge_weight(double scale_factor) { edge_weight_ *= scale_factor; }
+
   virtual bool CanBecomeDeoptimizationTarget() const {
     // Goto instruction can be used as a deoptimization target when LICM
     // hoists instructions out of the loop.
@@ -2029,6 +2054,7 @@
 
  private:
   JoinEntryInstr* successor_;
+  double edge_weight_;
 
   // Parallel move that will be used by linear scan register allocator to
   // connect live ranges at the end of the block and resolve phis.
@@ -2596,6 +2622,9 @@
     return (*arguments_)[index];
   }
 
+  // TODO(kmillikin): implement exact call counts for closure calls.
+  virtual intptr_t CallCount() const { return 1; }
+
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
   virtual bool CanDeoptimize() const { return true; }
@@ -2710,6 +2739,8 @@
 
   bool HasRecognizedTarget() const;
 
+  virtual intptr_t CallCount() const { return ic_data().AggregateCount(); }
+
   DECLARE_INSTRUCTION(PolymorphicInstanceCall)
 
   const ICData& ic_data() const { return ic_data_; }
@@ -3114,6 +3145,8 @@
     return (*arguments_)[index];
   }
 
+  virtual intptr_t CallCount() const { return ic_data()->AggregateCount(); }
+
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
   virtual bool CanDeoptimize() const { return true; }
@@ -6701,10 +6734,10 @@
         function_(function),
         outer_(outer) { }
 
-  // Deep copy the environment.  A 'length' parameter can be given, which
-  // may be less than the environment's length in order to drop values
-  // (e.g., passed arguments) from the copy.
-  Environment* DeepCopy() const;
+  // Deep copy an environment.  A 'length' parameter can be given, which may
+  // be less than the environment's length in order to drop values (e.g.,
+  // passed arguments) from the copy.
+  Environment* DeepCopy() const { return DeepCopy(Length()); }
   Environment* DeepCopy(intptr_t length) const;
 
   GrowableArray<Value*> values_;
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 830ade1..01f1c16 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -403,8 +403,8 @@
     // No need to update IC data.
     __ PopList((1 << R0) | (1 << R1));
     __ cmp(R0, ShifterOperand(R1));
-    __ LoadObject(R0, (kind == Token::kEQ) ? Bool::False() : Bool::True(), NE);
-    __ LoadObject(R0, (kind == Token::kEQ) ? Bool::True() : Bool::False(), EQ);
+    __ LoadObject(R0, Bool::Get(kind != Token::kEQ), NE);
+    __ LoadObject(R0, Bool::Get(kind == Token::kEQ), EQ);
     if (kind == Token::kNE) {
       // Skip not-equal result conversion.
       __ b(&equality_done);
@@ -588,10 +588,8 @@
   __ cmp(left, ShifterOperand(right));
   if (branch == NULL) {
     Register result = locs.out().reg();
-    __ LoadObject(result,
-                  (kind == Token::kEQ) ? Bool::True() : Bool::False(), EQ);
-    __ LoadObject(result,
-                  (kind == Token::kEQ) ? Bool::False() : Bool::True(), NE);
+    __ LoadObject(result, Bool::Get(kind == Token::kEQ), EQ);
+    __ LoadObject(result, Bool::Get(kind != Token::kEQ), NE);
   } else {
     Condition cond = TokenKindToSmiCondition(kind);
     branch->EmitBranchOnCondition(compiler, cond);
@@ -4132,6 +4130,10 @@
   if (InputCount() == 2) {
     result->set_in(1, Location::FpuRegisterLocation(Q1));
   }
+  if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
+    result->AddTemp(Location::RegisterLocation(R2));
+    result->AddTemp(Location::FpuRegisterLocation(Q2));
+  }
   result->set_out(Location::FpuRegisterLocation(Q0));
   return result;
 }
@@ -4141,14 +4143,37 @@
   // For pow-function return NaN if exponent is NaN.
   Label do_call, skip_call;
   if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
+    // Pseudo code:
+    // if (exponent == 0.0) return 0.0;
+    // if (base == 1.0) return 1.0;
+    // if (base.isNaN || exponent.isNaN) {
+    //    return double.NAN;
+    // }
+    DRegister base = EvenDRegisterOf(locs()->in(0).fpu_reg());
     DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg());
     DRegister result = EvenDRegisterOf(locs()->out().fpu_reg());
-    __ vcmpd(exp, exp);
+    Register temp = locs()->temp(0).reg();
+    DRegister saved_base = EvenDRegisterOf(locs()->temp(1).fpu_reg());
+    ASSERT((base == result) && (result != saved_base));
+    Label check_base_is_one;
+    // Check if exponent is 0.0 -> return 1.0;
+    __ vmovd(saved_base, base);
+    __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)));
+    __ LoadDFromOffset(DTMP, temp, Double::value_offset() - kHeapObjectTag);
+    __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)));
+    __ LoadDFromOffset(result, temp, Double::value_offset() - kHeapObjectTag);
+    __ vcmpd(exp, DTMP);
     __ vmstat();
-    __ b(&do_call, VC);  // NaN -> false;
-    // Exponent is NaN, return NaN.
-    __ vmovd(result, exp);
-    __ b(&skip_call);
+    __ b(&check_base_is_one, VS);  // NaN -> not zero.
+    __ b(&skip_call, EQ);  // exp is 0.0, result is 1.0.
+
+    __ Bind(&check_base_is_one);
+    __ vcmpd(saved_base, result);
+    __ vmstat();
+    __ vmovd(result, saved_base, VS);  // base is NaN, return NaN.
+    __ b(&skip_call, VS);
+    __ b(&skip_call, EQ);  // base and result are 1.0.
+    __ vmovd(base, saved_base);  // Restore base.
   }
   __ Bind(&do_call);
   // We currently use 'hardfp' ('gnueabihf') rather than 'softfp'
@@ -4427,6 +4452,28 @@
 }
 
 
+void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ Bind(compiler->GetJumpLabel(this));
+  if (!compiler->is_optimizing()) {
+    compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+                                   deopt_id_,
+                                   Scanner::kDummyTokenIndex);
+    // Add an edge counter.
+    const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+    counter.SetAt(0, Smi::Handle(Smi::New(0)));
+    __ Comment("Edge counter");
+    __ LoadObject(R0, counter);
+    __ ldr(IP, FieldAddress(R0, Array::element_offset(0)));
+    __ adds(IP, IP, ShifterOperand(Smi::RawValue(1)));
+    __ LoadImmediate(IP, Smi::RawValue(Smi::kMaxValue), VS);  // If overflow.
+    __ str(IP, FieldAddress(R0, Array::element_offset(0)));
+  }
+  if (HasParallelMove()) {
+    compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
+  }
+}
+
+
 LocationSummary* GotoInstr::MakeLocationSummary() const {
   return new LocationSummary(0, 0, LocationSummary::kNoCall);
 }
@@ -4508,7 +4555,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 ? Bool::True() : Bool::False());
+    __ LoadObject(locs()->out().reg(), Bool::Get(result));
     return;
   }
   if (left.IsConstant()) {
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index a57cc42..31dbe54 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -355,10 +355,10 @@
     __ popl(EDX);
     __ cmpl(EAX, EDX);
     __ j(EQUAL, &is_true);
-    __ LoadObject(EAX, (kind == Token::kEQ) ? Bool::False() : Bool::True());
+    __ LoadObject(EAX, Bool::Get(kind != Token::kEQ));
     __ jmp(&equality_done);
     __ Bind(&is_true);
-    __ LoadObject(EAX, (kind == Token::kEQ) ? Bool::True() : Bool::False());
+    __ LoadObject(EAX, Bool::Get(kind == Token::kEQ));
     if (kind == Token::kNE) {
       // Skip not-equal result conversion.
       __ jmp(&equality_done);
@@ -535,10 +535,10 @@
     Register result = locs.out().reg();
     __ j(EQUAL, &is_equal, Assembler::kNearJump);
     // Not equal.
-    __ LoadObject(result, (kind == Token::kEQ) ? Bool::False() : Bool::True());
+    __ LoadObject(result, Bool::Get(kind != Token::kEQ));
     __ jmp(&done, Assembler::kNearJump);
     __ Bind(&is_equal);
-    __ LoadObject(result, (kind == Token::kEQ) ? Bool::True() : Bool::False());
+    __ LoadObject(result, Bool::Get(kind == Token::kEQ));
     __ Bind(&done);
   } else {
     Condition cond = TokenKindToSmiCondition(kind);
@@ -4188,7 +4188,11 @@
   if (InputCount() == 2) {
     result->set_in(1, Location::FpuRegisterLocation(XMM2));
   }
-  result->set_out(Location::FpuRegisterLocation(XMM1));
+  if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
+    result->AddTemp(Location::RegisterLocation(EAX));
+    result->AddTemp(Location::FpuRegisterLocation(XMM4));
+  }
+  result->set_out(Location::FpuRegisterLocation(XMM3));
   return result;
 }
 
@@ -4199,15 +4203,43 @@
   for (intptr_t i = 0; i < InputCount(); i++) {
     __ movsd(Address(ESP, kDoubleSize * i), locs()->in(i).fpu_reg());
   }
-  // For pow-function return NaN if exponent is NaN.
   Label do_call, skip_call;
   if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
+    // Pseudo code:
+    // if (exponent == 0.0) return 1.0;
+    // if (base == 1.0) return 1.0;
+    // if (base.isNaN || exponent.isNaN) {
+    //    return double.NAN;
+    // }
+    XmmRegister base = locs()->in(0).fpu_reg();
     XmmRegister exp = locs()->in(1).fpu_reg();
-    __ comisd(exp, exp);
-    __ j(PARITY_ODD, &do_call, Assembler::kNearJump);  // NaN -> false;
-    // Exponent is NaN, return NaN.
-    __ movsd(locs()->out().fpu_reg(), exp);
+    XmmRegister result = locs()->out().fpu_reg();
+    Register temp = locs()->temp(0).reg();
+    XmmRegister zero_temp = locs()->temp(1).fpu_reg();
+
+    Label check_base_is_one;
+    // Check if exponent is 0.0 -> return 1.0;
+    __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)));
+    __ movsd(zero_temp, FieldAddress(temp, Double::value_offset()));
+    __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)));
+    __ movsd(result, FieldAddress(temp, Double::value_offset()));
+    // 'result' contains 1.0.
+    __ comisd(exp, zero_temp);
+    __ j(PARITY_EVEN, &check_base_is_one, Assembler::kNearJump);  // NaN.
+    __ j(EQUAL, &skip_call, Assembler::kNearJump);  // exp is 0, result is 1.0.
+
+    Label base_is_nan;
+    __ Bind(&check_base_is_one);
+    __ comisd(base, result);
+    __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump);
+    __ j(EQUAL, &skip_call, Assembler::kNearJump);  // base and result are 1.0
+    __ jmp(&do_call, Assembler::kNearJump);
+
+    __ Bind(&base_is_nan);
+    // Returns NaN.
+    __ movsd(result, base);
     __ jmp(&skip_call, Assembler::kNearJump);
+    // exp is Nan case is handled correctly in the C-library.
   }
   __ Bind(&do_call);
   __ CallRuntime(TargetFunction());
@@ -4766,12 +4798,56 @@
 }
 
 
+void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ Bind(compiler->GetJumpLabel(this));
+  if (!compiler->is_optimizing()) {
+    compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+                                   deopt_id_,
+                                   Scanner::kDummyTokenIndex);
+    // Add an edge counter.
+    const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+    counter.SetAt(0, Smi::Handle(Smi::New(0)));
+    Label done;
+    __ Comment("Edge counter");
+    __ LoadObject(EAX, counter);
+    __ addl(FieldAddress(EAX, Array::element_offset(0)),
+            Immediate(Smi::RawValue(1)));
+    __ j(NO_OVERFLOW, &done);
+    __ movl(FieldAddress(EAX, Array::element_offset(0)),
+            Immediate(Smi::RawValue(Smi::kMaxValue)));
+    __ Bind(&done);
+  }
+  if (HasParallelMove()) {
+    compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
+  }
+}
+
+
 LocationSummary* GotoInstr::MakeLocationSummary() const {
   return new LocationSummary(0, 0, LocationSummary::kNoCall);
 }
 
 
 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  if (!compiler->is_optimizing()) {
+    // Add deoptimization descriptor for deoptimizing instructions that may
+    // be inserted before this instruction.
+    compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+                                   GetDeoptId(),
+                                   0);  // No token position.
+    // Add an edge counter.
+    const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+    counter.SetAt(0, Smi::Handle(Smi::New(0)));
+    Label done;
+    __ Comment("Edge counter");
+    __ LoadObject(EAX, counter);
+    __ addl(FieldAddress(EAX, Array::element_offset(0)),
+            Immediate(Smi::RawValue(1)));
+    __ j(NO_OVERFLOW, &done);
+    __ movl(FieldAddress(EAX, Array::element_offset(0)),
+            Immediate(Smi::RawValue(Smi::kMaxValue)));
+    __ Bind(&done);
+  }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
   }
@@ -4866,7 +4942,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 ? Bool::True() : Bool::False());
+    __ LoadObject(locs()->out().reg(), Bool::Get(result));
     return;
   }
   if (left.IsConstant()) {
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index d32428a..3d2f338 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -400,10 +400,10 @@
     __ lw(A0, Address(SP, 0 * kWordSize));
     __ addiu(SP, SP, Immediate(2 * kWordSize));
     __ beq(A1, A0, &is_true);
-    __ LoadObject(V0, (kind == Token::kEQ) ? Bool::False() : Bool::True());
+    __ LoadObject(V0, Bool::Get(kind != Token::kEQ));
     __ b(&equality_done);
     __ Bind(&is_true);
-    __ LoadObject(V0, (kind == Token::kEQ) ? Bool::True() : Bool::False());
+    __ LoadObject(V0, Bool::Get(kind == Token::kEQ));
     if (kind == Token::kNE) {
       // Skip not-equal result conversion.
       __ b(&equality_done);
@@ -620,12 +620,10 @@
     Register result = locs.out().reg();
     __ beq(CMPRES, ZR, &is_equal);
     // Not equal.
-    __ LoadObject(result,
-                  (kind == Token::kEQ) ? Bool::False() : Bool::True());
+    __ LoadObject(result, Bool::Get(kind != Token::kEQ));
     __ b(&done);
     __ Bind(&is_equal);
-    __ LoadObject(result,
-                  (kind == Token::kEQ) ? Bool::True() : Bool::False());
+    __ LoadObject(result, Bool::Get(kind == Token::kEQ));
     __ Bind(&done);
 
   } else {
@@ -3524,6 +3522,8 @@
 
 
 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary() const {
+  // Calling convetion on MIPS uses D6 and D7 to pass the first two
+  // double arguments.
   ASSERT((InputCount() == 1) || (InputCount() == 2));
   const intptr_t kNumTemps = 0;
   LocationSummary* result =
@@ -3541,11 +3541,39 @@
   // For pow-function return NaN if exponent is NaN.
   Label do_call, skip_call;
   if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
+    // Pseudo code:
+    // if (exponent == 0.0) return 0.0;
+    // if (base == 1.0) return 1.0;
+    // if (base.isNaN || exponent.isNaN) {
+    //    return double.NAN;
+    // }
+    DRegister base = locs()->in(0).fpu_reg();
     DRegister exp = locs()->in(1).fpu_reg();
+    DRegister result = locs()->out().fpu_reg();
+
+    Label check_base_is_one;
+
+    // Check if exponent is 0.0 -> return 1.0;
+    __ LoadObject(TMP, Double::ZoneHandle(Double::NewCanonical(0)));
+    __ LoadDFromOffset(DTMP, TMP, Double::value_offset() - kHeapObjectTag);
+    __ LoadObject(TMP, Double::ZoneHandle(Double::NewCanonical(1)));
+    __ LoadDFromOffset(result, TMP, Double::value_offset() - kHeapObjectTag);
+    // 'result' contains 1.0.
     __ cund(exp, exp);
-    __ bc1f(&do_call);
-    // Exponent is NaN, return NaN.
-    __ movd(locs()->out().fpu_reg(), exp);
+    __ bc1t(&check_base_is_one);  // NaN -> not zero.
+    __ ceqd(exp, DTMP);
+    __ bc1t(&skip_call);  // exp is 0.0, result is 1.0.
+
+    Label base_is_nan;
+    __ Bind(&check_base_is_one);
+    __ cund(base, base);
+    __ bc1t(&base_is_nan);
+    __ ceqd(base, result);
+    __ bc1t(&skip_call);  // base and result are 1.0.
+    __ b(&do_call);
+
+    __ Bind(&base_is_nan);
+    __ movd(result, base);  // base is NaN, return NaN.
     __ b(&skip_call);
   }
   __ Bind(&do_call);
@@ -3820,6 +3848,32 @@
 }
 
 
+void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ Bind(compiler->GetJumpLabel(this));
+  if (!compiler->is_optimizing()) {
+    compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+                                   deopt_id_,
+                                   Scanner::kDummyTokenIndex);
+    // Add an edge counter.
+    const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+    counter.SetAt(0, Smi::Handle(Smi::New(0)));
+    Label done;
+    __ Comment("Edge counter");
+    __ LoadObject(T0, counter);
+    __ lw(T1, FieldAddress(T0, Array::element_offset(0)));
+    __ AddImmediateDetectOverflow(T1, T1, Smi::RawValue(1), CMPRES, T2);
+    __ bgez(CMPRES, &done);
+    __ delay_slot()->sw(T1, FieldAddress(T0, Array::element_offset(0)));
+    __ LoadImmediate(TMP1, Smi::RawValue(Smi::kMaxValue));
+    __ sw(TMP1, FieldAddress(T0, Array::element_offset(0)));  // If overflow.
+    __ Bind(&done);
+  }
+  if (HasParallelMove()) {
+    compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
+  }
+}
+
+
 LocationSummary* GotoInstr::MakeLocationSummary() const {
   return new LocationSummary(0, 0, LocationSummary::kNoCall);
 }
@@ -3924,7 +3978,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 ? Bool::True() : Bool::False());
+    __ LoadObject(locs()->out().reg(), Bool::Get(result));
     return;
   }
   if (left.IsConstant()) {
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index c5a1bf3..b5cc607 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -510,10 +510,10 @@
     __ popq(RDX);
     __ cmpq(RAX, RDX);
     __ j(EQUAL, &is_true);
-    __ LoadObject(RAX, (kind == Token::kEQ) ? Bool::False() : Bool::True());
+    __ LoadObject(RAX, Bool::Get(kind != Token::kEQ));
     __ jmp(&equality_done);
     __ Bind(&is_true);
-    __ LoadObject(RAX, (kind == Token::kEQ) ? Bool::True() : Bool::False());
+    __ LoadObject(RAX, Bool::Get(kind == Token::kEQ));
     if (kind == Token::kNE) {
       // Skip not-equal result conversion.
       __ jmp(&equality_done);
@@ -691,10 +691,10 @@
     Register result = locs.out().reg();
     __ j(EQUAL, &is_equal, Assembler::kNearJump);
     // Not equal.
-    __ LoadObject(result, (kind == Token::kEQ) ? Bool::False() : Bool::True());
+    __ LoadObject(result, Bool::Get(kind != Token::kEQ));
     __ jmp(&done, Assembler::kNearJump);
     __ Bind(&is_equal);
-    __ LoadObject(result, (kind == Token::kEQ) ? Bool::True() : Bool::False());
+    __ LoadObject(result, Bool::Get(kind == Token::kEQ));
     __ Bind(&done);
   } else {
     Condition cond = TokenKindToSmiCondition(kind);
@@ -4236,33 +4236,65 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* result =
       new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
-  result->set_in(0, Location::FpuRegisterLocation(XMM1));
+  result->set_in(0, Location::FpuRegisterLocation(XMM2));
   if (InputCount() == 2) {
-    result->set_in(1, Location::FpuRegisterLocation(XMM2));
+    result->set_in(1, Location::FpuRegisterLocation(XMM1));
   }
-  result->set_out(Location::FpuRegisterLocation(XMM1));
+  if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
+    result->AddTemp(Location::RegisterLocation(RAX));
+    result->AddTemp(Location::FpuRegisterLocation(XMM4));
+  }
+  result->set_out(Location::FpuRegisterLocation(XMM3));
   return result;
 }
 
 
 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(locs()->in(0).fpu_reg() == XMM1);
   __ EnterFrame(0);
   __ ReserveAlignedFrameSpace(0);
   __ movaps(XMM0, locs()->in(0).fpu_reg());
   if (InputCount() == 2) {
-    ASSERT(locs()->in(1).fpu_reg() == XMM2);
-    __ movaps(XMM1, locs()->in(1).fpu_reg());
+    ASSERT(locs()->in(1).fpu_reg() == XMM1);
   }
   // For pow-function return NaN if exponent is NaN.
   Label do_call, skip_call;
   if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
+    // Pseudo code:
+    // if (exponent == 0.0) return 0.0;
+    // if (base == 1.0) return 1.0;
+    // if (base.isNaN || exponent.isNaN) {
+    //    return double.NAN;
+    // }
+    XmmRegister base = locs()->in(0).fpu_reg();
     XmmRegister exp = locs()->in(1).fpu_reg();
-    __ comisd(exp, exp);
-    __ j(PARITY_ODD, &do_call, Assembler::kNearJump);  // NaN -> false;
-    // Exponent is NaN, return NaN.
-    __ movaps(locs()->out().fpu_reg(), exp);
+    XmmRegister result = locs()->out().fpu_reg();
+    Register temp = locs()->temp(0).reg();
+    XmmRegister zero_temp = locs()->temp(1).fpu_reg();
+
+    Label check_base_is_one;
+    // Check if exponent is 0.0 -> return 1.0;
+    __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)));
+    __ movsd(zero_temp, FieldAddress(temp, Double::value_offset()));
+    __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)));
+    __ movsd(result, FieldAddress(temp, Double::value_offset()));
+    // 'result' contains 1.0.
+    __ comisd(exp, zero_temp);
+    __ j(PARITY_EVEN, &check_base_is_one, Assembler::kNearJump);  // NaN.
+    __ j(EQUAL, &skip_call, Assembler::kNearJump);  // exp is 0, result is 1.0.
+
+    Label base_is_nan;
+    __ Bind(&check_base_is_one);
+    // Checks if base == 1.0.
+    __ comisd(base, result);
+    __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump);
+    __ j(EQUAL, &skip_call, Assembler::kNearJump);  // base and result are 1.0
+    __ jmp(&do_call, Assembler::kNearJump);
+
+    __ Bind(&base_is_nan);
+    // Returns NaN.
+    __ movsd(result, base);
     __ jmp(&skip_call, Assembler::kNearJump);
+    // exp is Nan case is handled correctly in the C-library.
   }
   __ Bind(&do_call);
   __ CallRuntime(TargetFunction());
@@ -4539,12 +4571,56 @@
 }
 
 
+void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ Bind(compiler->GetJumpLabel(this));
+  if (!compiler->is_optimizing()) {
+    compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+                                   deopt_id_,
+                                   Scanner::kDummyTokenIndex);
+    // Add an edge counter.
+    const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+    counter.SetAt(0, Smi::Handle(Smi::New(0)));
+    Label done;
+    __ Comment("Edge counter");
+    __ LoadObject(RAX, counter);
+    __ addq(FieldAddress(RAX, Array::element_offset(0)),
+            Immediate(Smi::RawValue(1)));
+    __ j(NO_OVERFLOW, &done);
+    __ movq(FieldAddress(RAX, Array::element_offset(0)),
+            Immediate(Smi::RawValue(Smi::kMaxValue)));
+    __ Bind(&done);
+  }
+  if (HasParallelMove()) {
+    compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
+  }
+}
+
+
 LocationSummary* GotoInstr::MakeLocationSummary() const {
   return new LocationSummary(0, 0, LocationSummary::kNoCall);
 }
 
 
 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  if (!compiler->is_optimizing()) {
+    // Add deoptimization descriptor for deoptimizing instructions that may
+    // be inserted before this instruction.
+    compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+                                   GetDeoptId(),
+                                   0);  // No token position.
+    // Add an edge counter.
+    const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+    counter.SetAt(0, Smi::Handle(Smi::New(0)));
+    Label done;
+    __ Comment("Edge counter");
+    __ LoadObject(RAX, counter);
+    __ addq(FieldAddress(RAX, Array::element_offset(0)),
+            Immediate(Smi::RawValue(1)));
+    __ j(NO_OVERFLOW, &done);
+    __ movq(FieldAddress(RAX, Array::element_offset(0)),
+            Immediate(Smi::RawValue(Smi::kMaxValue)));
+    __ Bind(&done);
+  }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
   }
@@ -4620,7 +4696,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 ? Bool::True() : Bool::False());
+    __ LoadObject(locs()->out().reg(), Bool::Get(result));
     return;
   }
   if (left.IsConstant()) {
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index 337b377..12c15ec 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -141,8 +141,8 @@
 }
 
 
-bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) {
-  if (!CanIntrinsify(function)) return false;
+void Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) {
+  if (!CanIntrinsify(function)) return;
 
   const char* function_name = String::Handle(function.name()).ToCString();
   const Class& function_class = Class::Handle(function.Owner());
@@ -167,8 +167,6 @@
   } else if (lib.raw() == Library::MathLibrary()) {
     MATH_LIB_INTRINSIC_LIST(FIND_INTRINSICS);
   }
-  return false;
-
 #undef FIND_INTRINSICS
 }
 
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index 0391beb..04d4199 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -16,7 +16,7 @@
 // When adding a new function for intrinsification add a 0 as fingerprint,
 // build and run to get the correct fingerprint from the mismatch error.
 #define CORE_LIB_INTRINSIC_LIST(V)                                             \
-  V(_Smi, ~, Smi_bitNegate, 824551298)                                         \
+  V(_Smi, ~, Smi_bitNegate, 635678453)                                         \
   V(_Double, >, Double_greaterThan, 1021232334)                                \
   V(_Double, >=, Double_greaterEqualThan, 324955595)                           \
   V(_Double, <, Double_lessThan, 978151157)                                    \
@@ -26,96 +26,96 @@
   V(_Double, -, Double_sub, 1180117486)                                        \
   V(_Double, *, Double_mul, 1999983053)                                        \
   V(_Double, /, Double_div, 1904009451)                                        \
-  V(_Double, get:isNaN, Double_getIsNaN, 266197199)                            \
-  V(_Double, get:isNegative, Double_getIsNegative, 264643149)                  \
+  V(_Double, get:isNaN, Double_getIsNaN, 916506740)                            \
+  V(_Double, get:isNegative, Double_getIsNegative, 1711332287)                 \
   V(_Double, _mulFromInteger, Double_mulFromInteger, 930284178)                \
-  V(_Double, .fromInteger, Double_fromInteger, 1488487599)                     \
-  V(_ObjectArray, ., ObjectArray_Allocate, 712468799)                          \
-  V(_ObjectArray, get:length, Array_getLength, 1441000484)                     \
-  V(_ObjectArray, [], Array_getIndexed, 658292540)                             \
-  V(_ObjectArray, []=, Array_setIndexed, 134661366)                            \
-  V(_GrowableObjectArray, .withData, GrowableArray_Allocate, 917195627)        \
-  V(_GrowableObjectArray, get:length, GrowableArray_getLength, 767561362)      \
-  V(_GrowableObjectArray, get:_capacity, GrowableArray_getCapacity, 874559046) \
-  V(_GrowableObjectArray, [], GrowableArray_getIndexed, 1020883940)            \
-  V(_GrowableObjectArray, []=, GrowableArray_setIndexed, 366077215)            \
-  V(_GrowableObjectArray, _setLength, GrowableArray_setLength, 1016226171)     \
-  V(_GrowableObjectArray, _setData, GrowableArray_setData, 1302055339)         \
+  V(_Double, .fromInteger, Double_fromInteger, 475441744)                      \
+  V(_ObjectArray, ., ObjectArray_Allocate, 1930677134)                         \
+  V(_ObjectArray, get:length, Array_getLength, 259323113)                      \
+  V(_ObjectArray, [], Array_getIndexed, 93386978)                              \
+  V(_ObjectArray, []=, Array_setIndexed, 1296046137)                           \
+  V(_GrowableObjectArray, .withData, GrowableArray_Allocate, 1012992871)       \
+  V(_GrowableObjectArray, get:length, GrowableArray_getLength, 1160357614)     \
+  V(_GrowableObjectArray, get:_capacity, GrowableArray_getCapacity, 1509781988)\
+  V(_GrowableObjectArray, [], GrowableArray_getIndexed, 500679426)             \
+  V(_GrowableObjectArray, []=, GrowableArray_setIndexed, 211112998)            \
+  V(_GrowableObjectArray, _setLength, GrowableArray_setLength, 1922121178)     \
+  V(_GrowableObjectArray, _setData, GrowableArray_setData, 236295352)          \
   V(_GrowableObjectArray, add, GrowableArray_add, 1442410650)                  \
-  V(_ImmutableArray, [], ImmutableArray_getIndexed, 1483706518)                \
-  V(_ImmutableArray, get:length, ImmutableArray_getLength, 1430953867)         \
+  V(_ImmutableArray, [], ImmutableArray_getIndexed, 894753724)                 \
+  V(_ImmutableArray, get:length, ImmutableArray_getLength, 1341942416)         \
   V(Object, ==, Object_equal, 677817295)                                       \
-  V(_StringBase, get:hashCode, String_getHashCode, 1654013013)                 \
+  V(_StringBase, get:hashCode, String_getHashCode, 654483446)                  \
   V(_StringBase, get:isEmpty, String_getIsEmpty, 1588094430)                   \
-  V(_StringBase, get:length, String_getLength, 1158042795)                     \
-  V(_StringBase, codeUnitAt, String_codeUnitAt, 1452213966)                    \
-  V(_OneByteString, get:hashCode, OneByteString_getHashCode, 1350708273)       \
+  V(_StringBase, get:length, String_getLength, 1483460481)                     \
+  V(_StringBase, codeUnitAt, String_codeUnitAt, 1958436584)                    \
+  V(_OneByteString, get:hashCode, OneByteString_getHashCode, 1236404434)       \
   V(_OneByteString, _substringUncheckedNative,                                 \
-      OneByteString_substringUnchecked, 1409543330)                            \
-  V(_OneByteString, _setAt, OneByteString_setAt, 456985263)                    \
-  V(_OneByteString, _allocate, OneByteString_allocate, 1842287414)             \
+      OneByteString_substringUnchecked, 25652388)                              \
+  V(_OneByteString, _setAt, OneByteString_setAt, 1754827784)                   \
+  V(_OneByteString, _allocate, OneByteString_allocate, 1064009711)             \
 
 
 #define CORE_INTEGER_LIB_INTRINSIC_LIST(V)                                     \
   V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger,           \
-    1061271878)                                                                \
+    740884607)                                                                 \
   V(_IntegerImplementation, +, Integer_add, 714540399)                         \
   V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger,           \
-    585090868)                                                                 \
+    584777821)                                                                 \
   V(_IntegerImplementation, -, Integer_sub, 1880284412)                        \
   V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger,           \
-    1145805333)                                                                \
+    1757603756)                                                                \
   V(_IntegerImplementation, *, Integer_mul, 1935440252)                        \
   V(_IntegerImplementation, remainder, Integer_remainder, 2140653009)          \
   V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger,     \
-    713610917)                                                                 \
+    1398988805)                                                                \
   V(_IntegerImplementation, ~/, Integer_truncDivide, 250357385)                \
   V(_IntegerImplementation, unary-, Integer_negate, 732448114)                 \
   V(_IntegerImplementation, _bitAndFromInteger,                                \
-    Integer_bitAndFromInteger, 1957162220)                                     \
+    Integer_bitAndFromInteger, 512285096)                                      \
   V(_IntegerImplementation, &, Integer_bitAnd, 1677634910)                     \
   V(_IntegerImplementation, _bitOrFromInteger,                                 \
-    Integer_bitOrFromInteger, 331026365)                                       \
+    Integer_bitOrFromInteger, 333543947)                                       \
   V(_IntegerImplementation, |, Integer_bitOr, 1062616305)                      \
   V(_IntegerImplementation, _bitXorFromInteger,                                \
-    Integer_bitXorFromInteger, 1884970526)                                     \
+    Integer_bitXorFromInteger, 1746295953)                                     \
   V(_IntegerImplementation, ^, Integer_bitXor, 2111001841)                     \
   V(_IntegerImplementation,                                                    \
     _greaterThanFromInteger,                                                   \
-    Integer_greaterThanFromInt, 1634594614)                                    \
+    Integer_greaterThanFromInt, 1883218996)                                    \
   V(_IntegerImplementation, >, Integer_greaterThan, 195542579)                 \
   V(_IntegerImplementation, ==, Integer_equal, 288044426)                      \
   V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger,           \
-    45967303)                                                                  \
+    111745915)                                                                 \
   V(_IntegerImplementation, <, Integer_lessThan, 1133694259)                   \
   V(_IntegerImplementation, <=, Integer_lessEqualThan, 1724243945)             \
   V(_IntegerImplementation, >=, Integer_greaterEqualThan, 879801865)           \
   V(_IntegerImplementation, <<, Integer_shl, 1508088336)                       \
   V(_IntegerImplementation, >>, Integer_sar, 1786839625)                       \
-  V(_Double, toInt, Double_toInt, 1580473283)
+  V(_Double, toInt, Double_toInt, 1328149975)
 
 
 #define MATH_LIB_INTRINSIC_LIST(V)                                             \
   V(::, sqrt, Math_sqrt, 465520247)                                            \
   V(::, sin, Math_sin, 730107143)                                              \
   V(::, cos, Math_cos, 1282146521)                                             \
-  V(_Random, _nextState, Random_nextState, 755413621)                          \
+  V(_Random, _nextState, Random_nextState, 1088413969)                         \
 
 
 #define TYPED_DATA_LIB_INTRINSIC_LIST(V)                                       \
-  V(_TypedList, get:length, TypedData_getLength, 117589485)                    \
-  V(_Int8Array, _new, TypedData_Int8Array_new, 1133705629)                     \
-  V(_Uint8Array, _new, TypedData_Uint8Array_new, 1643490889)                   \
-  V(_Uint8ClampedArray, _new, TypedData_Uint8ClampedArray_new, 1212601488)     \
-  V(_Int16Array, _new, TypedData_Int16Array_new, 1241260890)                   \
-  V(_Uint16Array, _new, TypedData_Uint16Array_new, 337798210)                  \
-  V(_Int32Array, _new, TypedData_Int32Array_new, 845463081)                    \
-  V(_Uint32Array, _new, TypedData_Uint32Array_new, 1406929599)                 \
-  V(_Int64Array, _new, TypedData_Int64Array_new, 408710474)                    \
-  V(_Uint64Array, _new, TypedData_Uint64Array_new, 202576356)                  \
-  V(_Float32Array, _new, TypedData_Float32Array_new, 224632748)                \
-  V(_Float64Array, _new, TypedData_Float64Array_new, 364786883)                \
-  V(_Float32x4Array, _new, TypedData_Float32x4Array_new, 255992094)            \
+  V(_TypedList, get:length, TypedData_getLength, 26556746)                     \
+  V(_Int8Array, _new, TypedData_Int8Array_new, 1145746295)                     \
+  V(_Uint8Array, _new, TypedData_Uint8Array_new, 1097983968)                   \
+  V(_Uint8ClampedArray, _new, TypedData_Uint8ClampedArray_new, 2036179275)     \
+  V(_Int16Array, _new, TypedData_Int16Array_new, 1550281862)                   \
+  V(_Uint16Array, _new, TypedData_Uint16Array_new, 381457023)                  \
+  V(_Int32Array, _new, TypedData_Int32Array_new, 1331503368)                   \
+  V(_Uint32Array, _new, TypedData_Uint32Array_new, 2068855037)                 \
+  V(_Int64Array, _new, TypedData_Int64Array_new, 2608399)                      \
+  V(_Uint64Array, _new, TypedData_Uint64Array_new, 1855520143)                 \
+  V(_Float32Array, _new, TypedData_Float32Array_new, 1251124964)               \
+  V(_Float64Array, _new, TypedData_Float64Array_new, 1439361428)               \
+  V(_Float32x4Array, _new, TypedData_Float32x4Array_new, 1902726893)           \
   V(_Int8Array, ., TypedData_Int8Array_factory, 1340298556)                    \
   V(_Uint8Array, ., TypedData_Uint8Array_factory, 1775618642)                  \
   V(_Uint8ClampedArray, ., TypedData_Uint8ClampedArray_factory, 264668024)     \
@@ -141,13 +141,13 @@
   // Try to intrinsify 'function'. Returns true if the function intrinsified
   // completely and the code does not need to be generated (i.e., no slow
   // path possible).
-  static bool Intrinsify(const Function& function, Assembler* assembler);
+  static void Intrinsify(const Function& function, Assembler* assembler);
   static bool CanIntrinsify(const Function& function);
   static void InitializeState();
 
  private:
 #define DECLARE_FUNCTION(test_class_name, test_function_name, destination, fp) \
-  static bool destination(Assembler* assembler);
+  static void destination(Assembler* assembler);
 
   CORE_LIB_INTRINSIC_LIST(DECLARE_FUNCTION)
   CORE_INTEGER_LIB_INTRINSIC_LIST(DECLARE_FUNCTION)
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 1a528f0..1050a0d 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -20,7 +20,7 @@
 
 #define __ assembler->
 
-bool Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
+void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
   const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
   const intptr_t kArrayLengthOffset = 0 * kWordSize;
   Label fall_through;
@@ -123,24 +123,22 @@
 
   __ Ret();  // Returns the newly allocated object in R0.
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Array_getLength(Assembler* assembler) {
+void Intrinsifier::Array_getLength(Assembler* assembler) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, Array::length_offset()));
   __ Ret();
-  return true;
 }
 
 
-bool Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
+void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
   return Array_getLength(assembler);
 }
 
 
-bool Intrinsifier::Array_getIndexed(Assembler* assembler) {
+void Intrinsifier::Array_getIndexed(Assembler* assembler) {
   Label fall_through;
 
   __ ldr(R0, Address(SP, + 0 * kWordSize));  // Index
@@ -159,11 +157,10 @@
   __ ldr(R0, FieldAddress(R6, Array::data_offset()), CC);
   __ bx(LR, CC);
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
   return Array_getIndexed(assembler);
 }
 
@@ -183,7 +180,7 @@
 
 // Intrinsify only for Smi value and index. Non-smi values need a store buffer
 // update. Array length is always a Smi.
-bool Intrinsifier::Array_setIndexed(Assembler* assembler) {
+void Intrinsifier::Array_setIndexed(Assembler* assembler) {
   Label fall_through;
 
   if (FLAG_enable_type_checks) {
@@ -245,13 +242,12 @@
   // Caller is responsible for preserving the value if necessary.
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Allocate a GrowableObjectArray using the backing array specified.
 // On stack: type argument (+1), data (+0).
-bool Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
   // The newly allocated object is returned in R0.
   const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
   const intptr_t kArrayOffset = 0 * kWordSize;
@@ -314,28 +310,25 @@
   __ Ret();  // Returns the newly allocated object in R0.
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
+void Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, GrowableObjectArray::length_offset()));
   __ Ret();
-  return true;
 }
 
 
-bool Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
+void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, GrowableObjectArray::data_offset()));
   __ ldr(R0, FieldAddress(R0, Array::length_offset()));
   __ Ret();
-  return true;
 }
 
 
-bool Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
   Label fall_through;
 
   __ ldr(R0, Address(SP, + 0 * kWordSize));  // Index
@@ -355,15 +348,14 @@
   __ ldr(R0, FieldAddress(R6, Array::data_offset()), CC);
   __ bx(LR, CC);
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Set value into growable object array at specified index.
 // On stack: growable array (+2), index (+1), value (+0).
-bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
-    return false;
+    return;
   }
   Label fall_through;
   __ ldr(R1, Address(SP, 1 * kWordSize));  // Index.
@@ -385,29 +377,27 @@
                      R2);
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Set length of growable object array. The length cannot
 // be greater than the length of the data container.
 // On stack: growable array (+1), length (+0).
-bool Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
+void Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
   __ ldr(R0, Address(SP, 1 * kWordSize));  // Growable array.
   __ ldr(R1, Address(SP, 0 * kWordSize));  // Length value.
   __ tst(R1, ShifterOperand(kSmiTagMask));  // Check for Smi.
   __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset()), EQ);
   __ bx(LR, EQ);
   // Fall through on non-Smi.
-  return false;
 }
 
 
 // Set data of growable object array.
 // On stack: growable array (+1), data (+0).
-bool Intrinsifier::GrowableArray_setData(Assembler* assembler) {
+void Intrinsifier::GrowableArray_setData(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
-    return false;
+    return;
   }
   Label fall_through;
   __ ldr(R1, Address(SP, 0 * kWordSize));  // Data.
@@ -422,16 +412,15 @@
                      R1);
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Add an element to growable array if it doesn't need to grow, otherwise
 // call into regular code.
 // On stack: growable array (+1), value (+0).
-bool Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableArray_add(Assembler* assembler) {
   // In checked mode we need to type-check the incoming argument.
-  if (FLAG_enable_type_checks) return false;
+  if (FLAG_enable_type_checks) return;
   Label fall_through;
   // R0: Array.
   __ ldr(R0, Address(SP, 1 * kWordSize));
@@ -458,7 +447,6 @@
   __ LoadImmediate(R0, raw_null);
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
@@ -547,11 +535,10 @@
 
 
 // Gets the length of a TypedData.
-bool Intrinsifier::TypedData_getLength(Assembler* assembler) {
+void Intrinsifier::TypedData_getLength(Assembler* assembler) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, TypedData::length_offset()));
   __ Ret();
-  return true;
 }
 
 
@@ -569,19 +556,17 @@
 
 
 #define TYPED_DATA_ALLOCATOR(clazz)                                            \
-bool Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) {             \
+void Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) {             \
   intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);       \
   intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid);           \
   int shift = GetScaleFactor(size);                                            \
   TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, shift);   \
-  return false;                                                                \
 }                                                                              \
-bool Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {         \
+void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {         \
   intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);       \
   intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid);           \
   int shift = GetScaleFactor(size);                                            \
   TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, shift);   \
-  return false;                                                                \
 }
 CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
 #undef TYPED_DATA_ALLOCATOR
@@ -599,45 +584,42 @@
 }
 
 
-bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);  // Checks two smis.
   __ adds(R0, R0, ShifterOperand(R1));  // Adds.
   __ bx(LR, VC);  // Return if no overflow.
   // Otherwise fall through.
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_add(Assembler* assembler) {
+void Intrinsifier::Integer_add(Assembler* assembler) {
   return Integer_addFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   __ subs(R0, R0, ShifterOperand(R1));  // Subtract.
   __ bx(LR, VC);  // Return if no overflow.
   // Otherwise fall through.
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_sub(Assembler* assembler) {
+void Intrinsifier::Integer_sub(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   __ subs(R0, R1, ShifterOperand(R0));  // Subtract.
   __ bx(LR, VC);  // Return if no overflow.
   // Otherwise fall through.
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
@@ -647,11 +629,10 @@
   __ cmp(IP, ShifterOperand(R0, ASR, 31));
   __ bx(LR, EQ);
   __ Bind(&fall_through);  // Fall through on overflow.
-  return false;
 }
 
 
-bool Intrinsifier::Integer_mul(Assembler* assembler) {
+void Intrinsifier::Integer_mul(Assembler* assembler) {
   return Integer_mulFromInteger(assembler);
 }
 
@@ -712,7 +693,7 @@
 //      res = res + right;
 //    }
 //  }
-bool Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
   // Check to see if we have integer division
   Label fall_through, subtract;
   __ ldr(R1, Address(SP, + 0 * kWordSize));
@@ -740,11 +721,10 @@
   __ Ret();
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_remainder(Assembler* assembler) {
+void Intrinsifier::Integer_remainder(Assembler* assembler) {
   // Check to see if we have integer division
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
@@ -759,11 +739,10 @@
   __ Ret();
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_truncDivide(Assembler* assembler) {
+void Intrinsifier::Integer_truncDivide(Assembler* assembler) {
   // Check to see if we have integer division
   Label fall_through;
 
@@ -782,11 +761,10 @@
   __ SmiTag(R0, NE);  // Not equal. Okay to tag and return.
   __ bx(LR, NE);  // Return.
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_negate(Assembler* assembler) {
+void Intrinsifier::Integer_negate(Assembler* assembler) {
   Label fall_through;
   __ ldr(R0, Address(SP, + 0 * kWordSize));  // Grab first argument.
   __ tst(R0, ShifterOperand(kSmiTagMask));  // Test for Smi.
@@ -795,11 +773,10 @@
   __ bx(LR, VC);  // Return if there wasn't overflow, fall through otherwise.
   // R0 is not a Smi. Fall through.
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
@@ -807,16 +784,15 @@
 
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitAnd(Assembler* assembler) {
+void Intrinsifier::Integer_bitAnd(Assembler* assembler) {
   return Integer_bitAndFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
@@ -824,16 +800,15 @@
 
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitOr(Assembler* assembler) {
+void Intrinsifier::Integer_bitOr(Assembler* assembler) {
   return Integer_bitOrFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
@@ -841,16 +816,15 @@
 
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitXor(Assembler* assembler) {
+void Intrinsifier::Integer_bitXor(Assembler* assembler) {
   return Integer_bitXorFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_shl(Assembler* assembler) {
+void Intrinsifier::Integer_shl(Assembler* assembler) {
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
   Label fall_through;
@@ -898,7 +872,6 @@
   __ str(R7, FieldAddress(R0, Mint::value_offset() + kWordSize));
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
@@ -929,7 +902,7 @@
 }
 
 
-static bool CompareIntegers(Assembler* assembler, Condition true_condition) {
+static void CompareIntegers(Assembler* assembler, Condition true_condition) {
   Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
   TestBothArgumentsSmis(assembler, &try_mint_smi);
   // R0 contains the right argument. R1 contains left argument
@@ -982,38 +955,37 @@
   __ b(&is_true);
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
+void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
   return CompareIntegers(assembler, LT);
 }
 
 
-bool Intrinsifier::Integer_lessThan(Assembler* assembler) {
+void Intrinsifier::Integer_lessThan(Assembler* assembler) {
   return Integer_greaterThanFromInt(assembler);
 }
 
 
-bool Intrinsifier::Integer_greaterThan(Assembler* assembler) {
+void Intrinsifier::Integer_greaterThan(Assembler* assembler) {
   return CompareIntegers(assembler, GT);
 }
 
 
-bool Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
+void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
   return CompareIntegers(assembler, LE);
 }
 
 
-bool Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
+void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
   return CompareIntegers(assembler, GE);
 }
 
 
 // This is called for Smi, Mint and Bigint receivers. The right argument
 // can be Smi, Mint, Bigint or double.
-bool Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
+void Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
   Label fall_through, true_label, check_for_mint;
   // For integer receiver '===' check first.
   __ ldr(R0, Address(SP, 0 * kWordSize));
@@ -1061,16 +1033,15 @@
   // TODO(srdjan): Implement Mint == Mint comparison.
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_equal(Assembler* assembler) {
+void Intrinsifier::Integer_equal(Assembler* assembler) {
   return Integer_equalToInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_sar(Assembler* assembler) {
+void Intrinsifier::Integer_sar(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);
@@ -1089,16 +1060,14 @@
   __ SmiTag(R0);
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Smi_bitNegate(Assembler* assembler) {
+void Intrinsifier::Smi_bitNegate(Assembler* assembler) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ mvn(R0, ShifterOperand(R0));
   __ bic(R0, R0, ShifterOperand(kSmiTagMask));  // Remove inverted smi-tag.
   __ Ret();
-  return true;
 }
 
 
@@ -1121,7 +1090,7 @@
 // type. Return true or false object in the register R0. Any NaN argument
 // 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) {
+static void CompareDoubles(Assembler* assembler, Condition true_condition) {
   Label fall_through, is_smi, double_op;
 
   TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
@@ -1146,38 +1115,37 @@
   __ vcvtdi(D1, S0);
   __ b(&double_op);  // Then do the comparison.
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_greaterThan(Assembler* assembler) {
+void Intrinsifier::Double_greaterThan(Assembler* assembler) {
   return CompareDoubles(assembler, HI);
 }
 
 
-bool Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
+void Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
   return CompareDoubles(assembler, CS);
 }
 
 
-bool Intrinsifier::Double_lessThan(Assembler* assembler) {
+void Intrinsifier::Double_lessThan(Assembler* assembler) {
   return CompareDoubles(assembler, CC);
 }
 
 
-bool Intrinsifier::Double_equal(Assembler* assembler) {
+void Intrinsifier::Double_equal(Assembler* assembler) {
   return CompareDoubles(assembler, EQ);
 }
 
 
-bool Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
+void Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
   return CompareDoubles(assembler, LS);
 }
 
 
 // Expects left argument to be double (receiver). Right argument is unknown.
 // Both arguments are on stack.
-static bool DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
+static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
   Label fall_through;
 
   TestLastArgumentIsDouble(assembler, &fall_through, &fall_through);
@@ -1198,32 +1166,31 @@
   __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_add(Assembler* assembler) {
+void Intrinsifier::Double_add(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kADD);
 }
 
 
-bool Intrinsifier::Double_mul(Assembler* assembler) {
+void Intrinsifier::Double_mul(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kMUL);
 }
 
 
-bool Intrinsifier::Double_sub(Assembler* assembler) {
+void Intrinsifier::Double_sub(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kSUB);
 }
 
 
-bool Intrinsifier::Double_div(Assembler* assembler) {
+void Intrinsifier::Double_div(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kDIV);
 }
 
 
 // Left is double right is integer (Bigint, Mint or Smi)
-bool Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
+void Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
   Label fall_through;
   // Only Smi-s allowed.
   __ ldr(R0, Address(SP, 0 * kWordSize));
@@ -1242,11 +1209,10 @@
   __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_fromInteger(Assembler* assembler) {
+void Intrinsifier::Double_fromInteger(Assembler* assembler) {
   Label fall_through;
 
   __ ldr(R0, Address(SP, 0 * kWordSize));
@@ -1262,11 +1228,10 @@
   __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_getIsNaN(Assembler* assembler) {
+void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
   Label is_true;
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
@@ -1275,11 +1240,10 @@
   __ LoadObject(R0, Bool::False(), VC);
   __ LoadObject(R0, Bool::True(), VS);
   __ Ret();
-  return true;
 }
 
 
-bool Intrinsifier::Double_getIsNegative(Assembler* assembler) {
+void Intrinsifier::Double_getIsNegative(Assembler* assembler) {
   Label is_false, is_true, is_zero;
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
@@ -1305,11 +1269,10 @@
   __ tst(R1, ShifterOperand(1));
   __ b(&is_true, NE);  // Sign bit set.
   __ b(&is_false);
-  return true;
 }
 
 
-bool Intrinsifier::Double_toInt(Assembler* assembler) {
+void Intrinsifier::Double_toInt(Assembler* assembler) {
   Label fall_through;
 
   __ ldr(R0, Address(SP, 0 * kWordSize));
@@ -1330,11 +1293,10 @@
   __ SmiTag(R0);
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Math_sqrt(Assembler* assembler) {
+void Intrinsifier::Math_sqrt(Assembler* assembler) {
   Label fall_through, is_smi, double_op;
   TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
   // Argument is double and is in R0.
@@ -1352,24 +1314,21 @@
   __ vcvtdi(D1, S0);
   __ b(&double_op);
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Math_sin(Assembler* assembler) {
-  return false;
+void Intrinsifier::Math_sin(Assembler* assembler) {
 }
 
 
-bool Intrinsifier::Math_cos(Assembler* assembler) {
-  return false;
+void Intrinsifier::Math_cos(Assembler* assembler) {
 }
 
 
 //    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
 //    _state[kSTATE_LO] = state & _MASK_32;
 //    _state[kSTATE_HI] = state >> 32;
-bool Intrinsifier::Random_nextState(Assembler* assembler) {
+void Intrinsifier::Random_nextState(Assembler* assembler) {
   const Library& math_lib = Library::Handle(Library::MathLibrary());
   ASSERT(!math_lib.IsNull());
   const Class& random_class = Class::Handle(
@@ -1408,39 +1367,35 @@
   __ StoreToOffset(kWord, R3, R1, disp_0 - kHeapObjectTag);
   __ StoreToOffset(kWord, R6, R1, disp_1 - kHeapObjectTag);
   __ Ret();
-  return true;
 }
 
 
-bool Intrinsifier::Object_equal(Assembler* assembler) {
+void Intrinsifier::Object_equal(Assembler* assembler) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R1, Address(SP, 1 * kWordSize));
   __ cmp(R0, ShifterOperand(R1));
   __ LoadObject(R0, Bool::False(), NE);
   __ LoadObject(R0, Bool::True(), EQ);
   __ Ret();
-  return true;
 }
 
 
-bool Intrinsifier::String_getHashCode(Assembler* assembler) {
+void Intrinsifier::String_getHashCode(Assembler* assembler) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, String::hash_offset()));
   __ cmp(R0, ShifterOperand(0));
   __ bx(LR, NE);  // Hash not yet computed.
-  return false;
 }
 
 
-bool Intrinsifier::String_getLength(Assembler* assembler) {
+void Intrinsifier::String_getLength(Assembler* assembler) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, String::length_offset()));
   __ Ret();
-  return true;
 }
 
 
-bool Intrinsifier::String_codeUnitAt(Assembler* assembler) {
+void Intrinsifier::String_codeUnitAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
 
   __ ldr(R1, Address(SP, 0 * kWordSize));  // Index.
@@ -1469,22 +1424,20 @@
   __ Ret();
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::String_getIsEmpty(Assembler* assembler) {
+void Intrinsifier::String_getIsEmpty(Assembler* assembler) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, String::length_offset()));
   __ cmp(R0, ShifterOperand(Smi::RawValue(0)));
   __ LoadObject(R0, Bool::True(), EQ);
   __ LoadObject(R0, Bool::False(), NE);
   __ Ret();
-  return false;
 }
 
 
-bool Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
+void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
   __ ldr(R1, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R1, String::hash_offset()));
   __ cmp(R0, ShifterOperand(0));
@@ -1540,7 +1493,6 @@
   __ SmiTag(R0);
   __ str(R0, FieldAddress(R1, String::hash_offset()));
   __ Ret();
-  return true;
 }
 
 
@@ -1623,7 +1575,7 @@
 // Arg1: Start index as Smi.
 // Arg2: End index as Smi.
 // The indexes must be valid.
-bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
+void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
   const intptr_t kStringOffset = 2 * kWordSize;
   const intptr_t kStartIndexOffset = 1 * kWordSize;
   const intptr_t kEndIndexOffset = 0 * kWordSize;
@@ -1672,11 +1624,10 @@
   __ Bind(&done);
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::OneByteString_setAt(Assembler* assembler) {
+void Intrinsifier::OneByteString_setAt(Assembler* assembler) {
   __ ldr(R2, Address(SP, 0 * kWordSize));  // Value.
   __ ldr(R1, Address(SP, 1 * kWordSize));  // Index.
   __ ldr(R0, Address(SP, 2 * kWordSize));  // OneByteString.
@@ -1685,11 +1636,10 @@
   __ AddImmediate(R3, R0, OneByteString::data_offset() - kHeapObjectTag);
   __ strb(R2, Address(R3, R1));
   __ Ret();
-  return true;
 }
 
 
-bool Intrinsifier::OneByteString_allocate(Assembler* assembler) {
+void Intrinsifier::OneByteString_allocate(Assembler* assembler) {
   __ ldr(R2, Address(SP, 0 * kWordSize));  // Length.
   Label fall_through, ok;
   TryAllocateOnebyteString(assembler, &ok, &fall_through);
@@ -1698,7 +1648,6 @@
   __ Ret();
 
   __ Bind(&fall_through);
-  return false;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index aac288d..2b9c95c 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -28,7 +28,7 @@
 
 #define __ assembler->
 
-bool Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
+void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
   // This snippet of inlined code uses the following registers:
   // EAX, EBX, EDI
   // and the newly allocated object is returned in EAX.
@@ -132,24 +132,22 @@
   __ ret();  // returns the newly allocated object in EAX.
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Array_getLength(Assembler* assembler) {
+void Intrinsifier::Array_getLength(Assembler* assembler) {
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
   __ movl(EAX, FieldAddress(EAX, Array::length_offset()));
   __ ret();
-  return true;
 }
 
 
-bool Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
+void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
   return Array_getLength(assembler);
 }
 
 
-bool Intrinsifier::Array_getIndexed(Assembler* assembler) {
+void Intrinsifier::Array_getIndexed(Assembler* assembler) {
   Label fall_through;
   __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Index.
   __ movl(EAX, Address(ESP, + 2 * kWordSize));  // Array.
@@ -164,11 +162,10 @@
   __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()));
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
   return Array_getIndexed(assembler);
 }
 
@@ -188,7 +185,7 @@
 
 // Intrinsify only for Smi value and index. Non-smi values need a store buffer
 // update. Array length is always a Smi.
-bool Intrinsifier::Array_setIndexed(Assembler* assembler) {
+void Intrinsifier::Array_setIndexed(Assembler* assembler) {
   Label fall_through;
   if (FLAG_enable_type_checks) {
     const intptr_t type_args_field_offset =
@@ -243,13 +240,12 @@
   // Caller is responsible of preserving the value if necessary.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Allocate a GrowableObjectArray using the backing array specified.
 // On stack: type argument (+2), data (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
   // This snippet of inlined code uses the following registers:
   // EAX, EBX
   // and the newly allocated object is returned in EAX.
@@ -311,34 +307,31 @@
   __ ret();  // returns the newly allocated object in EAX.
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Get length of growable object array.
 // On stack: growable array (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
+void Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
   __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
   __ ret();
-  return true;
 }
 
 
 // Get capacity of growable object array.
 // On stack: growable array (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
+void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
   __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset()));
   __ movl(EAX, FieldAddress(EAX, Array::length_offset()));
   __ ret();
-  return true;
 }
 
 
 // Access growable object array at specified index.
 // On stack: growable array (+2), index (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
   Label fall_through;
   __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Index.
   __ movl(EAX, Address(ESP, + 2 * kWordSize));  // GrowableArray.
@@ -355,15 +348,14 @@
   __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()));
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Set value into growable object array at specified index.
 // On stack: growable array (+3), index (+2), value (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
-    return false;
+    return;
   }
   Label fall_through;
   __ movl(EBX, Address(ESP, + 2 * kWordSize));  // Index.
@@ -383,14 +375,13 @@
                      EDI);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Set length of growable object array. The length cannot
 // be greater than the length of the data container.
 // On stack: growable array (+2), length (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
+void Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
   Label fall_through;
   __ movl(EAX, Address(ESP, + 2 * kWordSize));  // Growable array.
   __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Length value.
@@ -399,15 +390,14 @@
   __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), EBX);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Set data of growable object array.
 // On stack: growable array (+2), data (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_setData(Assembler* assembler) {
+void Intrinsifier::GrowableArray_setData(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
-    return false;
+    return;
   }
   Label fall_through;
   __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Data.
@@ -422,16 +412,16 @@
                      EBX);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Add an element to growable array if it doesn't need to grow, otherwise
 // call into regular code.
 // On stack: growable array (+2), value (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableArray_add(Assembler* assembler) {
   // In checked mode we need to type-check the incoming argument.
-  if (FLAG_enable_type_checks) return false;
+  if (FLAG_enable_type_checks) return;
+
   Label fall_through;
   __ movl(EAX, Address(ESP, + 2 * kWordSize));  // Array.
   __ movl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
@@ -455,7 +445,6 @@
   __ movl(EAX, raw_null);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
@@ -554,11 +543,10 @@
 
 
 // Gets the length of a TypedData.
-bool Intrinsifier::TypedData_getLength(Assembler* assembler) {
+void Intrinsifier::TypedData_getLength(Assembler* assembler) {
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
   __ movl(EAX, FieldAddress(EAX, TypedData::length_offset()));
   __ ret();
-  return true;
 }
 
 
@@ -576,19 +564,17 @@
 
 
 #define TYPED_DATA_ALLOCATOR(clazz)                                            \
-bool Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) {             \
+void Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) {             \
   intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);       \
   intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid);           \
   ScaleFactor scale = GetScaleFactor(size);                                    \
   TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale);   \
-  return false;                                                                \
 }                                                                              \
-bool Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {         \
+void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {         \
   intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);       \
   intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid);           \
   ScaleFactor scale = GetScaleFactor(size);                                    \
   TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale);   \
-  return false;                                                                \
 }
 CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
 #undef TYPED_DATA_ALLOCATOR
@@ -605,7 +591,7 @@
 }
 
 
-bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   __ addl(EAX, Address(ESP, + 2 * kWordSize));
@@ -613,16 +599,15 @@
   // Result is in EAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_add(Assembler* assembler) {
+void Intrinsifier::Integer_add(Assembler* assembler) {
   return Integer_addFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   __ subl(EAX, Address(ESP, + 2 * kWordSize));
@@ -630,11 +615,10 @@
   // Result is in EAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_sub(Assembler* assembler) {
+void Intrinsifier::Integer_sub(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   __ movl(EBX, EAX);
@@ -644,12 +628,11 @@
   // Result is in EAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 
-bool Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   ASSERT(kSmiTag == 0);  // Adjust code below if not the case.
@@ -659,11 +642,10 @@
   // Result is in EAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_mul(Assembler* assembler) {
+void Intrinsifier::Integer_mul(Assembler* assembler) {
   return Integer_mulFromInteger(assembler);
 }
 
@@ -715,7 +697,7 @@
 //      res = res + right;
 //    }
 //  }
-bool Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
   Label fall_through, subtract;
   TestBothArgumentsSmis(assembler, &fall_through);
   __ movl(EBX, Address(ESP, + 2 * kWordSize));
@@ -746,11 +728,10 @@
   __ ret();
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_remainder(Assembler* assembler) {
+void Intrinsifier::Integer_remainder(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // EAX: right argument (divisor)
@@ -768,11 +749,10 @@
   __ ret();
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_truncDivide(Assembler* assembler) {
+void Intrinsifier::Integer_truncDivide(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // EAX: right argument (divisor)
@@ -793,11 +773,10 @@
   __ SmiTag(EAX);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_negate(Assembler* assembler) {
+void Intrinsifier::Integer_negate(Assembler* assembler) {
   Label fall_through;
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
   __ testl(EAX, Immediate(kSmiTagMask));
@@ -807,11 +786,10 @@
   // Result is in EAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   __ movl(EBX, Address(ESP, + 2 * kWordSize));
@@ -819,16 +797,15 @@
   // Result is in EAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitAnd(Assembler* assembler) {
+void Intrinsifier::Integer_bitAnd(Assembler* assembler) {
   return Integer_bitAndFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   __ movl(EBX, Address(ESP, + 2 * kWordSize));
@@ -836,16 +813,15 @@
   // Result is in EAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitOr(Assembler* assembler) {
+void Intrinsifier::Integer_bitOr(Assembler* assembler) {
   return Integer_bitOrFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   __ movl(EBX, Address(ESP, + 2 * kWordSize));
@@ -853,16 +829,15 @@
   // Result is in EAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitXor(Assembler* assembler) {
+void Intrinsifier::Integer_bitXor(Assembler* assembler) {
   return Integer_bitXorFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_shl(Assembler* assembler) {
+void Intrinsifier::Integer_shl(Assembler* assembler) {
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
   Label fall_through, overflow;
@@ -909,7 +884,6 @@
   __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
@@ -937,7 +911,7 @@
 }
 
 
-static bool CompareIntegers(Assembler* assembler, Condition true_condition) {
+static void CompareIntegers(Assembler* assembler, Condition true_condition) {
   Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
   TestBothArgumentsSmis(assembler, &try_mint_smi);
   // EAX contains the right argument.
@@ -993,39 +967,38 @@
   __ Bind(&drop_two_fall_through);
   __ Drop(2);
   __ Bind(&fall_through);
-  return false;
 }
 
 
 
-bool Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
+void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
   return CompareIntegers(assembler, LESS);
 }
 
 
-bool Intrinsifier::Integer_lessThan(Assembler* assembler) {
+void Intrinsifier::Integer_lessThan(Assembler* assembler) {
   return Integer_greaterThanFromInt(assembler);
 }
 
 
-bool Intrinsifier::Integer_greaterThan(Assembler* assembler) {
+void Intrinsifier::Integer_greaterThan(Assembler* assembler) {
   return CompareIntegers(assembler, GREATER);
 }
 
 
-bool Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
+void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
   return CompareIntegers(assembler, LESS_EQUAL);
 }
 
 
-bool Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
+void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
   return CompareIntegers(assembler, GREATER_EQUAL);
 }
 
 
 // This is called for Smi, Mint and Bigint receivers. The right argument
 // can be Smi, Mint, Bigint or double.
-bool Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
+void Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
   Label fall_through, true_label, check_for_mint;
   // For integer receiver '===' check first.
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
@@ -1071,16 +1044,15 @@
   // TODO(srdjan): Implement Mint == Mint comparison.
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_equal(Assembler* assembler) {
+void Intrinsifier::Integer_equal(Assembler* assembler) {
   return Integer_equalToInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_sar(Assembler* assembler) {
+void Intrinsifier::Integer_sar(Assembler* assembler) {
   Label fall_through, shift_count_ok;
   TestBothArgumentsSmis(assembler, &fall_through);
   // Can destroy ECX since we are not falling through.
@@ -1103,17 +1075,15 @@
   __ SmiTag(EAX);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Argument is Smi (receiver).
-bool Intrinsifier::Smi_bitNegate(Assembler* assembler) {
+void Intrinsifier::Smi_bitNegate(Assembler* assembler) {
   __ movl(EAX, Address(ESP, + 1 * kWordSize));  // Index.
   __ notl(EAX);
   __ andl(EAX, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
   __ ret();
-  return true;
 }
 
 
@@ -1136,7 +1106,7 @@
 // type. Return true or false object in the register EAX. Any NaN argument
 // 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) {
+static void CompareDoubles(Assembler* assembler, Condition true_condition) {
   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.
@@ -1159,43 +1129,42 @@
   __ cvtsi2sd(XMM1, EAX);
   __ jmp(&double_op);
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // arg0 is Double, arg1 is unknown.
-bool Intrinsifier::Double_greaterThan(Assembler* assembler) {
+void Intrinsifier::Double_greaterThan(Assembler* assembler) {
   return CompareDoubles(assembler, ABOVE);
 }
 
 
 // arg0 is Double, arg1 is unknown.
-bool Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
+void Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
   return CompareDoubles(assembler, ABOVE_EQUAL);
 }
 
 
 // arg0 is Double, arg1 is unknown.
-bool Intrinsifier::Double_lessThan(Assembler* assembler) {
+void Intrinsifier::Double_lessThan(Assembler* assembler) {
   return CompareDoubles(assembler, BELOW);
 }
 
 
 // arg0 is Double, arg1 is unknown.
-bool Intrinsifier::Double_equal(Assembler* assembler) {
+void Intrinsifier::Double_equal(Assembler* assembler) {
   return CompareDoubles(assembler, EQUAL);
 }
 
 
 // arg0 is Double, arg1 is unknown.
-bool Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
+void Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
   return CompareDoubles(assembler, BELOW_EQUAL);
 }
 
 
 // Expects left argument to be double (receiver). Right argument is unknown.
 // Both arguments are on stack.
-static bool DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
+static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
   Label fall_through;
   TestLastArgumentIsDouble(assembler, &fall_through, &fall_through);
   // Both arguments are double, right operand is in EAX.
@@ -1218,32 +1187,31 @@
   __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_add(Assembler* assembler) {
+void Intrinsifier::Double_add(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kADD);
 }
 
 
-bool Intrinsifier::Double_mul(Assembler* assembler) {
+void Intrinsifier::Double_mul(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kMUL);
 }
 
 
-bool Intrinsifier::Double_sub(Assembler* assembler) {
+void Intrinsifier::Double_sub(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kSUB);
 }
 
 
-bool Intrinsifier::Double_div(Assembler* assembler) {
+void Intrinsifier::Double_div(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kDIV);
 }
 
 
 // Left is double right is integer (Bigint, Mint or Smi)
-bool Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
+void Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
   Label fall_through;
   // Only Smi-s allowed.
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
@@ -1264,11 +1232,10 @@
   __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_fromInteger(Assembler* assembler) {
+void Intrinsifier::Double_fromInteger(Assembler* assembler) {
   Label fall_through;
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ testl(EAX, Immediate(kSmiTagMask));
@@ -1285,11 +1252,10 @@
   __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_getIsNaN(Assembler* assembler) {
+void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
   Label is_true;
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
@@ -1300,11 +1266,10 @@
   __ Bind(&is_true);
   __ LoadObject(EAX, Bool::True());
   __ ret();
-  return true;  // Method is complete, no slow case.
 }
 
 
-bool Intrinsifier::Double_getIsNegative(Assembler* assembler) {
+void Intrinsifier::Double_getIsNegative(Assembler* assembler) {
   Label is_false, is_true, is_zero;
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
@@ -1325,11 +1290,10 @@
   __ testl(EAX, Immediate(1));
   __ j(NOT_ZERO, &is_true, Assembler::kNearJump);
   __ jmp(&is_false, Assembler::kNearJump);
-  return true;  // Method is complete, no slow case.
 }
 
 
-bool Intrinsifier::Double_toInt(Assembler* assembler) {
+void Intrinsifier::Double_toInt(Assembler* assembler) {
   __ movl(EAX, Address(ESP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
   __ cvttsd2si(EAX, XMM0);
@@ -1341,12 +1305,11 @@
   __ SmiTag(EAX);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Argument type is not known
-bool Intrinsifier::Math_sqrt(Assembler* assembler) {
+void Intrinsifier::Math_sqrt(Assembler* assembler) {
   Label fall_through, is_smi, double_op;
   TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
   // Argument is double and is in EAX.
@@ -1366,7 +1329,6 @@
   __ cvtsi2sd(XMM1, EAX);
   __ jmp(&double_op);
   __ Bind(&fall_through);
-  return false;
 }
 
 
@@ -1414,22 +1376,20 @@
 }
 
 
-bool Intrinsifier::Math_sin(Assembler* assembler) {
+void Intrinsifier::Math_sin(Assembler* assembler) {
   EmitTrigonometric(assembler, kSine);
-  return false;  // Compile method for slow case.
 }
 
 
-bool Intrinsifier::Math_cos(Assembler* assembler) {
+void Intrinsifier::Math_cos(Assembler* assembler) {
   EmitTrigonometric(assembler, kCosine);
-  return false;  // Compile method for slow case.
 }
 
 
 //    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
 //    _state[kSTATE_LO] = state & _MASK_32;
 //    _state[kSTATE_HI] = state >> 32;
-bool Intrinsifier::Random_nextState(Assembler* assembler) {
+void Intrinsifier::Random_nextState(Assembler* assembler) {
   const Library& math_lib = Library::Handle(Library::MathLibrary());
   ASSERT(!math_lib.IsNull());
   const Class& random_class = Class::Handle(
@@ -1468,12 +1428,11 @@
   __ movl(addr_1, EDX);
   __ movl(addr_0, EAX);
   __ ret();
-  return true;
 }
 
 
 // Identity comparison.
-bool Intrinsifier::Object_equal(Assembler* assembler) {
+void Intrinsifier::Object_equal(Assembler* assembler) {
   Label is_true;
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
   __ cmpl(EAX, Address(ESP, + 2 * kWordSize));
@@ -1483,11 +1442,10 @@
   __ Bind(&is_true);
   __ LoadObject(EAX, Bool::True());
   __ ret();
-  return true;
 }
 
 
-bool Intrinsifier::String_getHashCode(Assembler* assembler) {
+void Intrinsifier::String_getHashCode(Assembler* assembler) {
   Label fall_through;
   __ movl(EAX, Address(ESP, + 1 * kWordSize));  // String object.
   __ movl(EAX, FieldAddress(EAX, String::hash_offset()));
@@ -1496,19 +1454,17 @@
   __ ret();
   __ Bind(&fall_through);
   // Hash not yet computed.
-  return false;
 }
 
 
-bool Intrinsifier::String_getLength(Assembler* assembler) {
+void Intrinsifier::String_getLength(Assembler* assembler) {
   __ movl(EAX, Address(ESP, + 1 * kWordSize));  // String object.
   __ movl(EAX, FieldAddress(EAX, String::length_offset()));
   __ ret();
-  return true;
 }
 
 
-bool Intrinsifier::String_codeUnitAt(Assembler* assembler) {
+void Intrinsifier::String_codeUnitAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
   __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Index.
   __ movl(EAX, Address(ESP, + 2 * kWordSize));  // String.
@@ -1534,11 +1490,10 @@
   __ ret();
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::String_getIsEmpty(Assembler* assembler) {
+void Intrinsifier::String_getIsEmpty(Assembler* assembler) {
   Label is_true;
   // Get length.
   __ movl(EAX, Address(ESP, + 1 * kWordSize));  // String object.
@@ -1550,11 +1505,10 @@
   __ Bind(&is_true);
   __ LoadObject(EAX, Bool::True());
   __ ret();
-  return false;
 }
 
 
-bool Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
+void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
   Label compute_hash;
   __ movl(EBX, Address(ESP, + 1 * kWordSize));  // OneByteString object.
   __ movl(EAX, FieldAddress(EBX, String::hash_offset()));
@@ -1620,7 +1574,6 @@
   __ SmiTag(EAX);
   __ movl(FieldAddress(EBX, String::hash_offset()), EAX);
   __ ret();
-  return true;
 }
 
 
@@ -1704,7 +1657,7 @@
 // Arg1: Start index as Smi.
 // Arg2: End index as Smi.
 // The indexes must be valid.
-bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
+void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
   const intptr_t kStringOffset = 3 * kWordSize;
   const intptr_t kStartIndexOffset = 2 * kWordSize;
   const intptr_t kEndIndexOffset = 1 * kWordSize;
@@ -1741,11 +1694,10 @@
   __ j(LESS, &loop, Assembler::kNearJump);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::OneByteString_setAt(Assembler* assembler) {
+void Intrinsifier::OneByteString_setAt(Assembler* assembler) {
   __ movl(ECX, Address(ESP, + 1 * kWordSize));  // Value.
   __ movl(EBX, Address(ESP, + 2 * kWordSize));  // Index.
   __ movl(EAX, Address(ESP, + 3 * kWordSize));  // OneByteString.
@@ -1753,11 +1705,10 @@
   __ SmiUntag(ECX);
   __ movb(FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()), CL);
   __ ret();
-  return true;
 }
 
 
-bool Intrinsifier::OneByteString_allocate(Assembler* assembler) {
+void Intrinsifier::OneByteString_allocate(Assembler* assembler) {
   __ movl(EDI, Address(ESP, + 1 * kWordSize));  // Length.
   Label fall_through, ok;
   TryAllocateOnebyteString(assembler, &ok, &fall_through, EDI);
@@ -1767,7 +1718,6 @@
   __ ret();
 
   __ Bind(&fall_through);
-  return false;
 }
 
 #undef __
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index 81dacc7..44c895f 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -20,7 +20,7 @@
 
 #define __ assembler->
 
-bool Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
+void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
   const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
   const intptr_t kArrayLengthOffset = 0 * kWordSize;
   Label fall_through;
@@ -130,24 +130,22 @@
   __ Ret();  // Returns the newly allocated object in V0.
   __ delay_slot()->mov(V0, T0);
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Array_getLength(Assembler* assembler) {
+void Intrinsifier::Array_getLength(Assembler* assembler) {
   __ lw(V0, Address(SP, 0 * kWordSize));
   __ Ret();
   __ delay_slot()->lw(V0, FieldAddress(V0, Array::length_offset()));
-  return true;
 }
 
 
-bool Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
+void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
   return Array_getLength(assembler);
 }
 
 
-bool Intrinsifier::Array_getIndexed(Assembler* assembler) {
+void Intrinsifier::Array_getIndexed(Assembler* assembler) {
   Label fall_through;
 
   __ lw(T0, Address(SP, + 0 * kWordSize));  // Index
@@ -167,11 +165,10 @@
   __ Ret();
   __ delay_slot()->lw(V0, FieldAddress(T2, Array::data_offset()));
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
   return Array_getIndexed(assembler);
 }
 
@@ -191,7 +188,7 @@
 
 // Intrinsify only for Smi value and index. Non-smi values need a store buffer
 // update. Array length is always a Smi.
-bool Intrinsifier::Array_setIndexed(Assembler* assembler) {
+void Intrinsifier::Array_setIndexed(Assembler* assembler) {
   Label fall_through;
 
   if (FLAG_enable_type_checks) {
@@ -250,13 +247,12 @@
   // Caller is responsible for preserving the value if necessary.
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Allocate a GrowableObjectArray using the backing array specified.
 // On stack: type argument (+1), data (+0).
-bool Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
   // The newly allocated object is returned in V0.
   const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
   const intptr_t kArrayOffset = 0 * kWordSize;
@@ -318,29 +314,26 @@
       FieldAddress(V0, GrowableObjectArray::length_offset()));
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
+void Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
   __ lw(V0, Address(SP, 0 * kWordSize));
   __ Ret();
   __ delay_slot()->lw(V0,
       FieldAddress(V0, GrowableObjectArray::length_offset()));
-  return true;
 }
 
 
-bool Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
+void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
   __ lw(V0, Address(SP, 0 * kWordSize));
   __ lw(V0, FieldAddress(V0, GrowableObjectArray::data_offset()));
   __ Ret();
   __ delay_slot()->lw(V0, FieldAddress(V0, Array::length_offset()));
-  return true;
 }
 
 
-bool Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
   Label fall_through;
 
   __ lw(T0, Address(SP, 0 * kWordSize));  // Index
@@ -362,15 +355,14 @@
   __ Ret();
   __ delay_slot()->lw(V0, FieldAddress(T2, Array::data_offset()));
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Set value into growable object array at specified index.
 // On stack: growable array (+2), index (+1), value (+0).
-bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
-    return false;
+    return;
   }
   Label fall_through;
   __ lw(T1, Address(SP, 1 * kWordSize));  // Index.
@@ -392,14 +384,13 @@
                      T2);
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Set length of growable object array. The length cannot
 // be greater than the length of the data container.
 // On stack: growable array (+1), length (+0).
-bool Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
+void Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
   Label fall_through;
   __ lw(T1, Address(SP, 0 * kWordSize));  // Length value.
   __ andi(CMPRES, T1, Immediate(kSmiTagMask));
@@ -409,15 +400,14 @@
   __ delay_slot()->sw(T1,
       FieldAddress(T0, GrowableObjectArray::length_offset()));
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Set data of growable object array.
 // On stack: growable array (+1), data (+0).
-bool Intrinsifier::GrowableArray_setData(Assembler* assembler) {
+void Intrinsifier::GrowableArray_setData(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
-    return false;
+    return;
   }
   Label fall_through;
   __ lw(T1, Address(SP, 0 * kWordSize));  // Data.
@@ -432,16 +422,15 @@
                      T1);
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Add an element to growable array if it doesn't need to grow, otherwise
 // call into regular code.
 // On stack: growable array (+1), value (+0).
-bool Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableArray_add(Assembler* assembler) {
   // In checked mode we need to type-check the incoming argument.
-  if (FLAG_enable_type_checks) return false;
+  if (FLAG_enable_type_checks) return;
   Label fall_through;
   __ lw(T0, Address(SP, 1 * kWordSize));  // Array.
   __ lw(T1, FieldAddress(T0, GrowableObjectArray::length_offset()));
@@ -467,7 +456,6 @@
   __ Ret();
   __ delay_slot()->mov(V0, T7);
   __ Bind(&fall_through);
-  return false;
 }
 
 
@@ -559,11 +547,10 @@
 
 
 // Gets the length of a TypedData.
-bool Intrinsifier::TypedData_getLength(Assembler* assembler) {
+void Intrinsifier::TypedData_getLength(Assembler* assembler) {
   __ lw(T0, Address(SP, 0 * kWordSize));
   __ Ret();
   __ delay_slot()->lw(V0, FieldAddress(T0, TypedData::length_offset()));
-  return true;
 }
 
 
@@ -581,19 +568,17 @@
 
 
 #define TYPED_DATA_ALLOCATOR(clazz)                                            \
-bool Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) {             \
+void Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) {             \
   intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);       \
   intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid);           \
   int shift = GetScaleFactor(size);                                            \
   TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, shift);   \
-  return false;                                                                \
 }                                                                              \
-bool Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {         \
+void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {         \
   intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);       \
   intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid);           \
   int shift = GetScaleFactor(size);                                            \
   TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, shift);   \
-  return false;                                                                \
 }
 CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
 #undef TYPED_DATA_ALLOCATOR
@@ -611,7 +596,7 @@
 }
 
 
-bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);  // Checks two Smis.
@@ -619,16 +604,15 @@
   __ bltz(CMPRES, &fall_through);  // Fall through on overflow.
   __ Ret();  // Nothing in branch delay slot.
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_add(Assembler* assembler) {
+void Intrinsifier::Integer_add(Assembler* assembler) {
   return Integer_addFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);
@@ -636,11 +620,10 @@
   __ bltz(CMPRES, &fall_through);  // Fall through on overflow.
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_sub(Assembler* assembler) {
+void Intrinsifier::Integer_sub(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);
@@ -648,11 +631,10 @@
   __ bltz(CMPRES, &fall_through);  // Fall through on overflow.
   __ Ret();  // Nothing in branch delay slot.
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);  // checks two smis
@@ -665,11 +647,10 @@
   __ bne(T2, T3, &fall_through);  // Fall through on overflow.
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_mul(Assembler* assembler) {
+void Intrinsifier::Integer_mul(Assembler* assembler) {
   return Integer_mulFromInteger(assembler);
 }
 
@@ -721,7 +702,7 @@
 //      res = res + right;
 //    }
 //  }
-bool Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
   Label fall_through, subtract;
   // Test arguments for smi.
   __ lw(T1, Address(SP, 0 * kWordSize));
@@ -753,11 +734,10 @@
   __ delay_slot()->SmiTag(V0);
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_remainder(Assembler* assembler) {
+void Intrinsifier::Integer_remainder(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);
@@ -772,11 +752,10 @@
   __ delay_slot()->SmiTag(V0);
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_truncDivide(Assembler* assembler) {
+void Intrinsifier::Integer_truncDivide(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);
@@ -792,11 +771,10 @@
   __ Ret();
   __ delay_slot()->SmiTag(V0);
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_negate(Assembler* assembler) {
+void Intrinsifier::Integer_negate(Assembler* assembler) {
   Label fall_through;
 
   __ lw(T0, Address(SP, + 0 * kWordSize));  // Grabs first argument.
@@ -806,59 +784,55 @@
   __ bltz(CMPRES, &fall_through);  // There was overflow.
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);  // Checks two smis.
   __ Ret();
   __ delay_slot()->and_(V0, T0, T1);
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitAnd(Assembler* assembler) {
+void Intrinsifier::Integer_bitAnd(Assembler* assembler) {
   return Integer_bitAndFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);  // Checks two smis.
   __ Ret();
   __ delay_slot()->or_(V0, T0, T1);
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitOr(Assembler* assembler) {
+void Intrinsifier::Integer_bitOr(Assembler* assembler) {
   return Integer_bitOrFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);  // Checks two smis.
   __ Ret();
   __ delay_slot()->xor_(V0, T0, T1);
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitXor(Assembler* assembler) {
+void Intrinsifier::Integer_bitXor(Assembler* assembler) {
   return Integer_bitXorFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_shl(Assembler* assembler) {
+void Intrinsifier::Integer_shl(Assembler* assembler) {
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
   Label fall_through, overflow;
@@ -905,7 +879,6 @@
   __ Ret();
   __ delay_slot()->sw(T3, FieldAddress(V0, Mint::value_offset() + kWordSize));
   __ Bind(&fall_through);
-  return false;
 }
 
 
@@ -936,7 +909,7 @@
 }
 
 
-static bool CompareIntegers(Assembler* assembler, Condition true_condition) {
+static void CompareIntegers(Assembler* assembler, Condition true_condition) {
   Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
   TestBothArgumentsSmis(assembler, &try_mint_smi);
   // T0 contains the right argument. T1 contains left argument
@@ -1005,38 +978,37 @@
   __ b(&is_true);
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
+void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
   return CompareIntegers(assembler, LT);
 }
 
 
-bool Intrinsifier::Integer_lessThan(Assembler* assembler) {
+void Intrinsifier::Integer_lessThan(Assembler* assembler) {
   return Integer_greaterThanFromInt(assembler);
 }
 
 
-bool Intrinsifier::Integer_greaterThan(Assembler* assembler) {
+void Intrinsifier::Integer_greaterThan(Assembler* assembler) {
   return CompareIntegers(assembler, GT);
 }
 
 
-bool Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
+void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
   return CompareIntegers(assembler, LE);
 }
 
 
-bool Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
+void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
   return CompareIntegers(assembler, GE);
 }
 
 
 // This is called for Smi, Mint and Bigint receivers. The right argument
 // can be Smi, Mint, Bigint or double.
-bool Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
+void Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
   Label fall_through, true_label, check_for_mint;
   // For integer receiver '===' check first.
   __ lw(T0, Address(SP, 0 * kWordSize));
@@ -1084,16 +1056,15 @@
   // TODO(srdjan): Implement Mint == Mint comparison.
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_equal(Assembler* assembler) {
+void Intrinsifier::Integer_equal(Assembler* assembler) {
   return Integer_equalToInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_sar(Assembler* assembler) {
+void Intrinsifier::Integer_sar(Assembler* assembler) {
   Label fall_through;
 
   TestBothArgumentsSmis(assembler, &fall_through);
@@ -1111,16 +1082,14 @@
   __ Ret();
   __ delay_slot()->SmiTag(V0);
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Smi_bitNegate(Assembler* assembler) {
+void Intrinsifier::Smi_bitNegate(Assembler* assembler) {
   __ lw(T0, Address(SP, 0 * kWordSize));
   __ nor(V0, T0, ZR);
   __ Ret();
   __ delay_slot()->addiu(V0, V0, Immediate(-1));  // Remove inverted smi-tag.
-  return false;
 }
 
 
@@ -1143,7 +1112,7 @@
 // type. Return true or false object in the register V0. Any NaN argument
 // 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) {
+static void CompareDoubles(Assembler* assembler, Condition true_condition) {
   Label is_smi, double_op, no_NaN, fall_through;
   __ Comment("CompareDoubles Intrinsic");
 
@@ -1190,38 +1159,37 @@
   __ b(&double_op);
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_greaterThan(Assembler* assembler) {
+void Intrinsifier::Double_greaterThan(Assembler* assembler) {
   return CompareDoubles(assembler, GT);
 }
 
 
-bool Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
+void Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
   return CompareDoubles(assembler, GE);
 }
 
 
-bool Intrinsifier::Double_lessThan(Assembler* assembler) {
+void Intrinsifier::Double_lessThan(Assembler* assembler) {
   return CompareDoubles(assembler, LT);
 }
 
 
-bool Intrinsifier::Double_equal(Assembler* assembler) {
+void Intrinsifier::Double_equal(Assembler* assembler) {
   return CompareDoubles(assembler, EQ);
 }
 
 
-bool Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
+void Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
   return CompareDoubles(assembler, LE);
 }
 
 
 // Expects left argument to be double (receiver). Right argument is unknown.
 // Both arguments are on stack.
-static bool DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
+static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
   Label fall_through;
 
   TestLastArgumentIsDouble(assembler, &fall_through, &fall_through);
@@ -1246,32 +1214,31 @@
   __ delay_slot()->swc1(F1,
                         FieldAddress(V0, Double::value_offset() + kWordSize));
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_add(Assembler* assembler) {
+void Intrinsifier::Double_add(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kADD);
 }
 
 
-bool Intrinsifier::Double_mul(Assembler* assembler) {
+void Intrinsifier::Double_mul(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kMUL);
 }
 
 
-bool Intrinsifier::Double_sub(Assembler* assembler) {
+void Intrinsifier::Double_sub(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kSUB);
 }
 
 
-bool Intrinsifier::Double_div(Assembler* assembler) {
+void Intrinsifier::Double_div(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kDIV);
 }
 
 
 // Left is double right is integer (Bigint, Mint or Smi)
-bool Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
+void Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
   Label fall_through;
   // Only Smi-s allowed.
   __ lw(T0, Address(SP, 0 * kWordSize));
@@ -1295,11 +1262,10 @@
   __ delay_slot()->swc1(F1,
                         FieldAddress(V0, Double::value_offset() + kWordSize));
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_fromInteger(Assembler* assembler) {
+void Intrinsifier::Double_fromInteger(Assembler* assembler) {
   Label fall_through;
 
   __ lw(T0, Address(SP, 0 * kWordSize));
@@ -1318,11 +1284,10 @@
   __ delay_slot()->swc1(F1,
                         FieldAddress(V0, Double::value_offset() + kWordSize));
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_getIsNaN(Assembler* assembler) {
+void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
   Label is_true;
 
   __ lw(T0, Address(SP, 0 * kWordSize));
@@ -1335,11 +1300,10 @@
   __ Bind(&is_true);
   __ LoadObject(V0, Bool::True());
   __ Ret();
-  return true;
 }
 
 
-bool Intrinsifier::Double_getIsNegative(Assembler* assembler) {
+void Intrinsifier::Double_getIsNegative(Assembler* assembler) {
   Label is_false, is_true, is_zero;
   __ lw(T0, Address(SP, 0 * kWordSize));
   __ LoadDFromOffset(D0, T0, Double::value_offset() - kHeapObjectTag);
@@ -1369,11 +1333,10 @@
   __ andi(CMPRES, T0, Immediate(1));  // Check if the bit is set.
   __ bne(T0, ZR, &is_true);  // Sign bit set. True.
   __ b(&is_false);
-  return true;
 }
 
 
-bool Intrinsifier::Double_toInt(Assembler* assembler) {
+void Intrinsifier::Double_toInt(Assembler* assembler) {
   __ lw(T0, Address(SP, 0 * kWordSize));
   __ LoadDFromOffset(D0, T0, Double::value_offset() - kHeapObjectTag);
 
@@ -1389,11 +1352,10 @@
   __ Ret();
   __ delay_slot()->SmiTag(V0);
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Math_sqrt(Assembler* assembler) {
+void Intrinsifier::Math_sqrt(Assembler* assembler) {
   Label fall_through, is_smi, double_op;
   TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
   // Argument is double and is in T0.
@@ -1414,24 +1376,21 @@
   __ b(&double_op);
   __ delay_slot()->cvtdw(D1, F2);
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Math_sin(Assembler* assembler) {
-  return false;
+void Intrinsifier::Math_sin(Assembler* assembler) {
 }
 
 
-bool Intrinsifier::Math_cos(Assembler* assembler) {
-  return false;
+void Intrinsifier::Math_cos(Assembler* assembler) {
 }
 
 
 //    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
 //    _state[kSTATE_LO] = state & _MASK_32;
 //    _state[kSTATE_HI] = state >> 32;
-bool Intrinsifier::Random_nextState(Assembler* assembler) {
+void Intrinsifier::Random_nextState(Assembler* assembler) {
   const Library& math_lib = Library::Handle(Library::MathLibrary());
   ASSERT(!math_lib.IsNull());
   const Class& random_class = Class::Handle(
@@ -1473,11 +1432,10 @@
   __ sw(T3, addr_0);
   __ sw(T6, addr_1);
   __ Ret();
-  return true;
 }
 
 
-bool Intrinsifier::Object_equal(Assembler* assembler) {
+void Intrinsifier::Object_equal(Assembler* assembler) {
   Label is_true;
 
   __ lw(T0, Address(SP, 0 * kWordSize));
@@ -1488,30 +1446,27 @@
   __ Bind(&is_true);
   __ LoadObject(V0, Bool::True());
   __ Ret();
-  return true;
 }
 
 
-bool Intrinsifier::String_getHashCode(Assembler* assembler) {
+void Intrinsifier::String_getHashCode(Assembler* assembler) {
   Label fall_through;
   __ lw(T0, Address(SP, 0 * kWordSize));
   __ lw(V0, FieldAddress(T0, String::hash_offset()));
   __ beq(V0, ZR, &fall_through);
   __ Ret();
   __ Bind(&fall_through);  // Hash not yet computed.
-  return false;
 }
 
 
-bool Intrinsifier::String_getLength(Assembler* assembler) {
+void Intrinsifier::String_getLength(Assembler* assembler) {
   __ lw(T0, Address(SP, 0 * kWordSize));
   __ Ret();
   __ delay_slot()->lw(V0, FieldAddress(T0, String::length_offset()));
-  return true;
 }
 
 
-bool Intrinsifier::String_codeUnitAt(Assembler* assembler) {
+void Intrinsifier::String_codeUnitAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
 
   __ lw(T1, Address(SP, 0 * kWordSize));  // Index.
@@ -1542,11 +1497,10 @@
   __ delay_slot()->SmiTag(V0);
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::String_getIsEmpty(Assembler* assembler) {
+void Intrinsifier::String_getIsEmpty(Assembler* assembler) {
   Label is_true;
 
   __ lw(T0, Address(SP, 0 * kWordSize));
@@ -1558,11 +1512,10 @@
   __ Bind(&is_true);
   __ LoadObject(V0, Bool::True());
   __ Ret();
-  return false;
 }
 
 
-bool Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
+void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
   Label no_hash;
 
   __ lw(T1, Address(SP, 0 * kWordSize));
@@ -1625,7 +1578,6 @@
 
   __ Ret();
   __ delay_slot()->sw(V0, FieldAddress(T1, String::hash_offset()));
-  return true;
 }
 
 
@@ -1707,7 +1659,7 @@
 // Arg1: Start index as Smi.
 // Arg2: End index as Smi.
 // The indexes must be valid.
-bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
+void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
   const intptr_t kStringOffset = 2 * kWordSize;
   const intptr_t kStartIndexOffset = 1 * kWordSize;
   const intptr_t kEndIndexOffset = 0 * kWordSize;
@@ -1754,11 +1706,10 @@
   __ Bind(&done);
   __ Ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::OneByteString_setAt(Assembler* assembler) {
+void Intrinsifier::OneByteString_setAt(Assembler* assembler) {
   __ lw(T2, Address(SP, 0 * kWordSize));  // Value.
   __ lw(T1, Address(SP, 1 * kWordSize));  // Index.
   __ lw(T0, Address(SP, 2 * kWordSize));  // OneByteString.
@@ -1767,11 +1718,10 @@
   __ addu(T3, T0, T1);
   __ Ret();
   __ delay_slot()->sb(T2, FieldAddress(T3, OneByteString::data_offset()));
-  return true;
 }
 
 
-bool Intrinsifier::OneByteString_allocate(Assembler* assembler) {
+void Intrinsifier::OneByteString_allocate(Assembler* assembler) {
   Label fall_through, ok;
 
   __ lw(T2, Address(SP, 0 * kWordSize));  // Length.
@@ -1781,7 +1731,6 @@
   __ Ret();
 
   __ Bind(&fall_through);
-  return false;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index f6d70b6..89b9622 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -27,7 +27,7 @@
 #define __ assembler->
 
 
-bool Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
+void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
   // This snippet of inlined code uses the following registers:
   // RAX, RCX, RDI, R13
   // and the newly allocated object is returned in RAX.
@@ -132,24 +132,22 @@
   __ ret();  // returns the newly allocated object in RAX.
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Array_getLength(Assembler* assembler) {
+void Intrinsifier::Array_getLength(Assembler* assembler) {
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
   __ movq(RAX, FieldAddress(RAX, Array::length_offset()));
   __ ret();
-  return true;
 }
 
 
-bool Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
+void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
   return Array_getLength(assembler);
 }
 
 
-bool Intrinsifier::Array_getIndexed(Assembler* assembler) {
+void Intrinsifier::Array_getIndexed(Assembler* assembler) {
   Label fall_through;
   __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Index.
   __ movq(RAX, Address(RSP, + 2 * kWordSize));  // Array.
@@ -164,18 +162,17 @@
   __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()));
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
   return Array_getIndexed(assembler);
 }
 
 
-bool Intrinsifier::Array_setIndexed(Assembler* assembler) {
+void Intrinsifier::Array_setIndexed(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
-    return false;
+    return;
   }
   __ movq(RDX, Address(RSP, + 1 * kWordSize));  // Value.
   __ movq(RCX, Address(RSP, + 2 * kWordSize));  // Index.
@@ -196,13 +193,12 @@
   // Caller is responsible of preserving the value if necessary.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Allocate a GrowableObjectArray using the backing array specified.
 // On stack: type argument (+2), data (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
   // This snippet of inlined code uses the following registers:
   // RAX, RCX, R13
   // and the newly allocated object is returned in RAX.
@@ -267,32 +263,29 @@
   __ ret();  // returns the newly allocated object in RAX.
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Get length of growable object array.
 // On stack: growable array (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
+void Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
   __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
   __ ret();
-  return true;
 }
 
 
-bool Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
+void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
   __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset()));
   __ movq(RAX, FieldAddress(RAX, Array::length_offset()));
   __ ret();
-  return true;
 }
 
 
 // Access growable object array at specified index.
 // On stack: growable array (+2), index (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
   Label fall_through;
   __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Index.
   __ movq(RAX, Address(RSP, + 2 * kWordSize));  // GrowableArray.
@@ -309,15 +302,14 @@
   __ movq(RAX, FieldAddress(RAX, RCX, TIMES_4, Array::data_offset()));
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Set value into growable object array at specified index.
 // On stack: growable array (+3), index (+2), value (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
-    return false;
+    return;
   }
   __ movq(RDX, Address(RSP, + 1 * kWordSize));  // Value.
   __ movq(RCX, Address(RSP, + 2 * kWordSize));  // Index.
@@ -337,14 +329,13 @@
                      RDX);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Set length of growable object array. The length cannot
 // be greater than the length of the data container.
 // On stack: growable array (+2), length (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
+void Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
   Label fall_through;
   __ movq(RAX, Address(RSP, + 2 * kWordSize));  // Growable array.
   __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Length value.
@@ -353,15 +344,14 @@
   __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()), RCX);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Set data of growable object array.
 // On stack: growable array (+2), data (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_setData(Assembler* assembler) {
+void Intrinsifier::GrowableArray_setData(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
-    return false;
+    return;
   }
   Label fall_through;
   __ movq(RBX, Address(RSP, + 1 * kWordSize));  /// Data.
@@ -375,16 +365,15 @@
                      RBX);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Add an element to growable array if it doesn't need to grow, otherwise
 // call into regular code.
 // On stack: growable array (+2), value (+1), return-address (+0).
-bool Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableArray_add(Assembler* assembler) {
   // In checked mode we need to check the incoming argument.
-  if (FLAG_enable_type_checks) return false;
+  if (FLAG_enable_type_checks) return;
   Label fall_through;
   __ movq(RAX, Address(RSP, + 2 * kWordSize));  // Array.
   __ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
@@ -408,7 +397,6 @@
   __ movq(RAX, raw_null);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
@@ -511,14 +499,10 @@
 
 
 // Gets the length of a TypedData.
-bool Intrinsifier::TypedData_getLength(Assembler* assembler) {
+void Intrinsifier::TypedData_getLength(Assembler* assembler) {
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
   __ movq(RAX, FieldAddress(RAX, TypedData::length_offset()));
   __ ret();
-  // Generate enough code to satisfy patchability constraint.
-  intptr_t offset = __ CodeSize();
-  __ nop(JumpPattern::InstructionLength() - offset);
-  return true;
 }
 
 
@@ -536,19 +520,17 @@
 
 
 #define TYPED_DATA_ALLOCATOR(clazz)                                            \
-bool Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) {             \
+void Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) {             \
   intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);       \
   intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid);           \
   ScaleFactor scale = GetScaleFactor(size);                                    \
   TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale);   \
-  return false;                                                                \
 }                                                                              \
-bool Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {         \
+void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) {         \
   intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);       \
   intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid);           \
   ScaleFactor scale = GetScaleFactor(size);                                    \
   TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale);   \
-  return false;                                                                \
 }
 CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
 #undef TYPED_DATA_ALLOCATOR
@@ -565,7 +547,7 @@
 }
 
 
-bool Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_addFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX contains right argument.
@@ -574,16 +556,15 @@
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_add(Assembler* assembler) {
+void Intrinsifier::Integer_add(Assembler* assembler) {
   return Integer_addFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_subFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX contains right argument, which is the actual minuend of subtraction.
@@ -592,11 +573,10 @@
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_sub(Assembler* assembler) {
+void Intrinsifier::Integer_sub(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX contains right argument, which is the actual subtrahend of subtraction.
@@ -607,12 +587,11 @@
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 
-bool Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_mulFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX is the right argument.
@@ -623,11 +602,10 @@
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_mul(Assembler* assembler) {
+void Intrinsifier::Integer_mul(Assembler* assembler) {
   return Integer_mulFromInteger(assembler);
 }
 
@@ -703,7 +681,7 @@
 //      res = res + right;
 //    }
 //  }
-bool Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
   Label fall_through, negative_result;
   TestBothArgumentsSmis(assembler, &fall_through);
   __ movq(RCX, Address(RSP, + 2 * kWordSize));
@@ -734,11 +712,10 @@
   __ ret();
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_remainder(Assembler* assembler) {
+void Intrinsifier::Integer_remainder(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX: right argument (divisor)
@@ -753,11 +730,10 @@
   __ SmiTag(RAX);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_truncDivide(Assembler* assembler) {
+void Intrinsifier::Integer_truncDivide(Assembler* assembler) {
   Label fall_through, not_32bit;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX: right argument (divisor)
@@ -801,11 +777,10 @@
   __ SmiTag(RAX);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_negate(Assembler* assembler) {
+void Intrinsifier::Integer_negate(Assembler* assembler) {
   Label fall_through;
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
   __ testq(RAX, Immediate(kSmiTagMask));
@@ -815,11 +790,10 @@
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX is the right argument.
@@ -827,16 +801,15 @@
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitAnd(Assembler* assembler) {
+void Intrinsifier::Integer_bitAnd(Assembler* assembler) {
   return Integer_bitAndFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX is the right argument.
@@ -844,16 +817,15 @@
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitOr(Assembler* assembler) {
+void Intrinsifier::Integer_bitOr(Assembler* assembler) {
   return Integer_bitOrFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
+void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler) {
   Label fall_through;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX is the right argument.
@@ -861,16 +833,15 @@
   // Result is in RAX.
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_bitXor(Assembler* assembler) {
+void Intrinsifier::Integer_bitXor(Assembler* assembler) {
   return Integer_bitXorFromInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_shl(Assembler* assembler) {
+void Intrinsifier::Integer_shl(Assembler* assembler) {
   ASSERT(kSmiTagShift == 1);
   ASSERT(kSmiTag == 0);
   Label fall_through, overflow;
@@ -899,11 +870,10 @@
   // Mint is rarely used on x64 (only for integers requiring 64 bit instead of
   // 63 bits as represented by Smi).
   __ Bind(&fall_through);
-  return false;
 }
 
 
-static bool CompareIntegers(Assembler* assembler, Condition true_condition) {
+static void CompareIntegers(Assembler* assembler, Condition true_condition) {
   Label fall_through, true_label;
   TestBothArgumentsSmis(assembler, &fall_through);
   // RAX contains the right argument.
@@ -915,39 +885,38 @@
   __ LoadObject(RAX, Bool::True());
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 
-bool Intrinsifier::Integer_lessThan(Assembler* assembler) {
+void Intrinsifier::Integer_lessThan(Assembler* assembler) {
   return CompareIntegers(assembler, LESS);
 }
 
 
-bool Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
+void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler) {
   return CompareIntegers(assembler, LESS);
 }
 
 
-bool Intrinsifier::Integer_greaterThan(Assembler* assembler) {
+void Intrinsifier::Integer_greaterThan(Assembler* assembler) {
   return CompareIntegers(assembler, GREATER);
 }
 
 
-bool Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
+void Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
   return CompareIntegers(assembler, LESS_EQUAL);
 }
 
 
-bool Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
+void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
   return CompareIntegers(assembler, GREATER_EQUAL);
 }
 
 
 // This is called for Smi, Mint and Bigint receivers. The right argument
 // can be Smi, Mint, Bigint or double.
-bool Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
+void Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
   Label fall_through, true_label, check_for_mint;
   // For integer receiver '===' check first.
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
@@ -993,16 +962,15 @@
   // TODO(srdjan): Implement Mint == Mint comparison.
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Integer_equal(Assembler* assembler) {
+void Intrinsifier::Integer_equal(Assembler* assembler) {
   return Integer_equalToInteger(assembler);
 }
 
 
-bool Intrinsifier::Integer_sar(Assembler* assembler) {
+void Intrinsifier::Integer_sar(Assembler* assembler) {
   Label fall_through, shift_count_ok;
   TestBothArgumentsSmis(assembler, &fall_through);
   const Immediate& count_limit = Immediate(0x3F);
@@ -1024,17 +992,15 @@
   __ SmiTag(RAX);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Argument is Smi (receiver).
-bool Intrinsifier::Smi_bitNegate(Assembler* assembler) {
+void Intrinsifier::Smi_bitNegate(Assembler* assembler) {
   __ movq(RAX, Address(RSP, + 1 * kWordSize));  // Index.
   __ notq(RAX);
   __ andq(RAX, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
   __ ret();
-  return true;
 }
 
 
@@ -1057,7 +1023,7 @@
 // unknown type. Return true or false object in RAX. Any NaN argument
 // 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) {
+static void CompareDoubles(Assembler* assembler, Condition true_condition) {
   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.
@@ -1080,38 +1046,37 @@
   __ cvtsi2sd(XMM1, RAX);
   __ jmp(&double_op);
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_greaterThan(Assembler* assembler) {
+void Intrinsifier::Double_greaterThan(Assembler* assembler) {
   return CompareDoubles(assembler, ABOVE);
 }
 
 
-bool Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
+void Intrinsifier::Double_greaterEqualThan(Assembler* assembler) {
   return CompareDoubles(assembler, ABOVE_EQUAL);
 }
 
 
-bool Intrinsifier::Double_lessThan(Assembler* assembler) {
+void Intrinsifier::Double_lessThan(Assembler* assembler) {
   return CompareDoubles(assembler, BELOW);
 }
 
 
-bool Intrinsifier::Double_equal(Assembler* assembler) {
+void Intrinsifier::Double_equal(Assembler* assembler) {
   return CompareDoubles(assembler, EQUAL);
 }
 
 
-bool Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
+void Intrinsifier::Double_lessEqualThan(Assembler* assembler) {
   return CompareDoubles(assembler, BELOW_EQUAL);
 }
 
 
 // Expects left argument to be double (receiver). Right argument is unknown.
 // Both arguments are on stack.
-static bool DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
+static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
   Label fall_through;
   TestLastArgumentIsDouble(assembler, &fall_through, &fall_through);
   // Both arguments are double, right operand is in RAX.
@@ -1134,31 +1099,30 @@
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_add(Assembler* assembler) {
+void Intrinsifier::Double_add(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kADD);
 }
 
 
-bool Intrinsifier::Double_mul(Assembler* assembler) {
+void Intrinsifier::Double_mul(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kMUL);
 }
 
 
-bool Intrinsifier::Double_sub(Assembler* assembler) {
+void Intrinsifier::Double_sub(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kSUB);
 }
 
 
-bool Intrinsifier::Double_div(Assembler* assembler) {
+void Intrinsifier::Double_div(Assembler* assembler) {
   return DoubleArithmeticOperations(assembler, Token::kDIV);
 }
 
 
-bool Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
+void Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
   Label fall_through;
   // Only Smi-s allowed.
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
@@ -1179,12 +1143,11 @@
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
 // Left is double right is integer (Bigint, Mint or Smi)
-bool Intrinsifier::Double_fromInteger(Assembler* assembler) {
+void Intrinsifier::Double_fromInteger(Assembler* assembler) {
   Label fall_through;
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ testq(RAX, Immediate(kSmiTagMask));
@@ -1201,11 +1164,10 @@
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Double_getIsNaN(Assembler* assembler) {
+void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
   Label is_true;
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
@@ -1216,11 +1178,10 @@
   __ Bind(&is_true);
   __ LoadObject(RAX, Bool::True());
   __ ret();
-  return true;  // Method is complete, no slow case.
 }
 
 
-bool Intrinsifier::Double_getIsNegative(Assembler* assembler) {
+void Intrinsifier::Double_getIsNegative(Assembler* assembler) {
   Label is_false, is_true, is_zero;
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
@@ -1241,7 +1202,6 @@
   __ testq(RAX, Immediate(1));
   __ j(NOT_ZERO, &is_true, Assembler::kNearJump);
   __ jmp(&is_false, Assembler::kNearJump);
-  return true;  // Method is complete, no slow case.
 }
 
 
@@ -1289,7 +1249,7 @@
 }
 
 
-bool Intrinsifier::Double_toInt(Assembler* assembler) {
+void Intrinsifier::Double_toInt(Assembler* assembler) {
   __ movq(RAX, Address(RSP, +1 * kWordSize));
   __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
   __ cvttsd2siq(RAX, XMM0);
@@ -1302,11 +1262,10 @@
   __ SmiTag(RAX);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Math_sqrt(Assembler* assembler) {
+void Intrinsifier::Math_sqrt(Assembler* assembler) {
   Label fall_through, is_smi, double_op;
   TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
   // Argument is double and is in RAX.
@@ -1326,26 +1285,23 @@
   __ cvtsi2sd(XMM1, RAX);
   __ jmp(&double_op);
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::Math_sin(Assembler* assembler) {
+void Intrinsifier::Math_sin(Assembler* assembler) {
   EmitTrigonometric(assembler, kSine);
-  return false;  // Compile method for slow case.
 }
 
 
-bool Intrinsifier::Math_cos(Assembler* assembler) {
+void Intrinsifier::Math_cos(Assembler* assembler) {
   EmitTrigonometric(assembler, kCosine);
-  return false;  // Compile method for slow case.
 }
 
 
 //    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
 //    _state[kSTATE_LO] = state & _MASK_32;
 //    _state[kSTATE_HI] = state >> 32;
-bool Intrinsifier::Random_nextState(Assembler* assembler) {
+void Intrinsifier::Random_nextState(Assembler* assembler) {
   const Library& math_lib = Library::Handle(Library::MathLibrary());
   ASSERT(!math_lib.IsNull());
   const Class& random_class = Class::Handle(
@@ -1383,13 +1339,12 @@
   __ shrq(RDX, Immediate(32));
   __ movl(addr_1, RDX);
   __ ret();
-  return true;
 }
 
 
 
 // Identity comparison.
-bool Intrinsifier::Object_equal(Assembler* assembler) {
+void Intrinsifier::Object_equal(Assembler* assembler) {
   Label is_true;
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
   __ cmpq(RAX, Address(RSP, + 2 * kWordSize));
@@ -1399,11 +1354,10 @@
   __ Bind(&is_true);
   __ LoadObject(RAX, Bool::True());
   __ ret();
-  return true;
 }
 
 
-bool Intrinsifier::String_getHashCode(Assembler* assembler) {
+void Intrinsifier::String_getHashCode(Assembler* assembler) {
   Label fall_through;
   __ movq(RAX, Address(RSP, + 1 * kWordSize));  // String object.
   __ movq(RAX, FieldAddress(RAX, String::hash_offset()));
@@ -1412,19 +1366,17 @@
   __ ret();
   __ Bind(&fall_through);
   // Hash not yet computed.
-  return false;
 }
 
 
-bool Intrinsifier::String_getLength(Assembler* assembler) {
+void Intrinsifier::String_getLength(Assembler* assembler) {
   __ movq(RAX, Address(RSP, + 1 * kWordSize));  // String object.
   __ movq(RAX, FieldAddress(RAX, String::length_offset()));
   __ ret();
-  return true;
 }
 
 
-bool Intrinsifier::String_codeUnitAt(Assembler* assembler) {
+void Intrinsifier::String_codeUnitAt(Assembler* assembler) {
   Label fall_through, try_two_byte_string;
   __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Index.
   __ movq(RAX, Address(RSP, + 2 * kWordSize));  // String.
@@ -1450,11 +1402,10 @@
   __ ret();
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::String_getIsEmpty(Assembler* assembler) {
+void Intrinsifier::String_getIsEmpty(Assembler* assembler) {
   Label is_true;
   // Get length.
   __ movq(RAX, Address(RSP, + 1 * kWordSize));  // String object.
@@ -1466,11 +1417,10 @@
   __ Bind(&is_true);
   __ LoadObject(RAX, Bool::True());
   __ ret();
-  return false;
 }
 
 
-bool Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
+void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) {
   Label compute_hash;
   __ movq(RBX, Address(RSP, + 1 * kWordSize));  // OneByteString object.
   __ movq(RAX, FieldAddress(RBX, String::hash_offset()));
@@ -1536,7 +1486,6 @@
   __ SmiTag(RAX);
   __ movq(FieldAddress(RBX, String::hash_offset()), RAX);
   __ ret();
-  return true;
 }
 
 
@@ -1622,7 +1571,7 @@
 // Arg1: Start index as Smi.
 // Arg2: End index as Smi.
 // The indexes must be valid.
-bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
+void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
   const intptr_t kStringOffset = 3 * kWordSize;
   const intptr_t kStartIndexOffset = 2 * kWordSize;
   const intptr_t kEndIndexOffset = 1 * kWordSize;
@@ -1659,11 +1608,10 @@
   __ j(LESS, &loop, Assembler::kNearJump);
   __ ret();
   __ Bind(&fall_through);
-  return false;
 }
 
 
-bool Intrinsifier::OneByteString_setAt(Assembler* assembler) {
+void Intrinsifier::OneByteString_setAt(Assembler* assembler) {
   __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Value.
   __ movq(RBX, Address(RSP, + 2 * kWordSize));  // Index.
   __ movq(RAX, Address(RSP, + 3 * kWordSize));  // OneByteString.
@@ -1671,11 +1619,10 @@
   __ SmiUntag(RCX);
   __ movb(FieldAddress(RAX, RBX, TIMES_1, OneByteString::data_offset()), RCX);
   __ ret();
-  return true;
 }
 
 
-bool Intrinsifier::OneByteString_allocate(Assembler* assembler) {
+void Intrinsifier::OneByteString_allocate(Assembler* assembler) {
   __ movq(RDI, Address(RSP, + 1 * kWordSize));  // Length.v=
   Label fall_through, ok;
   TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI);
@@ -1685,7 +1632,6 @@
   __ ret();
 
   __ Bind(&fall_through);
-  return false;
 }
 
 
diff --git a/runtime/vm/json_test.cc b/runtime/vm/json_test.cc
index bdbfc26..89a1b5b 100644
--- a/runtime/vm/json_test.cc
+++ b/runtime/vm/json_test.cc
@@ -73,11 +73,14 @@
                      "    \"foo\" : [null, 1, { }, \"bar\", true, false],"
                      "    \"line\": 111, "
                      "  },"
-                     "  \"foo\": \"outer foo\", "
+                     "  \"foo\": \"outer foo\",     "
+                     "  \"quote\": \"\\\"\",        "
+                     "  \"white\": \"\\t \\n\",     "
                      "}";
 
   JSONReader reader(jobj);
   bool found;
+  char s[128];
 
   found = reader.Seek("id");
   EXPECT(found);
@@ -86,6 +89,23 @@
   EXPECT(found);
   EXPECT_EQ(reader.Type(), JSONReader::kString);
   EXPECT(reader.IsStringLiteral("outer foo"));
+
+  found = reader.Seek("quote");
+  EXPECT(found);
+  EXPECT_EQ(reader.Type(), JSONReader::kString);
+  reader.GetRawValueChars(s, sizeof s);
+  EXPECT_STREQ("\\\"", s);
+  reader.GetDecodedValueChars(s, sizeof s);
+  EXPECT_STREQ("\"", s);
+
+  found = reader.Seek("white");
+  EXPECT(found);
+  EXPECT_EQ(reader.Type(), JSONReader::kString);
+  reader.GetRawValueChars(s, sizeof s);
+  EXPECT_STREQ("\\t \\n", s);
+  reader.GetDecodedValueChars(s, sizeof s);
+  EXPECT_STREQ("\t \n", s);
+
   found = reader.Seek("line");
   EXPECT(!found);
   found = reader.Seek("params");
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 6fcb9fa..137eb9d 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -61,6 +61,7 @@
 DECLARE_FLAG(bool, enable_type_checks);
 DECLARE_FLAG(bool, trace_deoptimization);
 DECLARE_FLAG(bool, trace_deoptimization_verbose);
+DECLARE_FLAG(bool, error_on_bad_type);
 DECLARE_FLAG(bool, error_on_bad_override);
 
 static const char* kGetterPrefix = "get:";
@@ -1751,7 +1752,7 @@
   TypeParameter& type_param = reused_handles.TypeParameterHandle();
   String& type_param_name = reused_handles.StringHandle();
   if (!type_params.IsNull()) {
-    intptr_t num_type_params = type_params.Length();
+    const intptr_t num_type_params = type_params.Length();
     for (intptr_t i = 0; i < num_type_params; i++) {
       type_param ^= type_params.TypeAt(i);
       type_param_name = type_param.name();
@@ -2051,6 +2052,55 @@
 }
 
 
+static RawPatchClass* MakeTempPatchClass(const Class& cls,
+                                         const String& expr) {
+  String& src = String::Handle(String::New("() => "));
+  src = String::Concat(src, expr);
+  src = String::Concat(src, Symbols::Semicolon());
+  Script& script = Script::Handle();
+  script = Script::New(Symbols::Empty(), src, RawScript::kSourceTag);
+  // In order to tokenize the source, we need to get the key to mangle
+  // private names from the library from which the object's class
+  // originates.
+  const Library& lib = Library::Handle(cls.library());
+  ASSERT(!lib.IsNull());
+  const String& lib_key = String::Handle(lib.private_key());
+  script.Tokenize(lib_key);
+
+  const String& src_class_name = String::Handle(Symbols::New(":internal"));
+  const Class& src_class = Class::Handle(
+      Class::New(src_class_name, script, Scanner::kDummyTokenIndex));
+  src_class.set_is_finalized();
+  src_class.set_library(lib);
+  return PatchClass::New(cls, src_class);
+}
+
+
+RawObject* Class::Evaluate(const String& expr) const {
+  const PatchClass& temp_class =
+      PatchClass::Handle(MakeTempPatchClass(*this, expr));
+  const String& eval_func_name = String::Handle(Symbols::New(":eval"));
+  const Function& eval_func =
+      Function::Handle(Function::New(eval_func_name,
+                                     RawFunction::kRegularFunction,
+                                     true,   // Static.
+                                     false,  // Not const.
+                                     false,  // Not abstract.
+                                     false,  // Not external.
+                                     temp_class,
+                                     0));
+  eval_func.set_result_type(Type::Handle(Type::DynamicType()));
+  eval_func.set_num_fixed_parameters(0);
+  eval_func.SetNumOptionalParameters(0, true);
+  eval_func.set_is_optimizable(false);
+
+  const Array& args = Array::Handle(Array::New(0));
+  const Object& result =
+      Object::Handle(DartEntry::InvokeFunction(eval_func, args));
+  return result.raw();
+}
+
+
 // Ensure that top level parsing of the class has been done.
 RawError* Class::EnsureIsFinalized(Isolate* isolate) const {
   // Finalized classes have already been parsed.
@@ -2134,11 +2184,6 @@
       Isolate::Current()->object_store()->function_impl_type()));
   result.set_is_synthesized_class();
   result.set_type_arguments_field_offset(Closure::type_arguments_offset());
-  // Implements interface "Function".
-  const Type& function_type = Type::Handle(Type::Function());
-  const Array& interfaces = Array::Handle(Array::New(1, Heap::kOld));
-  interfaces.SetAt(0, function_type);
-  result.set_interfaces(interfaces);
   if (!signature_function.IsNull()) {
     result.PatchSignatureFunction(signature_function);
   }
@@ -2418,7 +2463,7 @@
     const AbstractTypeArguments& type_arguments,
     const Class& other,
     const AbstractTypeArguments& other_type_arguments,
-    Error* malformed_error) const {
+    Error* bound_error) const {
   ASSERT(!IsVoidClass());
   // Check for DynamicType.
   // Each occurrence of DynamicType in type T is interpreted as the dynamic
@@ -2465,7 +2510,7 @@
     return type_arguments.TypeTest(test_kind,
                                    other_type_arguments,
                                    len,
-                                   malformed_error);
+                                   bound_error);
   }
   const bool other_is_function_class = other.IsFunctionClass();
   if (other.IsSignatureClass() || other_is_function_class) {
@@ -2480,7 +2525,7 @@
                           type_arguments,
                           other_fun,
                           other_type_arguments,
-                          malformed_error);
+                          bound_error);
     }
     // Check if type S has a call() method of function type T.
     Function& function =
@@ -2499,7 +2544,7 @@
                             type_arguments,
                             other_fun,
                             other_type_arguments,
-                            malformed_error)) {
+                            bound_error)) {
         return true;
       }
     }
@@ -2510,7 +2555,7 @@
   AbstractType& interface = AbstractType::Handle();
   Class& interface_class = Class::Handle();
   AbstractTypeArguments& interface_args = AbstractTypeArguments::Handle();
-  Error& args_malformed_error = Error::Handle();
+  Error& args_bound_error = Error::Handle();
   for (intptr_t i = 0; i < interfaces.Length(); i++) {
     interface ^= interfaces.At(i);
     if (!interface.IsFinalized()) {
@@ -2529,13 +2574,13 @@
       // parameters of the interface are at the end of the type vector,
       // after the type arguments of the super type of this type.
       // The index of the type parameters is adjusted upon finalization.
-      args_malformed_error = Error::null();
+      args_bound_error = Error::null();
       interface_args = interface_args.InstantiateFrom(type_arguments,
-                                                      &args_malformed_error);
-      if (!args_malformed_error.IsNull()) {
-        // Return the first malformed error to the caller if it requests it.
-        if ((malformed_error != NULL) && malformed_error->IsNull()) {
-          *malformed_error = args_malformed_error.raw();
+                                                      &args_bound_error);
+      if (!args_bound_error.IsNull()) {
+        // Return the first bound error to the caller if it requests it.
+        if ((bound_error != NULL) && bound_error->IsNull()) {
+          *bound_error = args_bound_error.raw();
         }
         continue;  // Another interface may work better.
       }
@@ -2544,7 +2589,7 @@
                                  interface_args,
                                  other,
                                  other_type_arguments,
-                                 malformed_error)) {
+                                 bound_error)) {
       return true;
     }
   }
@@ -2559,7 +2604,7 @@
                               type_arguments,
                               other,
                               other_type_arguments,
-                              malformed_error);
+                              bound_error);
 }
 
 
@@ -3034,7 +3079,7 @@
 intptr_t AbstractTypeArguments::Hash() const {
   if (IsNull()) return 0;
   uword result = 0;
-  intptr_t num_types = Length();
+  const intptr_t num_types = Length();
   AbstractType& type = AbstractType::Handle();
   for (intptr_t i = 0; i < num_types; i++) {
     type = TypeAt(i);
@@ -3080,7 +3125,7 @@
   if (other.IsNull()) {
     return false;
   }
-  intptr_t num_types = Length();
+  const intptr_t num_types = Length();
   if (num_types != other.Length()) {
     return false;
   }
@@ -3115,7 +3160,7 @@
 
 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* malformed_error) const {
+    Error* bound_error) const {
   // AbstractTypeArguments is an abstract class.
   UNREACHABLE();
   return NULL;
@@ -3153,7 +3198,7 @@
 bool AbstractTypeArguments::TypeTest(TypeTestKind test_kind,
                                      const AbstractTypeArguments& other,
                                      intptr_t len,
-                                     Error* malformed_error) const {
+                                     Error* bound_error) const {
   ASSERT(Length() >= len);
   ASSERT(!other.IsNull());
   ASSERT(other.Length() >= len);
@@ -3164,7 +3209,7 @@
     ASSERT(!type.IsNull());
     other_type = other.TypeAt(i);
     ASSERT(!other_type.IsNull());
-    if (!type.TypeTest(test_kind, other_type, malformed_error)) {
+    if (!type.TypeTest(test_kind, other_type, bound_error)) {
       return false;
     }
   }
@@ -3209,7 +3254,7 @@
 
 bool TypeArguments::IsResolved() const {
   AbstractType& type = AbstractType::Handle();
-  intptr_t num_types = Length();
+  const intptr_t num_types = Length();
   for (intptr_t i = 0; i < num_types; i++) {
     type = TypeAt(i);
     if (!type.IsResolved()) {
@@ -3222,7 +3267,7 @@
 
 bool TypeArguments::IsInstantiated() const {
   AbstractType& type = AbstractType::Handle();
-  intptr_t num_types = Length();
+  const intptr_t num_types = Length();
   for (intptr_t i = 0; i < num_types; i++) {
     type = TypeAt(i);
     ASSERT(!type.IsNull());
@@ -3320,7 +3365,7 @@
 
 bool TypeArguments::IsBounded() const {
   AbstractType& type = AbstractType::Handle();
-  intptr_t num_types = Length();
+  const intptr_t num_types = Length();
   for (intptr_t i = 0; i < num_types; i++) {
     type = TypeAt(i);
     if (type.IsBoundedType()) {
@@ -3346,7 +3391,7 @@
 
 RawAbstractTypeArguments* TypeArguments::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* malformed_error) const {
+    Error* bound_error) const {
   ASSERT(!IsInstantiated());
   if (!instantiator_type_arguments.IsNull() &&
       IsUninstantiatedIdentity() &&
@@ -3360,7 +3405,7 @@
   for (intptr_t i = 0; i < num_types; i++) {
     type = TypeAt(i);
     if (!type.IsInstantiated()) {
-      type = type.InstantiateFrom(instantiator_type_arguments, malformed_error);
+      type = type.InstantiateFrom(instantiator_type_arguments, bound_error);
     }
     instantiated_array.SetTypeAt(i, type);
   }
@@ -3543,13 +3588,13 @@
   if (!type.IsInstantiated()) {
     const AbstractTypeArguments& instantiator_type_args =
         AbstractTypeArguments::Handle(instantiator_type_arguments());
-    Error& malformed_error = Error::Handle();
-    type = type.InstantiateFrom(instantiator_type_args, &malformed_error);
+    Error& bound_error = Error::Handle();
+    type = type.InstantiateFrom(instantiator_type_args, &bound_error);
     // InstantiatedTypeArguments cannot include unchecked bounds.
     // In the presence of unchecked bounds, no InstantiatedTypeArguments are
     // allocated, but the type arguments are instantiated individually and their
     // bounds are checked.
-    ASSERT(malformed_error.IsNull());
+    ASSERT(bound_error.IsNull());
   }
   return type.raw();
 }
@@ -4369,16 +4414,16 @@
 
 
 bool Function::HasCompatibleParametersWith(const Function& other,
-                                           Error* error) const {
+                                           Error* bound_error) const {
   ASSERT(FLAG_error_on_bad_override);
   // Check that this function's signature type is a subtype of the other
   // function's signature type.
   if (!TypeTest(kIsSubtypeOf, Object::null_abstract_type_arguments(),
-                other, Object::null_abstract_type_arguments(), error)) {
+                other, Object::null_abstract_type_arguments(), bound_error)) {
     // For more informative error reporting, use the location of the other
     // function here, since the caller will use the location of this function.
-    *error = FormatError(
-        *error,  // A malformed error if non null.
+    *bound_error = FormatError(
+        *bound_error,  // A bound error if non null.
         Script::Handle(other.script()),
         other.token_pos(),
         "signature type '%s' of function '%s' is not a subtype of signature "
@@ -4414,13 +4459,13 @@
     const AbstractTypeArguments& type_arguments,
     const Function& other,
     const AbstractTypeArguments& other_type_arguments,
-    Error* malformed_error) const {
+    Error* bound_error) const {
   AbstractType& other_param_type =
       AbstractType::Handle(other.ParameterTypeAt(other_parameter_position));
   if (!other_param_type.IsInstantiated()) {
     other_param_type = other_param_type.InstantiateFrom(other_type_arguments,
-                                                        malformed_error);
-    ASSERT((malformed_error == NULL) || malformed_error->IsNull());
+                                                        bound_error);
+    ASSERT((bound_error == NULL) || bound_error->IsNull());
   }
   if (other_param_type.IsDynamicType()) {
     return true;
@@ -4428,20 +4473,20 @@
   AbstractType& param_type =
       AbstractType::Handle(ParameterTypeAt(parameter_position));
   if (!param_type.IsInstantiated()) {
-    param_type = param_type.InstantiateFrom(type_arguments, malformed_error);
-    ASSERT((malformed_error == NULL) || malformed_error->IsNull());
+    param_type = param_type.InstantiateFrom(type_arguments, bound_error);
+    ASSERT((bound_error == NULL) || bound_error->IsNull());
   }
   if (param_type.IsDynamicType()) {
     return test_kind == kIsSubtypeOf;
   }
   if (test_kind == kIsSubtypeOf) {
-    if (!param_type.IsSubtypeOf(other_param_type, malformed_error) &&
-        !other_param_type.IsSubtypeOf(param_type, malformed_error)) {
+    if (!param_type.IsSubtypeOf(other_param_type, bound_error) &&
+        !other_param_type.IsSubtypeOf(param_type, bound_error)) {
       return false;
     }
   } else {
     ASSERT(test_kind == kIsMoreSpecificThan);
-    if (!param_type.IsMoreSpecificThan(other_param_type, malformed_error)) {
+    if (!param_type.IsMoreSpecificThan(other_param_type, bound_error)) {
       return false;
     }
   }
@@ -4453,7 +4498,7 @@
                         const AbstractTypeArguments& type_arguments,
                         const Function& other,
                         const AbstractTypeArguments& other_type_arguments,
-                        Error* malformed_error) const {
+                        Error* bound_error) const {
   const intptr_t num_fixed_params = num_fixed_parameters();
   const intptr_t num_opt_pos_params = NumOptionalPositionalParameters();
   const intptr_t num_opt_named_params = NumOptionalNamedParameters();
@@ -4481,26 +4526,26 @@
   AbstractType& other_res_type = AbstractType::Handle(other.result_type());
   if (!other_res_type.IsInstantiated()) {
     other_res_type = other_res_type.InstantiateFrom(other_type_arguments,
-                                                    malformed_error);
-    ASSERT((malformed_error == NULL) || malformed_error->IsNull());
+                                                    bound_error);
+    ASSERT((bound_error == NULL) || bound_error->IsNull());
   }
   if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) {
     AbstractType& res_type = AbstractType::Handle(result_type());
     if (!res_type.IsInstantiated()) {
-      res_type = res_type.InstantiateFrom(type_arguments, malformed_error);
-      ASSERT((malformed_error == NULL) || malformed_error->IsNull());
+      res_type = res_type.InstantiateFrom(type_arguments, bound_error);
+      ASSERT((bound_error == NULL) || bound_error->IsNull());
     }
     if (res_type.IsVoidType()) {
       return false;
     }
     if (test_kind == kIsSubtypeOf) {
-      if (!res_type.IsSubtypeOf(other_res_type, malformed_error) &&
-          !other_res_type.IsSubtypeOf(res_type, malformed_error)) {
+      if (!res_type.IsSubtypeOf(other_res_type, bound_error) &&
+          !other_res_type.IsSubtypeOf(res_type, bound_error)) {
         return false;
       }
     } else {
       ASSERT(test_kind == kIsMoreSpecificThan);
-      if (!res_type.IsMoreSpecificThan(other_res_type, malformed_error)) {
+      if (!res_type.IsMoreSpecificThan(other_res_type, bound_error)) {
         return false;
       }
     }
@@ -4511,7 +4556,7 @@
     if (!TestParameterType(test_kind,
                            i + num_ignored_params, i + other_num_ignored_params,
                            type_arguments, other, other_type_arguments,
-                           malformed_error)) {
+                           bound_error)) {
       return false;
     }
   }
@@ -4542,7 +4587,7 @@
         if (!TestParameterType(test_kind,
                                j, i,
                                type_arguments, other, other_type_arguments,
-                               malformed_error)) {
+                               bound_error)) {
           return false;
         }
         break;
@@ -4766,7 +4811,7 @@
     if (!type_parameters.IsNull()) {
       const String& function_class_name = String::Handle(function_class.Name());
       pieces.Add(function_class_name);
-      intptr_t num_type_parameters = type_parameters.Length();
+      const intptr_t num_type_parameters = type_parameters.Length();
       pieces.Add(Symbols::LAngleBracket());
       TypeParameter& type_parameter = TypeParameter::Handle();
       AbstractType& bound = AbstractType::Handle();
@@ -8330,7 +8375,7 @@
     GetHandlerInfo(i, &info);
     handled_types = GetHandledTypes(i);
     ASSERT(!handled_types.IsNull());
-    intptr_t num_types = handled_types.Length();
+    const intptr_t num_types = handled_types.Length();
     len += OS::SNPrint(NULL, 0, kFormat,
                        i,
                        info.handler_pc,
@@ -8349,7 +8394,7 @@
   for (intptr_t i = 0; i < Length(); i++) {
     GetHandlerInfo(i, &info);
     handled_types = GetHandledTypes(i);
-    intptr_t num_types = handled_types.Length();
+    const intptr_t num_types = handled_types.Length();
     num_chars += OS::SNPrint((buffer + num_chars),
                              (len - num_chars),
                              kFormat,
@@ -9050,7 +9095,7 @@
 
 
 void ContextScope::SetIsFinalAt(intptr_t scope_index, bool is_final) const {
-  VariableDescAddr(scope_index)->is_final = Bool::Get(is_final);
+  VariableDescAddr(scope_index)->is_final = Bool::Get(is_final).raw();
 }
 
 
@@ -9060,7 +9105,7 @@
 
 
 void ContextScope::SetIsConstAt(intptr_t scope_index, bool is_const) const {
-  VariableDescAddr(scope_index)->is_const = Bool::Get(is_const);
+  VariableDescAddr(scope_index)->is_const = Bool::Get(is_const).raw();
 }
 
 
@@ -10012,30 +10057,6 @@
 }
 
 
-static RawPatchClass* MakeTempPatchClass(const Class& cls,
-                                         const String& expr) {
-  String& src = String::Handle(String::New("() => "));
-  src = String::Concat(src, expr);
-  src = String::Concat(src, Symbols::Semicolon());
-  Script& script = Script::Handle();
-  script = Script::New(Symbols::Empty(), src, RawScript::kSourceTag);
-  // In order to tokenize the source, we need to get the key to mangle
-  // private names from the library from which the object's class
-  // originates.
-  const Library& lib = Library::Handle(cls.library());
-  ASSERT(!lib.IsNull());
-  const String& lib_key = String::Handle(lib.private_key());
-  script.Tokenize(lib_key);
-
-  const String& src_class_name = String::Handle(Symbols::New(":internal"));
-  const Class& src_class = Class::Handle(
-      Class::New(src_class_name, script, Scanner::kDummyTokenIndex));
-  src_class.set_is_finalized();
-  src_class.set_library(lib);
-  return PatchClass::New(cls, src_class);
-}
-
-
 RawObject* Instance::Evaluate(const String& expr) const {
   const Class& cls = Class::Handle(clazz());
   const PatchClass& temp_class =
@@ -10230,10 +10251,11 @@
 
 bool Instance::IsInstanceOf(const AbstractType& other,
                             const AbstractTypeArguments& other_instantiator,
-                            Error* malformed_error) const {
+                            Error* bound_error) const {
   ASSERT(other.IsFinalized());
   ASSERT(!other.IsDynamicType());
   ASSERT(!other.IsMalformed());
+  ASSERT(!other.IsMalbounded());
   if (other.IsVoidType()) {
     return false;
   }
@@ -10262,8 +10284,8 @@
   // Note that we may encounter a bound error in checked mode.
   if (!other.IsInstantiated()) {
     const AbstractType& instantiated_other = AbstractType::Handle(
-        other.InstantiateFrom(other_instantiator, malformed_error));
-    if ((malformed_error != NULL) && !malformed_error->IsNull()) {
+        other.InstantiateFrom(other_instantiator, bound_error));
+    if ((bound_error != NULL) && !bound_error->IsNull()) {
       ASSERT(FLAG_enable_type_checks);
       return false;
     }
@@ -10274,7 +10296,7 @@
     other_type_arguments = other.arguments();
   }
   return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments,
-                         malformed_error);
+                         bound_error);
 }
 
 
@@ -10460,6 +10482,13 @@
 }
 
 
+bool AbstractType::IsMalboundedWithError(Error* bound_error) const {
+  // AbstractType is an abstract class.
+  UNREACHABLE();
+  return false;
+}
+
+
 RawError* AbstractType::malformed_error() const {
   // AbstractType is an abstract class.
   UNREACHABLE();
@@ -10482,7 +10511,7 @@
 
 RawAbstractType* AbstractType::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* malformed_error) const {
+    Error* bound_error) const {
   // AbstractType is an abstract class.
   UNREACHABLE();
   return NULL;
@@ -10652,28 +10681,29 @@
 
 bool AbstractType::TypeTest(TypeTestKind test_kind,
                             const AbstractType& other,
-                            Error* malformed_error) const {
+                            Error* bound_error) const {
   ASSERT(IsResolved());
   ASSERT(other.IsResolved());
-  // In case the type checked in a type test is malformed, the code generator
+  ASSERT(!IsMalformed());
+  ASSERT(!other.IsMalformed());
+  // In case the type checked in a type test is malbounded, the code generator
   // may compile a throw instead of a run time call performing the type check.
-  // However, in checked mode, a function type may include malformed result type
-  // and/or malformed parameter types, which will then be encountered here at
-  // run time.
-  if (IsMalformed()) {
+  // However, in checked mode, a function type may include malbounded result
+  // type and/or malbounded parameter types, which will then be encountered here
+  // at run time.
+  if (IsMalbounded()) {
     ASSERT(FLAG_enable_type_checks);
-    if ((malformed_error != NULL) && malformed_error->IsNull()) {
-      *malformed_error = this->malformed_error();
+    if ((bound_error != NULL) && bound_error->IsNull()) {
+      const bool is_malbounded = IsMalboundedWithError(bound_error);
+      ASSERT(is_malbounded);
     }
     return false;
   }
-  if (other.IsMalformed()) {
-    // Note that 'other' may represent an unresolved bound that is checked at
-    // compile time, even in production mode, in which case the resulting
-    // BoundedType is ignored at run time if in production mode.
-    // Therefore, we cannot assert that we are in checked mode here.
-    if ((malformed_error != NULL) && malformed_error->IsNull()) {
-      *malformed_error = other.malformed_error();
+  if (other.IsMalbounded()) {
+    ASSERT(FLAG_enable_type_checks);
+    if ((bound_error != NULL) && bound_error->IsNull()) {
+      const bool other_is_malbounded = other.IsMalboundedWithError(bound_error);
+      ASSERT(other_is_malbounded);
     }
     return false;
   }
@@ -10704,7 +10734,7 @@
       }
     }
     const AbstractType& bound = AbstractType::Handle(type_param.bound());
-    if (bound.IsMoreSpecificThan(other, malformed_error)) {
+    if (bound.IsMoreSpecificThan(other, bound_error)) {
       return true;
     }
     return false;  // TODO(regis): We should return "maybe after instantiation".
@@ -10717,7 +10747,7 @@
                       AbstractTypeArguments::Handle(arguments()),
                       Class::Handle(other.type_class()),
                       AbstractTypeArguments::Handle(other.arguments()),
-                      malformed_error);
+                      bound_error);
 }
 
 
@@ -10857,6 +10887,30 @@
 }
 
 
+bool Type::IsMalboundedWithError(Error* bound_error) const {
+  if (!FLAG_enable_type_checks && !FLAG_error_on_bad_type) {
+    return false;
+  }
+  ASSERT(IsResolved());
+  ASSERT(!IsMalformed());  // Must be checked first.
+  if (arguments() == AbstractTypeArguments::null()) {
+    return false;
+  }
+  const AbstractTypeArguments& type_arguments =
+      AbstractTypeArguments::Handle(arguments());
+  const intptr_t num_type_args = type_arguments.Length();
+  AbstractType& type_arg = AbstractType::Handle();
+  for (intptr_t i = 0; i < num_type_args; i++) {
+    type_arg = type_arguments.TypeAt(i);
+    ASSERT(!type_arg.IsNull());
+    if (type_arg.IsMalboundedWithError(bound_error)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
 void Type::set_malformed_error(const Error& value) const {
   StorePointer(&raw_ptr()->malformed_error_, value.raw());
 }
@@ -10945,7 +10999,7 @@
 
 RawAbstractType* Type::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* malformed_error) const {
+    Error* bound_error) const {
   ASSERT(IsResolved());
   ASSERT(!IsInstantiated());
   // Return the uninstantiated type unchanged if malformed. No copy needed.
@@ -10955,7 +11009,7 @@
   AbstractTypeArguments& type_arguments =
       AbstractTypeArguments::Handle(arguments());
   type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments,
-                                                  malformed_error);
+                                                  bound_error);
   // Note that the type class has to be resolved at this time, but not
   // necessarily finalized yet. We may be checking bounds at compile time.
   const Class& cls = Class::Handle(type_class());
@@ -11218,7 +11272,7 @@
 
 RawAbstractType* TypeParameter::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* malformed_error) const {
+    Error* bound_error) const {
   ASSERT(IsFinalized());
   if (instantiator_type_arguments.IsNull()) {
     return Type::DynamicType();
@@ -11230,10 +11284,14 @@
       instantiator_type_arguments.TypeAt(index()));
   if (type_arg.IsBoundedType()) {
     const BoundedType& bounded_type = BoundedType::Cast(type_arg);
-    ASSERT(!bounded_type.IsInstantiated());
-    ASSERT(AbstractType::Handle(bounded_type.bound()).IsInstantiated());
-    type_arg = bounded_type.InstantiateFrom(AbstractTypeArguments::Handle(),
-                                            malformed_error);
+    // Bounds checking of a type is postponed to run time if the type is still
+    // uninstantiated at compile time, or if the bound and the type are mutually
+    // recursive. In the latter case, the type may already be instantiated.
+    if (!bounded_type.IsInstantiated()) {
+      ASSERT(AbstractType::Handle(bounded_type.bound()).IsInstantiated());
+      type_arg = bounded_type.InstantiateFrom(AbstractTypeArguments::Handle(),
+                                              bound_error);
+    }
   }
   return type_arg.raw();
 }
@@ -11241,15 +11299,15 @@
 
 bool TypeParameter::CheckBound(const AbstractType& bounded_type,
                                const AbstractType& upper_bound,
-                               Error* malformed_error) const {
-  ASSERT((malformed_error == NULL) || malformed_error->IsNull());
+                               Error* bound_error) const {
+  ASSERT((bound_error == NULL) || bound_error->IsNull());
   ASSERT(bounded_type.IsFinalized());
   ASSERT(upper_bound.IsFinalized());
   ASSERT(!bounded_type.IsMalformed());
-  if (bounded_type.IsSubtypeOf(upper_bound, malformed_error)) {
+  if (bounded_type.IsSubtypeOf(upper_bound, bound_error)) {
     return true;
   }
-  if ((malformed_error != NULL) && malformed_error->IsNull()) {
+  if ((bound_error != NULL) && bound_error->IsNull()) {
     // Report the bound error.
     const String& bounded_type_name = String::Handle(
         bounded_type.UserVisibleName());
@@ -11264,8 +11322,8 @@
     const Script& script = Script::Handle(cls.script());
     // Since the bound may have been canonicalized, its token index is
     // meaningless, therefore use the token index of this type parameter.
-    *malformed_error = FormatError(
-        *malformed_error,
+    *bound_error = FormatError(
+        *bound_error,
         script,
         token_pos(),
         "type parameter '%s' of class '%s' must extend bound '%s', "
@@ -11350,13 +11408,28 @@
 
 
 bool BoundedType::IsMalformed() const {
-  return FLAG_enable_type_checks && AbstractType::Handle(bound()).IsMalformed();
+  return AbstractType::Handle(type()).IsMalformed();
+}
+
+
+bool BoundedType::IsMalboundedWithError(Error* bound_error) const {
+  if (!FLAG_enable_type_checks && !FLAG_error_on_bad_type) {
+    return false;
+  }
+  const AbstractType& upper_bound = AbstractType::Handle(bound());
+  if (upper_bound.IsMalformed()) {
+    if (bound_error != NULL) {
+      *bound_error = upper_bound.malformed_error();
+      ASSERT(!bound_error->IsNull());
+    }
+    return true;
+  }
+  return false;
 }
 
 
 RawError* BoundedType::malformed_error() const {
-  ASSERT(FLAG_enable_type_checks);
-  return AbstractType::Handle(bound()).malformed_error();
+  return AbstractType::Handle(type()).malformed_error();
 }
 
 
@@ -11417,15 +11490,15 @@
 
 RawAbstractType* BoundedType::InstantiateFrom(
     const AbstractTypeArguments& instantiator_type_arguments,
-    Error* malformed_error) const {
+    Error* bound_error) const {
   ASSERT(IsFinalized());
   AbstractType& bounded_type = AbstractType::Handle(type());
   if (!bounded_type.IsInstantiated()) {
     bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments,
-                                                malformed_error);
+                                                bound_error);
   }
   if (FLAG_enable_type_checks &&
-      malformed_error->IsNull() &&
+      bound_error->IsNull() &&
       !is_being_checked()) {
     // Avoid endless recursion while checking and instantiating bound.
     set_is_being_checked(true);
@@ -11434,10 +11507,10 @@
     const TypeParameter& type_param = TypeParameter::Handle(type_parameter());
     if (!upper_bound.IsInstantiated()) {
       upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments,
-                                                malformed_error);
+                                                bound_error);
     }
-    if (malformed_error->IsNull()) {
-      type_param.CheckBound(bounded_type, upper_bound, malformed_error);
+    if (bound_error->IsNull()) {
+      type_param.CheckBound(bounded_type, upper_bound, bound_error);
     }
     set_is_being_checked(false);
   }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index d591d4e..79cd964 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -817,24 +817,24 @@
   bool IsSubtypeOf(const AbstractTypeArguments& type_arguments,
                    const Class& other,
                    const AbstractTypeArguments& other_type_arguments,
-                   Error* malformed_error) const {
+                   Error* bound_error) const {
     return TypeTest(kIsSubtypeOf,
                     type_arguments,
                     other,
                     other_type_arguments,
-                    malformed_error);
+                    bound_error);
   }
 
   // Check the 'more specific' relationship.
   bool IsMoreSpecificThan(const AbstractTypeArguments& type_arguments,
                           const Class& other,
                           const AbstractTypeArguments& other_type_arguments,
-                          Error* malformed_error) const {
+                          Error* bound_error) const {
     return TypeTest(kIsMoreSpecificThan,
                     type_arguments,
                     other,
                     other_type_arguments,
-                    malformed_error);
+                    bound_error);
   }
 
   // Check if this is the top level class.
@@ -949,6 +949,11 @@
   // Return true on success, or false and error otherwise.
   bool ApplyPatch(const Class& patch, Error* error) const;
 
+  // Evaluate the given expression as if it appeared in a static
+  // method of this class and return the resulting value, or an
+  // error object if evaluating the expression fails.
+  RawObject* Evaluate(const String& expr) const;
+
   RawError* EnsureIsFinalized(Isolate* isolate) const;
 
   // Allocate a class used for VM internal objects.
@@ -1062,7 +1067,7 @@
                 const AbstractTypeArguments& type_arguments,
                 const Class& other,
                 const AbstractTypeArguments& other_type_arguments,
-                Error* malformed_error) const;
+                Error* bound_error) const;
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Class, Object);
   friend class AbstractType;
@@ -1116,10 +1121,10 @@
   // not refer to type parameters. Otherwise, return a new type argument vector
   // where each reference to a type parameter is replaced with the corresponding
   // type of the instantiator type argument vector.
-  // If malformed_error is not NULL, it may be set to reflect a bound error.
+  // If bound_error is not NULL, it may be set to reflect a bound error.
   virtual RawAbstractTypeArguments* InstantiateFrom(
       const AbstractTypeArguments& instantiator_type_arguments,
-      Error* malformed_error) const;
+      Error* bound_error) const;
 
   // Do not canonicalize InstantiatedTypeArguments or NULL objects
   virtual RawAbstractTypeArguments* Canonicalize() const { return this->raw(); }
@@ -1152,16 +1157,16 @@
   // Check the subtype relationship, considering only a prefix of length 'len'.
   bool IsSubtypeOf(const AbstractTypeArguments& other,
                    intptr_t len,
-                   Error* malformed_error) const {
-    return TypeTest(kIsSubtypeOf, other, len, malformed_error);
+                   Error* bound_error) const {
+    return TypeTest(kIsSubtypeOf, other, len, bound_error);
   }
 
   // Check the 'more specific' relationship, considering only a prefix of
   // length 'len'.
   bool IsMoreSpecificThan(const AbstractTypeArguments& other,
                           intptr_t len,
-                          Error* malformed_error) const {
-    return TypeTest(kIsMoreSpecificThan, other, len, malformed_error);
+                          Error* bound_error) const {
+    return TypeTest(kIsMoreSpecificThan, other, len, bound_error);
   }
 
   bool Equals(const AbstractTypeArguments& other) const;
@@ -1191,7 +1196,7 @@
   bool TypeTest(TypeTestKind test_kind,
                 const AbstractTypeArguments& other,
                 intptr_t len,
-                Error* malformed_error) const;
+                Error* bound_error) const;
 
   // Return the internal or public name of a subvector of this type argument
   // vector, e.g. "<T, dynamic, List<T>, int>".
@@ -1226,7 +1231,7 @@
 
   virtual RawAbstractTypeArguments* InstantiateFrom(
       const AbstractTypeArguments& instantiator_type_arguments,
-      Error* malformed_error) const;
+      Error* bound_error) const;
 
   static const intptr_t kBytesPerElement = kWordSize;
   static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
@@ -1672,19 +1677,19 @@
   // parameters of the other function in order for this function to override the
   // other function.
   bool HasCompatibleParametersWith(const Function& other,
-                                   Error* malformed_error) const;
+                                   Error* bound_error) const;
 
   // Returns true if the type of this function is a subtype of the type of
   // the other function.
   bool IsSubtypeOf(const AbstractTypeArguments& type_arguments,
                    const Function& other,
                    const AbstractTypeArguments& other_type_arguments,
-                   Error* malformed_error) const {
+                   Error* bound_error) const {
     return TypeTest(kIsSubtypeOf,
                     type_arguments,
                     other,
                     other_type_arguments,
-                    malformed_error);
+                    bound_error);
   }
 
   // Returns true if the type of this function is more specific than the type of
@@ -1692,12 +1697,12 @@
   bool IsMoreSpecificThan(const AbstractTypeArguments& type_arguments,
                           const Function& other,
                           const AbstractTypeArguments& other_type_arguments,
-                          Error* malformed_error) const {
+                          Error* bound_error) const {
     return TypeTest(kIsMoreSpecificThan,
                     type_arguments,
                     other,
                     other_type_arguments,
-                    malformed_error);
+                    bound_error);
   }
 
   // Returns true if this function represents an explicit getter function.
@@ -1844,7 +1849,7 @@
                 const AbstractTypeArguments& type_arguments,
                 const Function& other,
                 const AbstractTypeArguments& other_type_arguments,
-                Error* malformed_error) const;
+                Error* bound_error) const;
 
   // Checks the type of the formal parameter at the given position for
   // subtyping or 'more specific' relationship between the type of this function
@@ -1855,7 +1860,7 @@
                          const AbstractTypeArguments& type_arguments,
                          const Function& other,
                          const AbstractTypeArguments& other_type_arguments,
-                         Error* malformed_error) const;
+                         Error* bound_error) const;
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Function, Object);
   friend class Class;
@@ -3701,7 +3706,7 @@
   // Check if the type of this instance is a subtype of the given type.
   bool IsInstanceOf(const AbstractType& type,
                     const AbstractTypeArguments& type_instantiator,
-                    Error* malformed_error) const;
+                    Error* bound_error) const;
 
   bool IsValidNativeIndex(int index) const {
     return ((index >= 0) && (index < clazz()->ptr()->num_native_fields_));
@@ -3761,6 +3766,8 @@
   virtual bool IsFinalized() const;
   virtual bool IsBeingFinalized() const;
   virtual bool IsMalformed() const;
+  virtual bool IsMalbounded() const { return IsMalboundedWithError(NULL); }
+  virtual bool IsMalboundedWithError(Error* bound_error) const;
   virtual RawError* malformed_error() const;
   virtual void set_malformed_error(const Error& value) const;
   virtual bool IsResolved() const;
@@ -3774,10 +3781,10 @@
 
   // Instantiate this type using the given type argument vector.
   // Return a new type, or return 'this' if it is already instantiated.
-  // If malformed_error is not NULL, it may be set to reflect a bound error.
+  // If bound_error is not NULL, it may be set to reflect a bound error.
   virtual RawAbstractType* InstantiateFrom(
       const AbstractTypeArguments& instantiator_type_arguments,
-      Error* malformed_error) const;
+      Error* bound_error) const;
 
   virtual RawInstance* CheckAndCanonicalize(const char** error_str) const {
     return Canonicalize();
@@ -3846,21 +3853,21 @@
   bool IsFunctionType() const;
 
   // Check the subtype relationship.
-  bool IsSubtypeOf(const AbstractType& other, Error* malformed_error) const {
-    return TypeTest(kIsSubtypeOf, other, malformed_error);
+  bool IsSubtypeOf(const AbstractType& other, Error* bound_error) const {
+    return TypeTest(kIsSubtypeOf, other, bound_error);
   }
 
   // Check the 'more specific' relationship.
   bool IsMoreSpecificThan(const AbstractType& other,
-                          Error* malformed_error) const {
-    return TypeTest(kIsMoreSpecificThan, other, malformed_error);
+                          Error* bound_error) const {
+    return TypeTest(kIsMoreSpecificThan, other, bound_error);
   }
 
  private:
   // Check the subtype or 'more specific' relationship.
   bool TypeTest(TypeTestKind test_kind,
                 const AbstractType& other,
-                Error* malformed_error) const;
+                Error* bound_error) const;
 
   // Return the internal or public name of this type, including the names of its
   // type arguments, if any.
@@ -3898,6 +3905,8 @@
   }
   void set_is_being_finalized() const;
   virtual bool IsMalformed() const;
+  virtual bool IsMalbounded() const { return IsMalboundedWithError(NULL); }
+  virtual bool IsMalboundedWithError(Error* bound_error) const;
   virtual RawError* malformed_error() const;
   virtual void set_malformed_error(const Error& value) const;
   virtual bool IsResolved() const;  // Class and all arguments classes resolved.
@@ -4005,6 +4014,8 @@
   void set_is_finalized() const;
   virtual bool IsBeingFinalized() const { return false; }
   virtual bool IsMalformed() const { return false; }
+  virtual bool IsMalbounded() const { return false; }
+  virtual bool IsMalboundedWithError(Error* bound_error) const { return false; }
   virtual bool IsResolved() const { return true; }
   virtual bool HasResolvedTypeClass() const { return false; }
   RawClass* parameterized_class() const {
@@ -4016,16 +4027,16 @@
   RawAbstractType* bound() const { return raw_ptr()->bound_; }
   void set_bound(const AbstractType& value) const;
   // Returns true if bounded_type is below upper_bound, otherwise return false
-  // and set malformed_error if not NULL.
+  // and set bound_error if not NULL.
   bool CheckBound(const AbstractType& bounded_type,
                   const AbstractType& upper_bound,
-                  Error* malformed_error) const;
+                  Error* bound_error) const;
   virtual intptr_t token_pos() const { return raw_ptr()->token_pos_; }
   virtual bool IsInstantiated() const { return false; }
   virtual bool Equals(const Instance& other) const;
   virtual RawAbstractType* InstantiateFrom(
       const AbstractTypeArguments& instantiator_type_arguments,
-      Error* malformed_error) const;
+      Error* bound_error) const;
   virtual RawAbstractType* Canonicalize() const { return raw(); }
 
   virtual intptr_t Hash() const;
@@ -4067,6 +4078,8 @@
     return AbstractType::Handle(type()).IsBeingFinalized();
   }
   virtual bool IsMalformed() const;
+  virtual bool IsMalbounded() const { return IsMalboundedWithError(NULL); }
+  virtual bool IsMalboundedWithError(Error* bound_error) const;
   virtual RawError* malformed_error() const;
   virtual bool IsResolved() const { return true; }
   virtual bool HasResolvedTypeClass() const {
@@ -4095,7 +4108,7 @@
   virtual bool Equals(const Instance& other) const;
   virtual RawAbstractType* InstantiateFrom(
       const AbstractTypeArguments& instantiator_type_arguments,
-      Error* malformed_error) const;
+      Error* bound_error) const;
   virtual RawAbstractType* Canonicalize() const { return raw(); }
 
   virtual intptr_t Hash() const;
@@ -4134,7 +4147,9 @@
  public:
   // MixinAppType objects are replaced with their actual finalized type.
   virtual bool IsFinalized() const { return false; }
+  // TODO(regis): Handle malformed and malbounded MixinAppType.
   virtual bool IsMalformed() const { return false; }
+  virtual bool IsMalbounded() const { return false; }
   virtual bool IsResolved() const { return false; }
   virtual bool HasResolvedTypeClass() const { return false; }
   virtual RawString* Name() const;
@@ -5086,8 +5101,8 @@
     return Object::bool_false();
   }
 
-  static RawBool* Get(bool value) {
-    return value ? Bool::True().raw() : Bool::False().raw();
+  static const Bool& Get(bool value) {
+    return value ? Bool::True() : Bool::False();
   }
 
  private:
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 5a14414..450f581 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -346,7 +346,6 @@
 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
   const int kMinimumAlignment = 16;
 #elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
-  // TODO(regis): Verify alignment constraints on MIPS.
   const int kMinimumAlignment = 8;
 #else
 #error Unsupported architecture.
@@ -365,7 +364,6 @@
 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
   const int kMinimumAlignment = 32;
 #elif defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
-  // TODO(regis): Verify alignment constraints on MIPS.
   const int kMinimumAlignment = 16;
 #else
 #error Unsupported architecture.
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index cdbb608..e5e13fc 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -30,7 +30,7 @@
 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations.");
 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors.");
 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings.");
-DECLARE_FLAG(bool, error_on_malformed_type);
+DECLARE_FLAG(bool, error_on_bad_type);
 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
 
 static void CheckedModeHandler(bool value) {
@@ -775,6 +775,48 @@
 }
 
 
+RawObject* Parser::ParseFunctionParameters(const Function& func) {
+  ASSERT(!func.IsNull());
+  Isolate* isolate = Isolate::Current();
+  StackZone zone(isolate);
+  LongJump* base = isolate->long_jump_base();
+  LongJump jump;
+  isolate->set_long_jump_base(&jump);
+  if (setjmp(*jump.Set()) == 0) {
+    const Script& script = Script::Handle(isolate, func.script());
+    const Class& owner = Class::Handle(isolate, func.Owner());
+    ASSERT(!owner.IsNull());
+    const Library& lib = Library::Handle(isolate, owner.library());
+    Parser parser(script, lib, func.token_pos());
+    parser.set_current_class(owner);
+    parser.SkipFunctionPreamble();
+    ParamList params;
+    parser.ParseFormalParameterList(true, &params);
+    ParamDesc* param = params.parameters->data();
+    const int param_cnt = params.num_fixed_parameters +
+                          params.num_optional_parameters;
+    Array& param_descriptor = Array::Handle(isolate, Array::New(param_cnt * 2));
+    for (int i = 0, j = 0; i < param_cnt; i++, j += 2) {
+      param_descriptor.SetAt(j, param[i].is_final ? Bool::True() :
+                                                    Bool::False());
+      param_descriptor.SetAt(j + 1,
+          (param[i].default_value == NULL) ? Object::null_instance() :
+                                             *(param[i].default_value));
+    }
+    isolate->set_long_jump_base(base);
+    return param_descriptor.raw();
+  } else {
+    Error& error = Error::Handle();
+    error = isolate->object_store()->sticky_error();
+    isolate->object_store()->clear_sticky_error();
+    isolate->set_long_jump_base(base);
+    return error.raw();
+  }
+  UNREACHABLE();
+  return Object::null();
+}
+
+
 void Parser::ParseFunction(ParsedFunction* parsed_function) {
   TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer);
   Isolate* isolate = Isolate::Current();
@@ -1410,6 +1452,11 @@
     params->has_field_initializer = true;
   }
 
+  if (params->has_optional_named_parameters &&
+      (parameter.name->CharAt(0) == '_')) {
+    ErrorMsg(parameter.name_pos, "named parameter must not be private");
+  }
+
   // Check for duplicate formal parameters.
   const intptr_t num_existing_parameters =
       params->num_fixed_parameters + params->num_optional_parameters;
@@ -1591,7 +1638,6 @@
   }
   String& native_name = *CurrentLiteral();
   ConsumeToken();
-  ExpectSemicolon();
   return native_name;
 }
 
@@ -2701,57 +2747,56 @@
   }
   ASSERT((CurrentToken() == Token::kLPAREN) || func.IsGetterFunction());
   const bool allow_explicit_default_values = true;
-  if (!func.IsGetterFunction()) {
-    ParseFormalParameterList(allow_explicit_default_values, &params);
+  if (func.IsGetterFunction()) {
+    // Populate function scope with the formal parameters. Since in this case
+    // we are compiling a getter this will at most populate the receiver.
+    AddFormalParamsToScope(&params, current_block_->scope);
   } else {
-    // TODO(hausner): Remove this once we no longer support the old
-    // getter syntax with explicit empty parameter list.
-    if (CurrentToken() == Token::kLPAREN) {
-      ConsumeToken();
-      ExpectToken(Token::kRPAREN);
+    ParseFormalParameterList(allow_explicit_default_values, &params);
+
+    // The number of parameters and their type are not yet set in local
+    // functions, since they are not 'top-level' parsed.
+    if (func.IsLocalFunction()) {
+      AddFormalParamsToFunction(&params, func);
     }
-  }
+    SetupDefaultsForOptionalParams(&params, default_parameter_values);
+    ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
+    ASSERT(func.NumParameters() == params.parameters->length());
 
-  // The number of parameters and their type are not yet set in local functions,
-  // since they are not 'top-level' parsed.
-  if (func.IsLocalFunction()) {
-    AddFormalParamsToFunction(&params, func);
-  }
-  SetupDefaultsForOptionalParams(&params, default_parameter_values);
-  ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
-  ASSERT(func.NumParameters() == params.parameters->length());
-
-  // Check whether the function has any field initializer formal parameters,
-  // which are not allowed in non-constructor functions.
-  if (params.has_field_initializer) {
-    for (int i = 0; i < params.parameters->length(); i++) {
-      ParamDesc& param = (*params.parameters)[i];
-      if (param.is_field_initializer) {
-        ErrorMsg(param.name_pos,
-                 "field initializer only allowed in constructors");
+    // Check whether the function has any field initializer formal parameters,
+    // which are not allowed in non-constructor functions.
+    if (params.has_field_initializer) {
+      for (int i = 0; i < params.parameters->length(); i++) {
+        ParamDesc& param = (*params.parameters)[i];
+        if (param.is_field_initializer) {
+          ErrorMsg(param.name_pos,
+                   "field initializer only allowed in constructors");
+        }
       }
     }
-  }
-  // Populate function scope with the formal parameters.
-  AddFormalParamsToScope(&params, current_block_->scope);
+    // Populate function scope with the formal parameters.
+    AddFormalParamsToScope(&params, current_block_->scope);
 
-  if (FLAG_enable_type_checks &&
-      (current_block_->scope->function_level() > 0)) {
-    // We are parsing, but not compiling, a local function.
-    // The instantiator may be required at run time for generic type checks.
-    if (IsInstantiatorRequired()) {
-      // Make sure that the receiver of the enclosing instance function
-      // (or implicit first parameter of an enclosing factory) is marked as
-      // captured if type checks are enabled, because they may access it to
-      // instantiate types.
-      CaptureInstantiator();
+    if (FLAG_enable_type_checks &&
+        (current_block_->scope->function_level() > 0)) {
+      // We are parsing, but not compiling, a local function.
+      // The instantiator may be required at run time for generic type checks.
+      if (IsInstantiatorRequired()) {
+        // Make sure that the receiver of the enclosing instance function
+        // (or implicit first parameter of an enclosing factory) is marked as
+        // captured if type checks are enabled, because they may access it to
+        // instantiate types.
+        CaptureInstantiator();
+      }
     }
   }
 
   OpenBlock();  // Open a nested scope for the outermost function block.
+  intptr_t end_token_pos = 0;
   if (CurrentToken() == Token::kLBRACE) {
     ConsumeToken();
     ParseStatementSequence();
+    end_token_pos = TokenPos();
     ExpectToken(Token::kRBRACE);
   } else if (CurrentToken() == Token::kARROW) {
     ConsumeToken();
@@ -2759,8 +2804,11 @@
     AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
     ASSERT(expr != NULL);
     current_block_->statements->Add(new ReturnNode(expr_pos, expr));
+    end_token_pos = TokenPos();
   } else if (IsLiteral("native")) {
     ParseNativeFunctionBlock(&params, func);
+    end_token_pos = TokenPos();
+    ExpectSemicolon();
   } else if (func.is_external()) {
     // Body of an external method contains a single throw.
     const String& function_name = String::ZoneHandle(func.name());
@@ -2774,9 +2822,13 @@
                                    InvocationMirror::kStatic :
                                    InvocationMirror::kDynamic,
                                InvocationMirror::kMethod));
+    end_token_pos = TokenPos();
   } else {
     UnexpectedToken();
   }
+  ASSERT(func.end_token_pos() == func.token_pos() ||
+         func.end_token_pos() == end_token_pos);
+  func.set_end_token_pos(end_token_pos);
   SequenceNode* body = CloseBlock();
   current_block_->statements->Add(body);
   innermost_function_ = saved_innermost_function.raw();
@@ -2988,6 +3040,7 @@
           method->name->ToCString(),
           String::Handle(type.UserVisibleName()).ToCString());
     } else {
+      // TODO(regis): What if the redirection type is malbounded?
       redirection_type ^= type.raw();
     }
     if (CurrentToken() == Token::kPERIOD) {
@@ -3075,6 +3128,8 @@
                "Constructor with redirection may not have a function body");
     }
     ParseNativeDeclaration();
+    method_end_pos = TokenPos();
+    ExpectSemicolon();
   } else {
     // We haven't found a method body. Issue error if one is required.
     const bool must_have_body =
@@ -3813,7 +3868,8 @@
 }
 
 
-void Parser::ParseMixinTypedef(const GrowableObjectArray& pending_classes) {
+void Parser::ParseMixinTypedef(const GrowableObjectArray& pending_classes,
+                               intptr_t metadata_pos) {
   TRACE_PARSER("ParseMixinTypedef");
   const intptr_t classname_pos = TokenPos();
   String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected");
@@ -3866,6 +3922,9 @@
   }
   ExpectSemicolon();
   pending_classes.Add(mixin_application, Heap::kOld);
+  if (metadata_pos >= 0) {
+    library_.AddClassMetadata(mixin_application, metadata_pos);
+  }
 }
 
 
@@ -3909,12 +3968,13 @@
 }
 
 
-void Parser::ParseTypedef(const GrowableObjectArray& pending_classes) {
+void Parser::ParseTypedef(const GrowableObjectArray& pending_classes,
+                          intptr_t metadata_pos) {
   TRACE_PARSER("ParseTypedef");
   ExpectToken(Token::kTYPEDEF);
 
   if (IsMixinTypedef()) {
-    ParseMixinTypedef(pending_classes);
+    ParseMixinTypedef(pending_classes, metadata_pos);
     return;
   }
 
@@ -4021,6 +4081,9 @@
   ASSERT(!function_type_alias.IsCanonicalSignatureClass());
   ASSERT(!function_type_alias.is_finalized());
   pending_classes.Add(function_type_alias, Heap::kOld);
+  if (metadata_pos >= 0) {
+    library_.AddClassMetadata(function_type_alias, metadata_pos);
+  }
 }
 
 
@@ -4424,6 +4487,7 @@
 
   intptr_t function_end_pos = function_pos;
   if (is_external) {
+    function_end_pos = TokenPos();
     ExpectSemicolon();
   } else if (CurrentToken() == Token::kLBRACE) {
     SkipBlock();
@@ -4431,10 +4495,12 @@
   } else if (CurrentToken() == Token::kARROW) {
     ConsumeToken();
     SkipExpr();
+    function_end_pos = TokenPos();
     ExpectSemicolon();
-    function_end_pos = TokenPos() - 1;
   } else if (IsLiteral("native")) {
     ParseNativeDeclaration();
+    function_end_pos = TokenPos();
+    ExpectSemicolon();
   } else {
     ErrorMsg("function block expected");
   }
@@ -4549,6 +4615,7 @@
 
   intptr_t accessor_end_pos = accessor_pos;
   if (is_external) {
+    accessor_end_pos = TokenPos();
     ExpectSemicolon();
   } else if (CurrentToken() == Token::kLBRACE) {
     SkipBlock();
@@ -4556,10 +4623,12 @@
   } else if (CurrentToken() == Token::kARROW) {
     ConsumeToken();
     SkipExpr();
+    accessor_end_pos = TokenPos();
     ExpectSemicolon();
-    accessor_end_pos = TokenPos() - 1;
   } else if (IsLiteral("native")) {
     ParseNativeDeclaration();
+    accessor_end_pos = TokenPos();
+    ExpectSemicolon();
   } else {
     ErrorMsg("function block expected");
   }
@@ -4869,7 +4938,7 @@
     } else if ((CurrentToken() == Token::kTYPEDEF) &&
                (LookaheadToken(1) != Token::kLPAREN)) {
       set_current_class(toplevel_class);
-      ParseTypedef(pending_classes);
+      ParseTypedef(pending_classes, metadata_pos);
     } else if ((CurrentToken() == Token::kABSTRACT) &&
         (LookaheadToken(1) == Token::kCLASS)) {
       ParseClassDeclaration(pending_classes, metadata_pos);
@@ -5365,8 +5434,6 @@
   Array& default_parameter_values = Array::Handle();
   SequenceNode* statements = Parser::ParseFunc(function,
                                                default_parameter_values);
-  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
@@ -5438,6 +5505,7 @@
       const Error& error = Error::Handle(signature_type.malformed_error());
       function_type.set_malformed_error(error);
     }
+    // TODO(regis): What if the signature is malbounded?
 
     // The function type was initially marked as instantiated, but it may
     // actually be uninstantiated.
@@ -5874,7 +5942,7 @@
 
 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value,
                                   SourceLabel* case_label) {
-  TRACE_PARSER("ParseCaseStatement");
+  TRACE_PARSER("ParseCaseClause");
   bool default_seen = false;
   const intptr_t case_pos = TokenPos();
   // The case expressions node sequence does not own the enclosing scope.
@@ -5886,7 +5954,7 @@
       }
       ConsumeToken();  // Keyword case.
       const intptr_t expr_pos = TokenPos();
-      AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
+      AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades);
       AstNode* switch_expr_load = new LoadLocalNode(case_pos,
                                                     switch_expr_value);
       AstNode* case_comparison = new ComparisonNode(expr_pos,
@@ -5955,19 +6023,10 @@
   SourceLabel* label =
       SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch);
   ConsumeToken();
-  const bool parens_are_mandatory = false;
-  bool paren_found = false;
-  if (CurrentToken() == Token::kLPAREN) {
-    paren_found = true;
-    ConsumeToken();
-  } else if (parens_are_mandatory) {
-    ErrorMsg("'(' expected");
-  }
+  ExpectToken(Token::kLPAREN);
   const intptr_t expr_pos = TokenPos();
   AstNode* switch_expr = ParseExpr(kAllowConst, kConsumeCascades);
-  if (paren_found) {
-    ExpectToken(Token::kRPAREN);
-  }
+  ExpectToken(Token::kRPAREN);
   ExpectToken(Token::kLBRACE);
   OpenBlock();
   current_block_->scope->AddLabel(label);
@@ -6004,7 +6063,7 @@
         // the forward reference.
         case_label->ResolveForwardReference();
       } else {
-        ErrorMsg(label_pos, "name '%s' already exists in scope",
+        ErrorMsg(label_pos, "label '%s' already exists in scope",
                  label_name->ToCString());
       }
       ASSERT(case_label->kind() == SourceLabel::kCase);
@@ -6026,6 +6085,9 @@
     }
   }
 
+  // TODO(hausner): Check that all expressions in case clauses are
+  // of the same class, or implement int or String (issue 7307).
+
   // Check for unresolved label references.
   SourceLabel* unresolved_label =
       current_block_->scope->CheckUnresolvedLabels();
@@ -7112,7 +7174,6 @@
 
 
 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) {
-  ASSERT(type.IsMalformed());
   ArgumentListNode* arguments = new ArgumentListNode(type_pos);
   // Location argument.
   arguments->Add(new LiteralNode(
@@ -7123,8 +7184,14 @@
   arguments->Add(new LiteralNode(type_pos, Symbols::Malformed()));
   // Dst name argument.
   arguments->Add(new LiteralNode(type_pos, Symbols::Empty()));
-  // Malformed type error.
-  const Error& error = Error::Handle(type.malformed_error());
+  // Malformed type error or malbounded type error.
+  Error& error = Error::Handle();
+  if (type.IsMalformed()) {
+    error = type.malformed_error();
+  } else {
+    const bool is_malbounded = type.IsMalboundedWithError(&error);
+    ASSERT(is_malbounded);
+  }
   arguments->Add(new LiteralNode(type_pos, String::ZoneHandle(
       Symbols::New(error.ToErrorCString()))));
   return MakeStaticCall(Symbols::TypeError(),
@@ -7224,10 +7291,11 @@
           CaptureInstantiator();
         }
         right_operand = new TypeNode(type_pos, type);
-        // If the type is malformed, it is actually malbounded in checked mode.
-        ASSERT(!type.IsMalformed() || FLAG_enable_type_checks);
+        // The type is never malformed (mapped to dynamic), but it can be
+        // malbounded in checked mode.
+        ASSERT(!type.IsMalformed());
         if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT)) &&
-            type.IsMalformed()) {
+            type.IsMalbounded()) {
           // Note that a type error is thrown even if the tested value is null
           // in a type test. However, no cast exception is thrown if the value
           // is null in a type cast.
@@ -8261,7 +8329,7 @@
           if (ParsingStaticMember()) {
             ASSERT(scope_class.raw() == current_class().raw());
             if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) ||
-                FLAG_error_on_malformed_type) {
+                FLAG_error_on_bad_type) {
               *type = ClassFinalizer::NewFinalizedMalformedType(
                   Error::Handle(),  // No previous error.
                   scope_class,
@@ -8279,7 +8347,7 @@
           // malformed if type arguments have previously been parsed.
           if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) {
             if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) ||
-                FLAG_error_on_malformed_type) {
+                FLAG_error_on_bad_type) {
               *type = ClassFinalizer::NewFinalizedMalformedType(
                   Error::Handle(),  // No previous error.
                   scope_class,
@@ -8307,7 +8375,7 @@
             &error);
         if (!error.IsNull()) {
           if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) ||
-              FLAG_error_on_malformed_type) {
+              FLAG_error_on_bad_type) {
             *type = ClassFinalizer::NewFinalizedMalformedType(
                 error,
                 scope_class,
@@ -8333,7 +8401,7 @@
           &error);
       if (!error.IsNull()) {
         if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) ||
-            FLAG_error_on_malformed_type) {
+            FLAG_error_on_bad_type) {
           *type = ClassFinalizer::NewFinalizedMalformedType(
               error,
               scope_class,
@@ -8354,7 +8422,7 @@
       parameterized_type.set_type_class(resolved_type_class);
     } else if (finalization >= ClassFinalizer::kCanonicalize) {
       if ((finalization == ClassFinalizer::kCanonicalizeWellFormed) ||
-          FLAG_error_on_malformed_type) {
+          FLAG_error_on_bad_type) {
         ClassFinalizer::FinalizeMalformedType(
             Error::Handle(),  // No previous error.
             scope_class,
@@ -9155,7 +9223,7 @@
     if (list_type_arguments.Length() == 1) {
       element_type = list_type_arguments.TypeAt(0);
     } else {
-      if (FLAG_error_on_malformed_type) {
+      if (FLAG_error_on_bad_type) {
         ErrorMsg(type_pos,
                  "a list literal takes one type argument specifying "
                  "the element type");
@@ -9353,7 +9421,7 @@
                  "a type variable");
       }
       if (key_type.IsMalformed()) {
-        if (FLAG_error_on_malformed_type) {
+        if (FLAG_error_on_bad_type) {
           ErrorMsg(Error::Handle(key_type.malformed_error()));
         }
         // Map malformed key type to dynamic.
@@ -9361,7 +9429,7 @@
         map_type_arguments.SetTypeAt(0, key_type);
       }
       if (value_type.IsMalformed()) {
-        if (FLAG_error_on_malformed_type) {
+        if (FLAG_error_on_bad_type) {
           ErrorMsg(Error::Handle(value_type.malformed_error()));
         }
         // Map malformed value type to dynamic.
@@ -9369,7 +9437,7 @@
         map_type_arguments.SetTypeAt(1, value_type);
       }
     } else {
-      if (FLAG_error_on_malformed_type) {
+      if (FLAG_error_on_bad_type) {
         ErrorMsg(type_pos,
                  "a map literal takes two type arguments specifying "
                  "the key type and the value type");
@@ -9592,16 +9660,29 @@
       ParseType(ClassFinalizer::kCanonicalizeWellFormed));
   // In case the type is malformed, throw a dynamic type error after finishing
   // parsing the instance creation expression.
-  if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) {
-    // Replace the type with a malformed type.
-    type = ClassFinalizer::NewFinalizedMalformedType(
-        Error::Handle(),  // No previous error.
-        current_class(),
-        type_pos,
-        "%s'%s' cannot be instantiated",
-        type.IsTypeParameter() ? "type parameter " : "",
-        type.IsTypeParameter() ?
-            String::Handle(type.UserVisibleName()).ToCString() : "dynamic");
+  if (!type.IsMalformed()) {
+    if (type.IsTypeParameter() || type.IsDynamicType()) {
+      // Replace the type with a malformed type.
+      type = ClassFinalizer::NewFinalizedMalformedType(
+          Error::Handle(),  // No previous error.
+          current_class(),
+          type_pos,
+          "%s'%s' cannot be instantiated",
+          type.IsTypeParameter() ? "type parameter " : "",
+          type.IsTypeParameter() ?
+              String::Handle(type.UserVisibleName()).ToCString() : "dynamic");
+    } else if (FLAG_enable_type_checks || FLAG_error_on_bad_type) {
+      Error& bound_error = Error::Handle();
+      if (type.IsMalboundedWithError(&bound_error)) {
+        // Replace the type with a malformed type.
+        type = ClassFinalizer::NewFinalizedMalformedType(
+            bound_error,
+            current_class(),
+            type_pos,
+            "malbounded type '%s' cannot be instantiated",
+            String::Handle(type.UserVisibleName()).ToCString());
+      }
+    }
   }
 
   // The grammar allows for an optional ('.' identifier)? after the type, which
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index e7161a5..e5e53ec 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -144,6 +144,15 @@
   // class if the metadata is at the top-level).
   static RawObject* ParseMetadata(const Class& cls, intptr_t token_pos);
 
+  // Parse a function func and retrieve parameter information that can not be
+  // found in its function object. Returns either an error if the parser fails
+  // (which could be the case for local functions), or a flat array of the size
+  // (2*number_of_parameters). For each parameter i in this array, (2*i)
+  // contains a bool indicating whether the parameter has been final, and
+  // (2*i+1) contains an array of its default values (or null if it has no
+  // default values).
+  static RawObject* ParseFunctionParameters(const Function& func);
+
   // Format and print a message with source location.
   // A null script means no source and a negative token_pos means no position.
   static void PrintMessage(const Script& script,
@@ -337,8 +346,10 @@
   void ParseClassDeclaration(const GrowableObjectArray& pending_classes,
                              intptr_t metadata_pos);
   void ParseClassDefinition(const Class& cls);
-  void ParseMixinTypedef(const GrowableObjectArray& pending_classes);
-  void ParseTypedef(const GrowableObjectArray& pending_classes);
+  void ParseMixinTypedef(const GrowableObjectArray& pending_classes,
+                         intptr_t metadata_pos);
+  void ParseTypedef(const GrowableObjectArray& pending_classes,
+                    intptr_t metadata_pos);
   void ParseTopLevelVariable(TopLevel* top_level, intptr_t metadata_pos);
   void ParseTopLevelFunction(TopLevel* top_level, intptr_t metadata_pos);
   void ParseTopLevelAccessor(TopLevel* top_level, intptr_t metadata_pos);
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index ab17198..cd5edf9 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -11,7 +11,7 @@
 
 namespace dart {
 
-DECLARE_FLAG(bool, error_on_malformed_type);
+DECLARE_FLAG(bool, error_on_bad_type);
 
 
 #define NEW_OBJECT(type)                                                       \
@@ -247,7 +247,7 @@
 
   // Only resolved and finalized types should be written to a snapshot.
   // TODO(regis): Replace the test below by an ASSERT() or remove the flag test.
-  if (FLAG_error_on_malformed_type &&
+  if (FLAG_error_on_bad_type &&
       (ptr()->type_state_ != RawType::kFinalizedInstantiated) &&
       (ptr()->type_state_ != RawType::kFinalizedUninstantiated)) {
     // Print the name of the class of the unfinalized type, as well as the
@@ -335,7 +335,7 @@
 
   // Only finalized type parameters should be written to a snapshot.
   // TODO(regis): Replace the test below by an ASSERT() or remove the flag test.
-  if (FLAG_error_on_malformed_type &&
+  if (FLAG_error_on_bad_type &&
       (ptr()->type_state_ != RawTypeParameter::kFinalizedUninstantiated)) {
     // Print the name of the unfinalized type parameter, the name of the class
     // it parameterizes, as well as the token location from where it is referred
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index fd2cfbc..904eb1b 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -16,6 +16,7 @@
     'collection_dev_cc_file': '<(gen_source_dir)/collection_dev_gen.cc',
     'collection_dev_patch_cc_file': '<(gen_source_dir)/collection_dev_patch_gen.cc',
     'convert_cc_file': '<(gen_source_dir)/convert_gen.cc',
+    'convert_patch_cc_file': '<(gen_source_dir)/convert_patch_gen.cc',
     'math_cc_file': '<(gen_source_dir)/math_gen.cc',
     'math_patch_cc_file': '<(gen_source_dir)/math_patch_gen.cc',
     'mirrors_cc_file': '<(gen_source_dir)/mirrors_gen.cc',
@@ -23,7 +24,6 @@
     'isolate_cc_file': '<(gen_source_dir)/isolate_gen.cc',
     'isolate_patch_cc_file': '<(gen_source_dir)/isolate_patch_gen.cc',
     'json_cc_file': '<(gen_source_dir)/json_gen.cc',
-    'json_patch_cc_file': '<(gen_source_dir)/json_patch_gen.cc',
     'typed_data_cc_file': '<(gen_source_dir)/typed_data_gen.cc',
     'typed_data_patch_cc_file': '<(gen_source_dir)/typed_data_patch_gen.cc',
     'utf_cc_file': '<(gen_source_dir)/utf_gen.cc',
@@ -103,12 +103,12 @@
         'generate_collection_dev_cc_file#host',
         'generate_collection_dev_patch_cc_file#host',
         'generate_convert_cc_file#host',
+        'generate_convert_patch_cc_file#host',
         'generate_math_cc_file#host',
         'generate_math_patch_cc_file#host',
         'generate_isolate_cc_file#host',
         'generate_isolate_patch_cc_file#host',
         'generate_json_cc_file#host',
-        'generate_json_patch_cc_file#host',
         'generate_mirrors_cc_file#host',
         'generate_mirrors_patch_cc_file#host',
         'generate_typed_data_cc_file#host',
@@ -136,12 +136,12 @@
         '<(collection_dev_cc_file)',
         '<(collection_dev_patch_cc_file)',
         '<(convert_cc_file)',
+        '<(convert_patch_cc_file)',
         '<(math_cc_file)',
         '<(math_patch_cc_file)',
         '<(isolate_cc_file)',
         '<(isolate_patch_cc_file)',
         '<(json_cc_file)',
-        '<(json_patch_cc_file)',
         '<(mirrors_cc_file)',
         '<(mirrors_patch_cc_file)',
         '<(typed_data_cc_file)',
@@ -452,6 +452,46 @@
       ]
     },
     {
+      'target_name': 'generate_convert_patch_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'includes': [
+        # Load the shared convert library sources.
+        '../lib/convert_sources.gypi',
+      ],
+      'sources/': [
+        # Exclude all .[cc|h] files.
+        # This is only here for reference. Excludes happen after
+        # variable expansion, so the script has to do its own
+        # exclude processing of the sources being passed.
+        ['exclude', '\\.cc|h$'],
+      ],
+      'actions': [
+        {
+          'action_name': 'generate_convert_patch_cc',
+          'inputs': [
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
+          ],
+          'outputs': [
+            '<(convert_patch_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/gen_library_src_paths.py',
+            '--output', '<(convert_patch_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
+            '--include', 'vm/bootstrap.h',
+            '--var_name', 'dart::Bootstrap::convert_patch_paths_',
+            '--library_name', 'dart:convert',
+            '<@(_sources)',
+          ],
+          'message': 'Generating ''<(convert_patch_cc_file)'' file.'
+        },
+      ]
+    },
+    {
       'target_name': 'generate_math_cc_file',
       'type': 'none',
       'toolsets':['host'],
@@ -805,46 +845,6 @@
       ]
     },
     {
-      'target_name': 'generate_json_patch_cc_file',
-      'type': 'none',
-      'toolsets':['host'],
-      'includes': [
-        # Load the shared json library sources.
-        '../lib/json_sources.gypi',
-      ],
-      'sources/': [
-        # Exclude all .[cc|h] files.
-        # This is only here for reference. Excludes happen after
-        # variable expansion, so the script has to do its own
-        # exclude processing of the sources being passed.
-        ['exclude', '\\.cc|h$'],
-      ],
-      'actions': [
-        {
-          'action_name': 'generate_json_patch_cc',
-          'inputs': [
-            '../tools/gen_library_src_paths.py',
-            '<(libgen_in_cc_file)',
-            '<@(_sources)',
-          ],
-          'outputs': [
-            '<(json_patch_cc_file)',
-          ],
-          'action': [
-            'python',
-            'tools/gen_library_src_paths.py',
-            '--output', '<(json_patch_cc_file)',
-            '--input_cc', '<(libgen_in_cc_file)',
-            '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::json_patch_paths_',
-            '--library_name', 'dart:json',
-            '<@(_sources)',
-          ],
-          'message': 'Generating ''<(json_patch_cc_file)'' file.'
-        },
-      ]
-    },
-    {
       'target_name': 'generate_typed_data_cc_file',
       'type': 'none',
       'toolsets':['host'],
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index bb896d0..34348f8 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -45,6 +45,8 @@
     'bitmap.cc',
     'bitmap.h',
     'bitmap_test.cc',
+    'block_scheduler.cc',
+    'block_scheduler.h',
     'boolfield.h',
     'boolfield_test.cc',
     'bootstrap.h',
diff --git a/sdk/bin/dartanalyzer b/sdk/bin/dartanalyzer
index 4ea86af..8a6a072 100755
--- a/sdk/bin/dartanalyzer
+++ b/sdk/bin/dartanalyzer
@@ -65,7 +65,7 @@
   # Bump up the heap on Mac VMs, some of which default to 128M or less.
   # Users can specify DART_JVMARGS in the environment to override this
   # setting.
-  EXTRA_JVMARGS+=" -Xmx256M -client "
+  EXTRA_JVMARGS+=" -Xmx512M -client "
 else
   # On other architectures
   # -batch invocations will do better with a server vm
diff --git a/sdk/bin/dartanalyzer_developer b/sdk/bin/dartanalyzer_developer
index 1e95873..5639355 100755
--- a/sdk/bin/dartanalyzer_developer
+++ b/sdk/bin/dartanalyzer_developer
@@ -54,7 +54,7 @@
 OS=`uname | tr "[A-Z]" "[a-z]"`
 if [ "$OS" == "darwin" ] ; then
   # Bump up the heap on Mac VMs, some of which default to 128M or less.
-  EXTRA_JVMARGS+=" -Xmx256M -client "
+  EXTRA_JVMARGS+=" -Xmx512M -client "
 else
   # On other architectures
   # -batch invocations will do better with a server vm
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
index d9a6f1b..aaab842 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -129,6 +129,19 @@
   // Right now, it is set by the tests.
   bool useMirrorHelperLibrary = false;
 
+  /// Initialized if the useMirrorHelperLibrary field is set.
+  MirrorRenamer mirrorRenamer;
+
+  /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary
+  /// field is set.
+  LibraryElement mirrorHelperLibrary;
+  /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary
+  /// field is set.
+  FunctionElement mirrorHelperGetNameFunction;
+  /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary
+  /// field is set.
+  Element mirrorHelperSymbolsMap;
+
   Map<Element, TreeElements> get resolvedElements =>
       compiler.enqueuer.resolution.resolvedElements;
 
@@ -264,15 +277,22 @@
     fixedMemberNames.add('srcType');
     fixedMemberNames.add('dstType');
 
+    if (useMirrorHelperLibrary && compiler.mirrorsLibrary != null) {
+        mirrorRenamer = new MirrorRenamer(compiler, this);
+    } else {
+      useMirrorHelperLibrary = false;
+    }
+
     /**
      * Tells whether we should output given element. Corelib classes like
      * Object should not be in the resulting code.
      */
     bool shouldOutput(Element element) {
-      return !identical(element.kind, ElementKind.VOID)
+      return (element.kind != ElementKind.VOID
           && isUserLibrary(element.getLibrary())
           && !element.isSynthesized
-          && element is !AbstractFieldElement;
+          && element is !AbstractFieldElement)
+          || element.getLibrary() == mirrorHelperLibrary;
     }
 
     final elementAsts = new Map<Element, ElementAst>();
@@ -397,7 +417,12 @@
     // some unused identifier.
     collector.unresolvedNodes.add(synthesizedIdentifier);
     makePlaceholders(element) {
+      bool oldUseHelper = useMirrorHelperLibrary;
+      useMirrorHelperLibrary = (useMirrorHelperLibrary
+                               && element.getLibrary() != mirrorHelperLibrary);
       collector.collect(element);
+      useMirrorHelperLibrary = oldUseHelper;
+
       if (element.isClass()) {
         classMembers[element].forEach(makePlaceholders);
       }
@@ -450,8 +475,8 @@
       }
     }
 
-    if (useMirrorHelperLibrary && compiler.mirrorsLibrary != null) {
-      MirrorRenamer.addMirrorHelperImport(imports);
+    if (useMirrorHelperLibrary) {
+      mirrorRenamer.addRenames(renames, topLevelNodes, collector);
     }
 
     final unparser = new EmitterUnparser(renames);
@@ -480,9 +505,34 @@
 
   log(String message) => compiler.log('[DartBackend] $message');
 
+  void onLibraryLoaded(LibraryElement library, Uri uri) {
+    if (useMirrorHelperLibrary && library == compiler.mirrorsLibrary) {
+      mirrorHelperLibrary = compiler.scanBuiltinLibrary(
+          MirrorRenamer.MIRROR_HELPER_LIBRARY_NAME);
+      mirrorHelperGetNameFunction = mirrorHelperLibrary.find(
+          const SourceString(MirrorRenamer.MIRROR_HELPER_GET_NAME_FUNCTION));
+      mirrorHelperSymbolsMap = mirrorHelperLibrary.find(
+          const SourceString(MirrorRenamer.MIRROR_HELPER_SYMBOLS_MAP_NAME));
+    }
+  }
+
   void registerStaticSend(Element element, Node node) {
-    if (useMirrorHelperLibrary && compiler.mirrorsLibrary != null) {
-      MirrorRenamer.handleStaticSend(renames, element, node, compiler);
+    if (useMirrorHelperLibrary) {
+      mirrorRenamer.registerStaticSend(element, node);
+    }
+  }
+
+  void registerMirrorHelperElement(Element element, Node node) {
+    if (mirrorHelperLibrary != null
+        && element.getLibrary() == mirrorHelperLibrary) {
+      mirrorRenamer.registerHelperElement(element, node);
+    }
+  }
+
+  void registerStaticUse(Element element, Enqueuer enqueuer) {
+    if (useMirrorHelperLibrary &&
+        element == compiler.mirrorSystemGetNameFunction) {
+      enqueuer.addToWorkList(mirrorHelperGetNameFunction);
     }
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart
index 82bfe58..29d4b4d 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart
@@ -10,7 +10,7 @@
 import '../dart_types.dart';
 import '../tree/tree.dart';
 import '../util/util.dart';
-import '../mirror_renamer/mirror_renamer.dart' show MirrorRenamer;
+import '../mirror_renamer/mirror_renamer.dart';
 
 import '../scanner/scannerlib.dart' show StringToken,
                                          Keyword,
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
index db7b9ee..c97e070 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
@@ -45,7 +45,6 @@
   final PlaceholderCollector collector;
 
   get compiler => collector.compiler;
-  DartBackend get backend => compiler.backend;
 
   SendVisitor(this.collector, TreeElements elements) : super(elements);
 
@@ -107,7 +106,7 @@
 
   visitStaticSend(Send node) {
     final element = elements[node];
-    backend.registerStaticSend(element, node);
+    collector.backend.registerStaticSend(element, node);
 
     if (Elements.isUnresolved(element)
         || identical(element, compiler.assertMethod)) {
@@ -161,6 +160,7 @@
 
   LibraryElement get coreLibrary => compiler.coreLibrary;
   FunctionElement get entryFunction => compiler.mainApp.find(Compiler.MAIN);
+  DartBackend get backend => compiler.backend;
 
   get currentFunctionScope => functionScopes.putIfAbsent(
       topmostEnclosingFunction, () => new FunctionScope());
@@ -505,6 +505,9 @@
       // TODO(smok): Fix this when resolver correctly deals with
       // such cases.
       if (definitionElement == null) continue;
+      if (definitionElement == backend.mirrorHelperSymbolsMap) {
+        backend.registerMirrorHelperElement(definitionElement, node);
+      }
       Send send = definition.asSend();
       if (send != null) {
         // May get FunctionExpression here in definition.selector
@@ -540,6 +543,9 @@
     Element element = treeElements[node];
     // May get null here in case of A(int this.f());
     if (element != null) {
+      if (element == backend.mirrorHelperGetNameFunction) {
+        backend.registerMirrorHelperElement(element, node);
+      }
       // Rename only local functions.
       if (topmostEnclosingFunction == null) {
         topmostEnclosingFunction = element;
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
index 73480bf..cb7c4a7 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
@@ -180,33 +180,24 @@
     renameElement = makeElementRenamer(rename, generateUniqueName);
 
     List<Set<Node>> allLocals = new List<Set<Node>>();
-    // If we are using the mirror_helper library we need all names to be
-    // globally unique.
-    if (uniqueGlobalNaming) {
-      //TODO(zarah): Change this so that local variables don't get unique names.
-      for (var functionScope in placeholderCollector.functionScopes.values) {
-        functionScope.localPlaceholders.forEach(
-            (ph) => allLocals.add(ph.nodes.toSet()));
+
+    // Build a list sorted by usage of local nodes that will be renamed to
+    // the same identifier. So the top-used local variables in all functions
+    // will be renamed first and will all share the same new identifier.
+    for (var functionScope in placeholderCollector.functionScopes.values) {
+      // Add current sorted local identifiers to the whole sorted list
+      // of all local identifiers for all functions.
+      List<LocalPlaceholder> currentSortedPlaceholders =
+          sorted(functionScope.localPlaceholders,
+              compareBy((LocalPlaceholder ph) => -ph.nodes.length));
+      List<Set<Node>> currentSortedNodes =
+          currentSortedPlaceholders.map((ph) => ph.nodes).toList();
+      // Make room in all sorted locals list for new stuff.
+      while (currentSortedNodes.length > allLocals.length) {
+        allLocals.add(new Set<Node>());
       }
-    } else {
-      // Build a sorted (by usage) list of local nodes that will be renamed to
-      // the same identifier. So the top-used local variables in all functions
-      // will be renamed first and will all share the same new identifier.
-      for (var functionScope in placeholderCollector.functionScopes.values) {
-        // Add current sorted local identifiers to the whole sorted list
-        // of all local identifiers for all functions.
-        List<LocalPlaceholder> currentSortedPlaceholders =
-            sorted(functionScope.localPlaceholders,
-                compareBy((LocalPlaceholder ph) => -ph.nodes.length));
-        List<Set<Node>> currentSortedNodes =
-            currentSortedPlaceholders.map((ph) => ph.nodes).toList();
-        // Make room in all sorted locals list for new stuff.
-        while (currentSortedNodes.length > allLocals.length) {
-          allLocals.add(new Set<Node>());
-        }
-        for (int i = 0; i < currentSortedNodes.length; i++) {
-          allLocals[i].addAll(currentSortedNodes[i]);
-        }
+      for (int i = 0; i < currentSortedNodes.length; i++) {
+        allLocals[i].addAll(currentSortedNodes[i]);
       }
     }
 
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index f490288..f7a4385 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -83,7 +83,7 @@
   /**
    * If this type is malformed or a generic type created with the wrong number
    * of type arguments then [userProvidedBadType] holds the bad type provided
-   * by the user. 
+   * by the user.
    */
   DartType get userProvidedBadType => null;
 
@@ -105,7 +105,7 @@
   /// Returns an occurrence of a type variable within this type, if any.
   TypeVariableType get typeVariableOccurrence => null;
 
-  /// Applies [f] to each occurence of a [TypeVariableType] within this type. 
+  /// Applies [f] to each occurence of a [TypeVariableType] within this type.
   void forEachTypeVariable(f(TypeVariableType variable)) {}
 
   TypeVariableType _findTypeVariableOccurrence(Link<DartType> types) {
@@ -487,10 +487,10 @@
       Element member = classElement.implementation.lookupLocalMember(name);
       if (member == null) return null;
       if (member.isConstructor() || member.isPrefix()) return null;
-      assert(member.isFunction() || 
-             member.isAbstractField() || 
+      assert(member.isFunction() ||
+             member.isAbstractField() ||
              member.isField());
-    
+
       if (member.isAbstractField()) {
         AbstractFieldElement abstractFieldElement = member;
         if (fallbackAbstractField == null) {
@@ -505,7 +505,7 @@
           member = null;
         }
       }
-      return member != null 
+      return member != null
           ? new Member(receiver, declarer, member, isSetter: isSetter) : null;
     }
 
@@ -544,7 +544,7 @@
 /**
  * Special subclass of [InterfaceType] used for generic interface types created
  * with the wrong number of type arguments.
- * 
+ *
  * The type uses [:dynamic:] for all it s type arguments.
  */
 class BadInterfaceType extends InterfaceType {
@@ -563,7 +563,7 @@
 /**
  * Special subclass of [TypedefType] used for generic typedef types created
  * with the wrong number of type arguments.
- * 
+ *
  * The type uses [:dynamic:] for all it s type arguments.
  */
 class BadTypedefType extends TypedefType {
@@ -851,7 +851,7 @@
       if (element.isAbstractField()) {
         AbstractFieldElement abstractFieldElement = element;
         // Use setter if present and required or if no getter is available.
-        if ((isSetter && abstractFieldElement.setter != null) || 
+        if ((isSetter && abstractFieldElement.setter != null) ||
             abstractFieldElement.getter == null) {
           // TODO(johnniwinther): Add check of read of field with no getter.
           FunctionType functionType =
@@ -934,8 +934,8 @@
 
   bool isSubtype(DartType t, DartType s) {
     if (identical(t, s) ||
-        t.treatAsDynamic || 
-        s.treatAsDynamic || 
+        t.treatAsDynamic ||
+        s.treatAsDynamic ||
         identical(s.element, compiler.objectClass) ||
         identical(t.element, compiler.nullClass)) {
       return true;
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 7a809b7..8b6f872 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -268,7 +268,7 @@
   /**
    * Set of classes whose methods are intercepted.
    */
-  final Set<ClassElement> interceptedClasses = new Set<ClassElement>();
+  final Set<ClassElement> _interceptedClasses = new Set<ClassElement>();
 
   /**
    * Set of classes used as mixins on native classes.  Methods on these classes
@@ -557,10 +557,6 @@
     jsStringToString = compiler.lookupElementIn(
         jsStringClass, const SourceString('toString'));
 
-    for (ClassElement cls in classes) {
-      if (cls != null) interceptedClasses.add(cls);
-    }
-
     typeLiteralClass = compiler.findHelper(const SourceString('TypeImpl'));
     mapLiteralClass =
         compiler.coreLibrary.find(const SourceString('LinkedHashMap'));
@@ -630,6 +626,8 @@
                        Enqueuer enqueuer,
                        TreeElements elements) {
     if (enqueuer.isResolutionQueue) {
+      _interceptedClasses.add(jsInterceptorClass);
+      _interceptedClasses.add(cls);
       cls.ensureResolved(compiler);
       cls.forEachMember((ClassElement classElement, Element member) {
           // All methods on [Object] are shadowed by [Interceptor].
@@ -643,6 +641,11 @@
     enqueueClass(enqueuer, cls, elements);
   }
 
+  Set<ClassElement> get interceptedClasses {
+    assert(compiler.enqueuer.resolution.queueIsClosed);
+    return _interceptedClasses;
+  }
+
   void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
     String name = namer.getInterceptorName(getInterceptorMethod, classes);
     if (classes.contains(jsInterceptorClass)) {
@@ -711,8 +714,9 @@
                || cls == jsFixedArrayClass
                || cls == jsExtendableArrayClass) {
       addInterceptors(jsArrayClass, enqueuer, elements);
-      enqueueClass(enqueuer, jsFixedArrayClass, elements);
-      enqueueClass(enqueuer, jsExtendableArrayClass, elements);
+      addInterceptors(jsMutableArrayClass, enqueuer, elements);
+      addInterceptors(jsFixedArrayClass, enqueuer, elements);
+      addInterceptors(jsExtendableArrayClass, enqueuer, elements);
     } else if (cls == compiler.intClass || cls == jsIntClass) {
       addInterceptors(jsIntClass, enqueuer, elements);
       addInterceptors(jsNumberClass, enqueuer, elements);
@@ -1284,6 +1288,23 @@
     }
   }
 
+  /**
+   * Returns [:true:] if the checking of [type] is performed directly on the
+   * object and not on an interceptor.
+   */
+  bool hasDirectCheckFor(DartType type) {
+    Element element = type.element;
+    return element == compiler.stringClass ||
+        element == compiler.boolClass ||
+        element == compiler.numClass ||
+        element == compiler.intClass ||
+        element == compiler.doubleClass ||
+        element == jsArrayClass ||
+        element == jsMutableArrayClass ||
+        element == jsExtendableArrayClass ||
+        element == jsFixedArrayClass;
+  }
+
   Element getExceptionUnwrapper() {
     return compiler.findHelper(const SourceString('unwrapException'));
   }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 965822e..e7eb3ce 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -1822,12 +1822,16 @@
                 // 01:  function() { return this.field; }
                 // 10:  function(receiver) { return receiver.field; }
                 // 11:  function(receiver) { return this.field; }
-                getterCode += backend.fieldHasInterceptedGetter(field) ? 2 : 0;
+                bool isIntercepted = backend.fieldHasInterceptedGetter(field);
+                getterCode += isIntercepted ? 2 : 0;
                 getterCode += backend.isInterceptorClass(element) ? 0 : 1;
                 // TODO(sra): 'isInterceptorClass' might not be the correct test
                 // for methods forced to use the interceptor convention because
                 // the method's class was elsewhere mixed-in to an interceptor.
                 assert(!field.isInstanceMember() || getterCode != 0);
+                if (isIntercepted) {
+                  interceptorInvocationNames.add(namer.getterName(field));
+                }
               } else {
                 getterCode = 1;
               }
@@ -1838,9 +1842,13 @@
                 // 01:  function(value) { this.field = value; }
                 // 10:  function(receiver, value) { receiver.field = value; }
                 // 11:  function(receiver, value) { this.field = value; }
-                setterCode += backend.fieldHasInterceptedSetter(field) ? 2 : 0;
+                bool isIntercepted = backend.fieldHasInterceptedSetter(field);
+                setterCode += isIntercepted ? 2 : 0;
                 setterCode += backend.isInterceptorClass(element) ? 0 : 1;
                 assert(!field.isInstanceMember() || setterCode != 0);
+                if (isIntercepted) {
+                  interceptorInvocationNames.add(namer.setterName(field));
+                }
               } else {
                 setterCode = 1;
               }
@@ -2176,7 +2184,9 @@
       if (!knownSubtype) {
         registerDynamicFunctionTypeCheck(functionType);
         hasDynamicFunctionTypeCheck = true;
-      } else {
+      } else if (!backend.rti.isSimpleFunctionType(functionType)) {
+        // Simple function types are always checked using predicates and should
+        // not provoke generation of signatures.
         neededPredicates++;
       }
     });
@@ -2188,7 +2198,10 @@
     }
     functionTypeChecks.forEach((FunctionType functionType, bool knownSubtype) {
       if (knownSubtype) {
-        if (alwaysUseSignature) {
+        if (backend.rti.isSimpleFunctionType(functionType)) {
+          // Simple function types are always checked using predicates.
+          emitIsFunctionTypeTest(functionType);
+        } else if (alwaysUseSignature) {
           registerDynamicFunctionTypeCheck(functionType);
         } else {
           emitIsFunctionTypeTest(functionType);
@@ -2811,57 +2824,12 @@
       DartType objectType = objectClass.computeType(compiler);
 
       for (Selector selector in selectors) {
-        // If the selector is typed, we check to see if that type may
-        // have a user-defined noSuchMethod implementation. If not, we
-        // skip the selector altogether.
-
         TypeMask mask = selector.mask;
         if (mask == null) {
           mask = new TypeMask.subclass(compiler.objectClass.rawType);
         }
 
-        // If the receiver is guaranteed to have a member that
-        // matches what we're looking for, there's no need to
-        // introduce a noSuchMethod handler. It will never be called.
-        //
-        // As an example, consider this class hierarchy:
-        //
-        //                   A    <-- noSuchMethod
-        //                  / \
-        //                 C   B  <-- foo
-        //
-        // If we know we're calling foo on an object of type B we
-        // don't have to worry about the noSuchMethod method in A
-        // because objects of type B implement foo. On the other hand,
-        // if we end up calling foo on something of type C we have to
-        // add a handler for it.
-
-        // If the holders of all user-defined noSuchMethod
-        // implementations that might be applicable to the receiver
-        // type have a matching member for the current name and
-        // selector, we avoid introducing a noSuchMethod handler.
-        //
-        // As an example, consider this class hierarchy:
-        //
-        //                       A    <-- foo
-        //                      / \
-        //   noSuchMethod -->  B   C  <-- bar
-        //                     |   |
-        //                     C   D  <-- noSuchMethod
-        //
-        // When calling foo on an object of type A, we know that the
-        // implementations of noSuchMethod are in the classes B and D
-        // that also (indirectly) implement foo, so we do not need a
-        // handler for it.
-        //
-        // If we're calling bar on an object of type D, we don't need
-        // the handler either because all objects of type D implement
-        // bar through inheritance.
-        //
-        // If we're calling bar on an object of type A we do need the
-        // handler because we may have to call B.noSuchMethod since B
-        // does not implement bar.
-        if (mask.willHit(selector, compiler)) continue;
+        if (!mask.needsNoSuchMethodHandling(selector, compiler)) continue;
         String jsName = namer.invocationMirrorInternalName(selector);
         addedJsNames[jsName] = selector;
         String reflectionName = getReflectionName(selector, jsName);
@@ -2980,9 +2948,9 @@
     // onload event of all script tags and getting the first script which
     // finishes. Since onload is called immediately after execution this should
     // not substantially change execution order.
-    buffer.write("""
+    buffer.write('''
 ;(function (callback) {
-  if (typeof document === 'undefined') {
+  if (typeof document === "undefined") {
     callback(null);
     return;
   }
@@ -2994,18 +2962,18 @@
   var scripts = document.scripts;
   function onLoad(event) {
     for (var i = 0; i < scripts.length; ++i) {
-      scripts[i].removeEventListener('load', onLoad, false);
+      scripts[i].removeEventListener("load", onLoad, false);
     }
     callback(event.target);
   }
   for (var i = 0; i < scripts.length; ++i) {
-    scripts[i].addEventListener('load', onLoad, false);
+    scripts[i].addEventListener("load", onLoad, false);
   }
 })(function(currentScript) {
   ${namer.isolateName}.${namer.isolatePropertiesName}.\$currentScript =
       currentScript;
 
-  if (typeof console !== 'undefined' && typeof document !== 'undefined' &&
+  if (typeof console !== "undefined" && typeof document !== "undefined" &&
       document.readyState == "loading") {
     console.warn("Dart script executed synchronously, use <script src='" +
         currentScript.src + "' defer></scr" + "ipt> to execute after parsing " +
@@ -3016,13 +2984,13 @@
   } else {
     ${mainCall};
   }
-})$N""");
+})$N''');
     addComment('END invoke [main].', buffer);
   }
 
   void emitGetInterceptorMethod(CodeBuffer buffer,
                                 String key,
-                                Iterable<ClassElement> classes) {
+                                Set<ClassElement> classes) {
     jsAst.Statement buildReturnInterceptor(ClassElement cls) {
       return js.return_(js(namer.isolateAccess(cls))['prototype']);
     }
@@ -3097,7 +3065,7 @@
     }
     if (hasInt) hasNumber = true;
 
-    if (classes == backend.interceptedClasses) {
+    if (classes.containsAll(backend.interceptedClasses)) {
       // I.e. this is the general interceptor.
       hasNative = anyNativeClasses;
     }
@@ -3187,9 +3155,10 @@
    * Emit all versions of the [:getInterceptor:] method.
    */
   void emitGetInterceptorMethods(CodeBuffer buffer) {
-    var specializedGetInterceptors = backend.specializedGetInterceptors;
+    Map<String, Set<ClassElement>> specializedGetInterceptors =
+        backend.specializedGetInterceptors;
     for (String name in specializedGetInterceptors.keys.toList()..sort()) {
-      Iterable<ClassElement> classes = specializedGetInterceptors[name];
+      Set<ClassElement> classes = specializedGetInterceptors[name];
       emitGetInterceptorMethod(buffer, name, classes);
     }
   }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 7a6e6f3..e1246bf 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -225,7 +225,8 @@
         popularNameCounters = new Map<String, int>(),
         constantNames = new Map<Constant, String>(),
         constantLongNames = new Map<Constant, String>(),
-        constantHasher = new ConstantCanonicalHasher(compiler);
+        constantHasher = new ConstantCanonicalHasher(compiler),
+        functionTypeNamer = new FunctionTypeNamer(compiler);
 
   String get isolateName => 'Isolate';
   String get isolatePropertiesName => r'$isolateProperties';
@@ -800,7 +801,7 @@
 
   Map<FunctionType,String> functionTypeNameMap =
       new Map<FunctionType,String>();
-  FunctionTypeNamer functionTypeNamer = new FunctionTypeNamer();
+  final FunctionTypeNamer functionTypeNamer;
 
   String getFunctionTypeName(FunctionType functionType) {
     return functionTypeNameMap.putIfAbsent(functionType, () {
@@ -1223,8 +1224,13 @@
 }
 
 class FunctionTypeNamer extends DartTypeVisitor {
+  final Compiler compiler;
   StringBuffer sb;
 
+  FunctionTypeNamer(this.compiler);
+
+  JavaScriptBackend get backend => compiler.backend;
+
   String computeName(DartType type) {
     sb = new StringBuffer();
     visit(type);
@@ -1240,6 +1246,10 @@
   }
 
   visitFunctionType(FunctionType type, _) {
+    if (backend.rti.isSimpleFunctionType(type)) {
+      sb.write('args${type.parameterTypes.slowLength()}');
+      return;
+    }
     visit(type.returnType);
     sb.write('_');
     for (Link<DartType> link = type.parameterTypes;
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 29e1ecb..9308bec 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -545,6 +545,18 @@
     return representationGenerator.getTypeRepresentation(type, onVariable);
   }
 
+  bool isSimpleFunctionType(FunctionType type) {
+    if (!type.returnType.isDynamic) return false;
+    if (!type.optionalParameterTypes.isEmpty) return false;
+    if (!type.namedParameterTypes.isEmpty) return false;
+    for (Link<DartType> link = type.parameterTypes;
+        !link.isEmpty;
+        link = link.tail) {
+      if (!link.head.isDynamic) return false;
+    }
+    return true;
+  }
+
   static bool hasTypeArguments(DartType type) {
     if (type is InterfaceType) {
       InterfaceType interfaceType = type;
diff --git a/sdk/lib/_internal/compiler/implementation/mirror_renamer/mirror_renamer.dart b/sdk/lib/_internal/compiler/implementation/mirror_renamer/mirror_renamer.dart
index 3ed8b5d..5bd0db1 100644
--- a/sdk/lib/_internal/compiler/implementation/mirror_renamer/mirror_renamer.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirror_renamer/mirror_renamer.dart
@@ -4,11 +4,11 @@
 
 library mirror_renamer;
 
-// TODO(zarah): Remove this hack! LibraryElementX should not be created outside
-// the library loader!
-import '../elements/modelx.dart' show LibraryElementX;
 import '../dart2jslib.dart' show Script, Compiler;
 import '../tree/tree.dart';
+import '../scanner/scannerlib.dart' show SourceString, Token;
 import '../elements/elements.dart';
+import '../dart_backend/dart_backend.dart' show DartBackend,
+                                                PlaceholderCollector;
 
-part 'renamer.dart';
\ No newline at end of file
+part 'renamer.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/mirror_renamer/renamer.dart b/sdk/lib/_internal/compiler/implementation/mirror_renamer/renamer.dart
index 003dda4..b1f8eaf 100644
--- a/sdk/lib/_internal/compiler/implementation/mirror_renamer/renamer.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirror_renamer/renamer.dart
@@ -5,28 +5,94 @@
 part of mirror_renamer;
 
 class MirrorRenamer {
-  static const String MIRROR_HELPER_CLASS = 'MirrorHelper';
-  static const String MIRROR_HELPER_GET_NAME_FUNCTION = 'getName';
-  static const String MIRROR_HELPER_LIBRARY_NAME = 'mirror_helper.dart';
-  static const String MIRROR_HELPER_LIBRARY_PREFIX = 'm';
-  static const String MIRROR_HELPER_CLASS_FULLY_QUALIFIED_NAME =
-      '$MIRROR_HELPER_LIBRARY_PREFIX.$MIRROR_HELPER_CLASS';
+  static const String MIRROR_HELPER_GET_NAME_FUNCTION = 'helperGetName';
+  static const String MIRROR_HELPER_LIBRARY_NAME = '_mirror_helper';
+  static const String MIRROR_HELPER_SYMBOLS_MAP_NAME = '_SYMBOLS';
 
-  static void handleStaticSend(Map<Node, String> renames, Element element,
-                               Send node, Compiler compiler) {
+  /// Maps mangled name to original name.
+  Map<String, SourceString> symbols = new Map<String, SourceString>();
+  /// Contains all occurrencs of MirrorSystem.getName() calls in the user code.
+  List<Node> mirrorSystemGetNameNodes = <Node>[];
+  /**
+   *  Initialized when the placeholderCollector collects the FunctionElement
+   *  backend.mirrorHelperGetNameFunction which represents the helperGetName
+   *  function in _mirror_helper.
+   */
+  FunctionExpression mirrorHelperGetNameFunctionNode;
+  VariableDefinitions mirrorHelperSymbolsMapNode;
+  Compiler compiler;
+  DartBackend backend;
+
+  MirrorRenamer(this.compiler, this.backend);
+
+  void registerStaticSend(Element element, Send node) {
   if (element == compiler.mirrorSystemGetNameFunction) {
-    renames[node.selector] = MIRROR_HELPER_GET_NAME_FUNCTION;
-    renames[node.receiver] = MIRROR_HELPER_CLASS_FULLY_QUALIFIED_NAME;
-    }
+    mirrorSystemGetNameNodes.add(node);
+  }
  }
 
-  static void addMirrorHelperImport(Map<LibraryElement, String> imports) {
-    Uri mirrorHelperUri = new Uri(path: MIRROR_HELPER_LIBRARY_NAME);
-    // TODO(zarah): Remove this hack! LibraryElementX should not be created
-    // outside the library loader. When actual mirror helper library
-    // is created, change to load that.
-    LibraryElement mirrorHelperLib = new LibraryElementX(
-        new Script(mirrorHelperUri, null));
-    imports.putIfAbsent(mirrorHelperLib, () => MIRROR_HELPER_LIBRARY_PREFIX);
+  void registerHelperElement(Element element, Node node) {
+    if (element == backend.mirrorHelperGetNameFunction) {
+      mirrorHelperGetNameFunctionNode = node;
+    } else if (element == backend.mirrorHelperSymbolsMap) {
+      mirrorHelperSymbolsMapNode = node;
+    }
   }
-}
\ No newline at end of file
+
+  /**
+   * Adds a toplevel node to the output containing a map from the mangled
+   * to the unmangled names and replaces calls to MirrorSystem.getName()
+   * with calls to the corresponding wrapper from _mirror_helper which has
+   * been added during resolution. [renames] is assumed to map nodes in user
+   * code to mangled names appearing in output code, and [topLevelNodes] should
+   * contain all the toplevel ast nodes that will be emitted in the output.
+   */
+  void addRenames(Map<Node, String> renames, List<Node> topLevelNodes,
+                  PlaceholderCollector placeholderCollector) {
+    // Right now we only support instances of MirrorSystem.getName,
+    // hence if there are no occurence of these we don't do anything.
+    if (mirrorSystemGetNameNodes.isEmpty) {
+      return;
+    }
+
+    Node parse(String text) {
+      Token tokens = compiler.scanner.tokenize(text);
+      return compiler.parser.parseCompilationUnit(tokens);
+    }
+
+    // Add toplevel map containing all renames of members.
+    symbols = new Map<String, SourceString>();
+    for (Set<Identifier> s in placeholderCollector.memberPlaceholders.values) {
+      // All members in a set have the same name so we only need to look at one.
+      Identifier sampleNode = s.first;
+      symbols.putIfAbsent(renames[sampleNode], () => sampleNode.source);
+    }
+
+    Identifier symbolsMapIdentifier =
+        mirrorHelperSymbolsMapNode.definitions.nodes.head.asSend().selector;
+    assert(symbolsMapIdentifier != null);
+    topLevelNodes.remove(mirrorHelperSymbolsMapNode);
+
+    StringBuffer sb = new StringBuffer(
+        'const ${renames[symbolsMapIdentifier]} = const<String,SourceString>{');
+    bool first = true;
+    for (String mangledName in symbols.keys) {
+      if (!first) {
+        sb.write(',');
+      } else {
+        first = false;
+      }
+      sb.write("'$mangledName' : '");
+      symbols[mangledName].printOn(sb);
+      sb.write("'");
+    }
+    sb.write('};');
+    topLevelNodes.add(parse(sb.toString()));
+
+    // Replace calls to Mirrorsystem.getName with calls to helper function.
+    mirrorSystemGetNameNodes.forEach((node) {
+      renames[node.selector] = renames[mirrorHelperGetNameFunctionNode.name];
+      renames[node.receiver] = '';
+    });
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors_used.dart b/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
index 9c8df9c..144f395 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
@@ -120,8 +120,11 @@
   /// the resolver to suppress hints about using new Symbol or
   /// MirrorSystem.getName.
   bool hasMirrorUsage(Element element) {
-    return librariesWithUsage != null
-        && librariesWithUsage.contains(element.getLibrary());
+    LibraryElement library = element.getLibrary();
+    // Internal libraries always have implicit mirror usage.
+    return library.isInternalLibrary
+        || (librariesWithUsage != null
+            && librariesWithUsage.contains(library));
   }
 
   /// Call-back from the resolver to analyze MirorsUsed annotations. The result
diff --git a/sdk/lib/_internal/compiler/implementation/patch_parser.dart b/sdk/lib/_internal/compiler/implementation/patch_parser.dart
index 5827a3d..5ae5779 100644
--- a/sdk/lib/_internal/compiler/implementation/patch_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/patch_parser.dart
@@ -160,7 +160,7 @@
         CompilationUnitElement compilationUnit,
         LinkBuilder<tree.LibraryTag> imports) {
     measure(() {
-      // TODO(lrn): Possibly recursively handle #source directives in patch.
+      // TODO(lrn): Possibly recursively handle 'part' directives in patch.
       leg.Script script = compilationUnit.script;
       Token tokens = new StringScanner(script.text).tokenize();
       Function idGenerator = compiler.getNextFreeClassId;
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index a2c9d1d..89bb3e7 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -4012,11 +4012,17 @@
                                              Node expression) {
     // Find the unnamed constructor if the reference resolved to a
     // class.
-    if (!Elements.isUnresolved(e) && e.isClass()) {
-      ClassElement cls = e;
-      cls.ensureResolved(compiler);
-      // The unnamed constructor may not exist, so [e] may become unresolved.
-      e = lookupConstructor(cls, diagnosticNode, const SourceString(''));
+    if (!Elements.isUnresolved(e) && !e.isConstructor()) {
+      if (e.isClass()) {
+        ClassElement cls = e;
+        cls.ensureResolved(compiler);
+        // The unnamed constructor may not exist, so [e] may become unresolved.
+        e = lookupConstructor(cls, diagnosticNode, const SourceString(''));
+      } else {
+        e = failOrReturnErroneousElement(
+              e, diagnosticNode, e.name, MessageKind.NOT_A_TYPE,
+              {'node': diagnosticNode});
+      }
     }
     if (type == null) {
       if (Elements.isUnresolved(e)) {
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index 7d3cf1c..ab20f51 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -1184,14 +1184,16 @@
 
   void endTopLevelFields(int count, Token beginToken, Token endToken) {
     NodeList variables = makeNodeList(count, null, endToken, ",");
+    TypeAnnotation type = popNode();
     Modifiers modifiers = popNode();
-    pushNode(new VariableDefinitions(null, modifiers, variables));
+    pushNode(new VariableDefinitions(type, modifiers, variables));
   }
 
   void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
     Statement body = popNode();
     NodeList formalParameters = popNode();
     Identifier name = popNode();
+    TypeAnnotation type = popNode();
     Modifiers modifiers = popNode();
     ElementKind kind;
     if (getOrSet == null) {
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
index ee84b4c..327d1f2 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
@@ -1264,6 +1264,7 @@
       }
       // Fall-through to expression statement.
     }
+
     return parseExpressionStatement(token);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/parser_task.dart b/sdk/lib/_internal/compiler/implementation/scanner/parser_task.dart
index eca572b..e83e6f5 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/parser_task.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/parser_task.dart
@@ -11,4 +11,15 @@
   Node parse(Element element) {
     return measure(() => element.parseNode(compiler));
   }
+
+  Node parseCompilationUnit(Token token) {
+    return measure(() {
+      NodeListener listener = new NodeListener(compiler, null);
+      Parser parser = new Parser(listener);
+      parser.parseUnit(token);
+      Node result = listener.popNode();
+      assert(listener.nodes.isEmpty);
+      return result;
+    });
+  }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/scanner_task.dart b/sdk/lib/_internal/compiler/implementation/scanner/scanner_task.dart
index 0738355..765f49e 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/scanner_task.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/scanner_task.dart
@@ -35,6 +35,12 @@
     }
     compiler.dietParser.dietParse(compilationUnit, tokens);
   }
+
+  Token tokenize(String source) {
+    return measure(() {
+      return new StringScanner(source, includeComments: false).tokenize();
+    });
+  }
 }
 
 class DietParserTask extends CompilerTask {
diff --git a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
index 3188a3e..ca48fda 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
@@ -5,8 +5,8 @@
 library source_file_provider;
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
-import 'dart:utf';
 
 import '../compiler.dart' as api show Diagnostic;
 import 'dart2js.dart' show AbortLeg;
@@ -21,7 +21,7 @@
   var buffer = new List<int>(length);
   var bytes = file.readIntoSync(buffer, 0, length);
   file.closeSync();
-  return new String.fromCharCodes(new Utf8Decoder(buffer).decodeRest());
+  return UTF8.decode(buffer);
 }
 
 class SourceFileProvider {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 9169282..5e34fcd 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -31,52 +31,54 @@
   HGraph build(CodegenWorkItem work) {
     return measure(() {
       Element element = work.element.implementation;
-      HInstruction.idCounter = 0;
-      ConstantSystem constantSystem = compiler.backend.constantSystem;
-      SsaBuilder builder = new SsaBuilder(constantSystem, this, work);
-      HGraph graph;
-      ElementKind kind = element.kind;
-      if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
-        graph = compileConstructor(builder, work);
-      } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
-                 kind == ElementKind.FUNCTION ||
-                 kind == ElementKind.GETTER ||
-                 kind == ElementKind.SETTER) {
-        graph = builder.buildMethod(element);
-      } else if (kind == ElementKind.FIELD) {
-        assert(!element.isInstanceMember());
-        graph = builder.buildLazyInitializer(element);
-      } else {
-        compiler.internalErrorOnElement(element,
-                                        'unexpected element kind $kind');
-      }
-      assert(graph.isValid());
-      if (!identical(kind, ElementKind.FIELD)) {
-        FunctionElement function = element;
-        FunctionSignature signature = function.computeSignature(compiler);
-        signature.forEachOptionalParameter((Element parameter) {
-          // This ensures the default value will be computed.
-          builder.compileVariable(parameter);
-        });
-      }
-
-      if (compiler.tracer.enabled) {
-        String name;
-        if (element.isMember()) {
-          String className = element.getEnclosingClass().name.slowToString();
-          String memberName = element.name.slowToString();
-          name = "$className.$memberName";
-          if (element.isGenerativeConstructorBody()) {
-            name = "$name (body)";
-          }
+      return compiler.withCurrentElement(element, () {
+        HInstruction.idCounter = 0;
+        ConstantSystem constantSystem = compiler.backend.constantSystem;
+        SsaBuilder builder = new SsaBuilder(constantSystem, this, work);
+        HGraph graph;
+        ElementKind kind = element.kind;
+        if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
+          graph = compileConstructor(builder, work);
+        } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
+                   kind == ElementKind.FUNCTION ||
+                   kind == ElementKind.GETTER ||
+                   kind == ElementKind.SETTER) {
+          graph = builder.buildMethod(element);
+        } else if (kind == ElementKind.FIELD) {
+          assert(!element.isInstanceMember());
+          graph = builder.buildLazyInitializer(element);
         } else {
-          name = "${element.name.slowToString()}";
+          compiler.internalErrorOnElement(element,
+                                          'unexpected element kind $kind');
         }
-        compiler.tracer.traceCompilation(
-            name, work.compilationContext, compiler);
-        compiler.tracer.traceGraph('builder', graph);
-      }
-      return graph;
+        assert(graph.isValid());
+        if (!identical(kind, ElementKind.FIELD)) {
+          FunctionElement function = element;
+          FunctionSignature signature = function.computeSignature(compiler);
+          signature.forEachOptionalParameter((Element parameter) {
+            // This ensures the default value will be computed.
+            builder.compileVariable(parameter);
+          });
+        }
+
+        if (compiler.tracer.enabled) {
+          String name;
+          if (element.isMember()) {
+            String className = element.getEnclosingClass().name.slowToString();
+            String memberName = element.name.slowToString();
+            name = "$className.$memberName";
+            if (element.isGenerativeConstructorBody()) {
+              name = "$name (body)";
+            }
+          } else {
+            name = "${element.name.slowToString()}";
+          }
+          compiler.tracer.traceCompilation(
+              name, work.compilationContext, compiler);
+          compiler.tracer.traceGraph('builder', graph);
+        }
+        return graph;
+      });
     });
   }
 
@@ -1776,6 +1778,9 @@
       return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
           original, typeVariable);
     } else if (type.kind == TypeKind.FUNCTION) {
+      if (backend.rti.isSimpleFunctionType(type)) {
+        return original.convertType(compiler, type, kind);
+      }
       HType subtype = original.instructionType;
       if (type.containsTypeVariables) {
         bool contextIsTypeArguments = false;
@@ -2794,6 +2799,10 @@
   HInstruction buildIsNode(Node node, DartType type, HInstruction expression) {
     type = type.unalias(compiler);
     if (type.kind == TypeKind.FUNCTION) {
+      if (backend.rti.isSimpleFunctionType(type)) {
+        // TODO(johnniwinther): Avoid interceptor if unneeded.
+        return new HIs.raw(type, expression, invokeInterceptor(expression));
+      }
       Element checkFunctionSubtype = backend.getCheckFunctionSubtype();
 
       HInstruction signatureName = graph.addConstantString(
@@ -2829,16 +2838,14 @@
                                                  typeArguments];
       pushInvokeStatic(node, checkFunctionSubtype, inputs, HType.BOOLEAN);
       HInstruction call = pop();
-      return new HIs(type, <HInstruction>[expression, call],
-          HIs.COMPOUND_CHECK);
+      return new HIs.compound(type, expression, call);
     } else if (type.kind == TypeKind.TYPE_VARIABLE) {
       HInstruction runtimeType = addTypeVariableReference(type);
       Element helper = backend.getCheckSubtypeOfRuntimeType();
       List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
       pushInvokeStatic(null, helper, inputs, HType.BOOLEAN);
       HInstruction call = pop();
-      return new HIs(type, <HInstruction>[expression, call],
-                     HIs.VARIABLE_CHECK);
+      return new HIs.variable(type, expression, call);
     } else if (RuntimeTypes.hasTypeArguments(type)) {
       ClassElement element = type.element;
       Element helper = backend.getCheckSubtype();
@@ -2857,10 +2864,13 @@
                                                  asFieldName];
       pushInvokeStatic(node, helper, inputs, HType.BOOLEAN);
       HInstruction call = pop();
-      return
-          new HIs(type, <HInstruction>[expression, call], HIs.COMPOUND_CHECK);
+      return new HIs.compound(type, expression, call);
     } else {
-      return new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK);
+      if (backend.hasDirectCheckFor(type)) {
+        return new HIs.direct(type, expression);
+      }
+      // TODO(johnniwinther): Avoid interceptor if unneeded.
+      return new HIs.raw(type, expression, invokeInterceptor(expression));
     }
   }
 
@@ -4896,10 +4906,8 @@
           if (type == null) {
             compiler.internalError('On with no type', node: catchBlock.type);
           }
-          // TODO(karlkose): support type arguments here.
-          HInstruction condition = new HIs(type,
-                                           <HInstruction>[unwrappedException],
-                                           HIs.RAW_CHECK);
+          HInstruction condition =
+              buildIsNode(catchBlock.type, type, unwrappedException);
           push(condition);
         } else {
           VariableDefinitions declaration = catchBlock.formals.nodes.head;
@@ -4916,9 +4924,7 @@
             if (type == null) {
               compiler.cancel('Catch with unresolved type', node: catchBlock);
             }
-            // TODO(karlkose): support type arguments here.
-            condition = new HIs(type, <HInstruction>[unwrappedException],
-                                HIs.RAW_CHECK);
+            condition = buildIsNode(declaration.type, type, unwrappedException);
             push(condition);
           }
         }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 0e592f3..a9113e1 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -2216,7 +2216,8 @@
     if (negative) push(new js.Prefix('!', pop()));
   }
 
-  void checkType(HInstruction input, DartType type, {bool negative: false}) {
+  void checkType(HInstruction input, HInstruction interceptor,
+                 DartType type, {bool negative: false}) {
     Element element = type.element;
     if (element == backend.jsArrayClass) {
       checkArray(input, negative ? '!==': '===');
@@ -2243,24 +2244,16 @@
       }
       return;
     }
-    use(input);
+    if (interceptor != null) {
+      use(interceptor);
+    } else {
+      use(input);
+    }
 
-    // Hack in interceptor.  Ideally the interceptor would occur at the
-    // instruction level to allow optimizations, and checks would be broken into
-    // several smaller tests.
-    // This code is a slice of visitInterceptor for the univeral interceptor.
-    String interceptorName = backend.namer.getInterceptorName(
-        backend.getInterceptorMethod, backend.interceptedClasses);
-    backend.registerSpecializedGetInterceptor(backend.interceptedClasses);
-    backend.registerUseInterceptor(world);
-
-    var isolate = new js.VariableUse(backend.namer.CURRENT_ISOLATE);
-    List<js.Expression> arguments = <js.Expression>[pop()];
-    push(jsPropertyCall(isolate, interceptorName, arguments));
     world.registerIsCheck(type, work.resolutionTree);
 
     js.PropertyAccess field =
-        new js.PropertyAccess.field(pop(), backend.namer.operatorIs(element));
+        new js.PropertyAccess.field(pop(), backend.namer.operatorIsType(type));
     // We always negate at least once so that the result is boolified.
     push(new js.Prefix('!', field));
     // If the result is not negated, put another '!' in front.
@@ -2268,6 +2261,7 @@
   }
 
   void handleNumberOrStringSupertypeCheck(HInstruction input,
+                                          HInstruction interceptor,
                                           DartType type,
                                           { bool negative: false }) {
     assert(!identical(type.element, compiler.listClass)
@@ -2280,7 +2274,7 @@
     js.Expression stringTest = pop();
     checkObject(input, relation);
     js.Expression objectTest = pop();
-    checkType(input, type, negative: negative);
+    checkType(input, interceptor, type, negative: negative);
     String combiner = negative ? '&&' : '||';
     String combiner2 = negative ? '||' : '&&';
     push(new js.Binary(combiner,
@@ -2289,6 +2283,7 @@
   }
 
   void handleStringSupertypeCheck(HInstruction input,
+                                  HInstruction interceptor,
                                   DartType type,
                                   { bool negative: false }) {
     assert(!identical(type.element, compiler.listClass)
@@ -2299,7 +2294,7 @@
     js.Expression stringTest = pop();
     checkObject(input, relation);
     js.Expression objectTest = pop();
-    checkType(input, type, negative: negative);
+    checkType(input, interceptor, type, negative: negative);
     String combiner = negative ? '||' : '&&';
     push(new js.Binary(negative ? '&&' : '||',
                        stringTest,
@@ -2307,6 +2302,7 @@
   }
 
   void handleListOrSupertypeCheck(HInstruction input,
+                                  HInstruction interceptor,
                                   DartType type,
                                   { bool negative: false }) {
     assert(!identical(type.element, compiler.stringClass)
@@ -2317,7 +2313,7 @@
     js.Expression objectTest = pop();
     checkArray(input, relation);
     js.Expression arrayTest = pop();
-    checkType(input, type, negative: negative);
+    checkType(input, interceptor, type, negative: negative);
     String combiner = negative ? '&&' : '||';
     push(new js.Binary(negative ? '||' : '&&',
                        objectTest,
@@ -2343,6 +2339,7 @@
       if (negative) push(new js.Prefix('!', pop()));
     } else {
       assert(node.isRawCheck);
+      HInstruction interceptor = node.interceptor;
       LibraryElement coreLibrary = compiler.coreLibrary;
       ClassElement objectClass = compiler.objectClass;
       Element element = type.element;
@@ -2377,46 +2374,33 @@
         checkBigInt(input, relation);
         push(new js.Binary(negative ? '||' : '&&', numTest, pop()), node);
       } else if (Elements.isNumberOrStringSupertype(element, compiler)) {
-        handleNumberOrStringSupertypeCheck(input, type, negative: negative);
+        handleNumberOrStringSupertypeCheck(
+            input, interceptor, type, negative: negative);
         attachLocationToLast(node);
       } else if (Elements.isStringOnlySupertype(element, compiler)) {
-        handleStringSupertypeCheck(input, type, negative: negative);
+        handleStringSupertypeCheck(
+            input, interceptor, type, negative: negative);
         attachLocationToLast(node);
       } else if (identical(element, compiler.listClass)
                  || Elements.isListSupertype(element, compiler)) {
-        handleListOrSupertypeCheck(input, type, negative: negative);
+        handleListOrSupertypeCheck(
+            input, interceptor, type, negative: negative);
         attachLocationToLast(node);
-      } else if (element.isTypedef()) {
-        if (negative) {
-          checkNull(input);
-        } else {
-          checkNonNull(input);
-        }
-        js.Expression nullTest = pop();
-        checkType(input, type, negative: negative);
-        push(new js.Binary(negative ? '||' : '&&', nullTest, pop()));
+      } else if (type.kind == TypeKind.FUNCTION) {
+        checkType(input, interceptor, type, negative: negative);
         attachLocationToLast(node);
       } else if ((input.canBePrimitive(compiler)
                   && !input.canBePrimitiveArray(compiler))
                  || input.canBeNull()) {
         checkObject(input, relation);
         js.Expression objectTest = pop();
-        checkType(input, type, negative: negative);
+        checkType(input, interceptor, type, negative: negative);
         push(new js.Binary(negative ? '||' : '&&', objectTest, pop()), node);
       } else {
-        checkType(input, type, negative: negative);
+        checkType(input, interceptor, type, negative: negative);
         attachLocationToLast(node);
       }
     }
-    if (node.nullOk) {
-      if (negative) {
-        checkNonNull(input);
-        push(new js.Binary('&&', pop(), pop()), node);
-      } else {
-        checkNull(input);
-        push(new js.Binary('||', pop(), pop()), node);
-      }
-    }
   }
 
   js.Expression generateTest(HCheck node) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
index 1ea358d..cc36e72 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
@@ -191,6 +191,11 @@
     } else {
       interceptedClasses = new Set<ClassElement>();
       for (var user in node.usedBy) {
+        if (user is HIs) {
+          // Is-checks can be performed on any intercepted class.
+          interceptedClasses.addAll(backend.interceptedClasses);
+          break;
+        }
         if (user is! HInvoke) continue;
         // We don't handle escaping interceptors yet.
         interceptedClasses.addAll(
@@ -248,7 +253,6 @@
     return true;
   }
 
-  
   bool visitOneShotInterceptor(HOneShotInterceptor node) {
     HInstruction constant = tryComputeConstantInterceptor(
         node.inputs[1], node.interceptedClasses);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index a5110bb..ab9121e 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -2209,11 +2209,29 @@
   static const int VARIABLE_CHECK = 2;
 
   final DartType typeExpression;
-  final bool nullOk;
   final int kind;
 
-  HIs(this.typeExpression, List<HInstruction> inputs, this.kind,
-      {this.nullOk: false}) : super(inputs) {
+  HIs.direct(DartType typeExpression,
+             HInstruction expression)
+      : this.internal(typeExpression, [expression], RAW_CHECK);
+
+  HIs.raw(DartType typeExpression,
+          HInstruction expression,
+          HInterceptor interceptor)
+      : this.internal(typeExpression, [expression, interceptor], RAW_CHECK);
+
+  HIs.compound(DartType typeExpression,
+               HInstruction expression,
+               HInstruction call)
+      : this.internal(typeExpression, [expression, call], COMPOUND_CHECK);
+
+  HIs.variable(DartType typeExpression,
+               HInstruction expression,
+               HInstruction call)
+      : this.internal(typeExpression, [expression, call], VARIABLE_CHECK);
+
+  HIs.internal(this.typeExpression, List<HInstruction> inputs, this.kind)
+      : super(inputs) {
     assert(kind >= RAW_CHECK && kind <= VARIABLE_CHECK);
     setUseGvn();
     instructionType = HType.BOOLEAN;
@@ -2221,6 +2239,11 @@
 
   HInstruction get expression => inputs[0];
 
+  HInstruction get interceptor {
+    assert(kind == RAW_CHECK);
+    return inputs.length > 1 ? inputs[1] : null;
+  }
+
   HInstruction get checkCall {
     assert(kind == VARIABLE_CHECK || kind == COMPOUND_CHECK);
     return inputs[1];
@@ -2240,7 +2263,6 @@
 
   bool dataEquals(HIs other) {
     return typeExpression == other.typeExpression
-        && nullOk == other.nullOk
         && kind == other.kind;
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index e89ba47..791866a 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -293,10 +293,13 @@
             target = backend.jsStringSplit;
           }
         } else if (selector.applies(backend.jsStringConcat, compiler)) {
-          if (node.inputs[2].isString(compiler)) {
+          // `concat` is turned into a JavaScript '+' so we need to
+          // make sure the receiver is not null.
+          if (node.inputs[2].isString(compiler) && !input.canBeNull()) {
             target = backend.jsStringConcat;
           }
-        } else if (selector.applies(backend.jsStringToString, compiler)) {
+        } else if (selector.applies(backend.jsStringToString, compiler)
+                   && !input.canBeNull()) {
           return input;
         }
       }
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 c13d7a4..487ed93 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -572,6 +572,10 @@
   Element locateSingleElement(Selector selector, Compiler compiler) {
     throw new UnsupportedError("");
   }
+
+  bool needsNoSuchMethodHandling(Selector selector, Compiler compiler) {
+    throw new UnsupportedError("");
+  }
 }
 
 /**
diff --git a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
index 449ae88..069de64 100644
--- a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
@@ -495,6 +495,55 @@
            });
   }
 
+  bool needsNoSuchMethodHandling(Selector selector, Compiler compiler) {
+    // A call on an empty type mask is dead code.
+    if (isEmpty && !isNullable) return false;
+    // A call on an exact mask for an abstract class is dead code.
+    if (isExact && base.element.isAbstract(compiler)) return false;
+    // If the receiver is guaranteed to have a member that
+    // matches what we're looking for, there's no need to
+    // introduce a noSuchMethod handler. It will never be called.
+    //
+    // As an example, consider this class hierarchy:
+    //
+    //                   A    <-- noSuchMethod
+    //                  / \
+    //                 C   B  <-- foo
+    //
+    // If we know we're calling foo on an object of type B we
+    // don't have to worry about the noSuchMethod method in A
+    // because objects of type B implement foo. On the other hand,
+    // if we end up calling foo on something of type C we have to
+    // add a handler for it.
+
+    // If the holders of all user-defined noSuchMethod
+    // implementations that might be applicable to the receiver
+    // type have a matching member for the current name and
+    // selector, we avoid introducing a noSuchMethod handler.
+    //
+    // As an example, consider this class hierarchy:
+    //
+    //                       A    <-- foo
+    //                      / \
+    //   noSuchMethod -->  B   C  <-- bar
+    //                     |   |
+    //                     C   D  <-- noSuchMethod
+    //
+    // When calling foo on an object of type A, we know that the
+    // implementations of noSuchMethod are in the classes B and D
+    // that also (indirectly) implement foo, so we do not need a
+    // handler for it.
+    //
+    // If we're calling bar on an object of type D, we don't need
+    // the handler either because all objects of type D implement
+    // bar through inheritance.
+    //
+    // If we're calling bar on an object of type A we do need the
+    // handler because we may have to call B.noSuchMethod since B
+    // does not implement bar.
+    return !willHit(selector, compiler);
+  }
+
   Element locateSingleElement(Selector selector, Compiler compiler) {
     if (isEmpty) return null;
     Iterable<Element> targets = compiler.world.allFunctions.filter(selector);
diff --git a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
index 2741a99..cd3a071 100644
--- a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
@@ -90,6 +90,10 @@
     return forwardTo.willHit(selector, compiler);
   }
 
+  bool needsNoSuchMethodHandling(Selector selector, Compiler compiler) {
+    return forwardTo.needsNoSuchMethodHandling(selector, compiler);
+  }
+
   bool canHit(Element element, Selector selector, Compiler compiler) {
     return forwardTo.canHit(element, selector, compiler);
   }
diff --git a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
index 519d1fd..a549a6e 100644
--- a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
@@ -1207,11 +1207,14 @@
       if (!visitingOptionalParameter) {
         type = arguments.positional[parameterIndex];
       } else {
-        type = signature.optionalParametersAreNamed
-            ? arguments.named[parameter.name]
-            : parameterIndex < arguments.positional.length
-                ? arguments.positional[parameterIndex]
-                : info.defaultType;
+        if (signature.optionalParametersAreNamed) {
+          type = arguments.named[parameter.name];
+          if (type == null) type = info.defaultType;
+        } else if (parameterIndex < arguments.positional.length) {
+          type = arguments.positional[parameterIndex];
+        } else {
+          type = info.defaultType;
+        }
       }
       TypeMask oldType = info.assignments[node];
       info.addAssignment(node, type);
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index 47bd8bf..f5f473f 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -103,6 +103,12 @@
   bool willHit(Selector selector, Compiler compiler);
 
   /**
+   * Returns whether this [TypeMask] applied to [selector] can hit a
+   * [noSuchMethod].
+   */
+  bool needsNoSuchMethodHandling(Selector selector, Compiler compiler);
+
+  /**
    * Returns whether [element] is a potential target when being
    * invoked on this type mask. [selector] is used to ensure library
    * privacy is taken into account.
diff --git a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
index ed4eb2b..1167e6d 100644
--- a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
@@ -239,6 +239,11 @@
     return disjointMasks.every((e) => e.willHit(selector, compiler));
   }
 
+  bool needsNoSuchMethodHandling(Selector selector, Compiler compiler) {
+    return disjointMasks.any(
+        (e) => e.needsNoSuchMethodHandling(selector, compiler));
+  }
+
   bool canHit(Element element, Selector selector, Compiler compiler) {
     return disjointMasks.any((e) => e.canHit(element, selector, compiler));
   }
diff --git a/sdk/lib/_internal/compiler/implementation/universe/function_set.dart b/sdk/lib/_internal/compiler/implementation/universe/function_set.dart
index a228736..bae06cb 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/function_set.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/function_set.dart
@@ -172,7 +172,8 @@
     // If we cannot ensure a method will be found at runtime, we also
     // add [noSuchMethod] implementations that apply to [mask] as
     // potential targets.
-    if (noSuchMethods != null && !mask.willHit(selector, compiler)) {
+    if (noSuchMethods != null
+        && mask.needsNoSuchMethodHandling(selector, compiler)) {
       FunctionSetQuery noSuchMethodQuery = noSuchMethods.query(
           new TypedSelector(mask, compiler.noSuchMethodSelector),
           compiler,
diff --git a/sdk/lib/_internal/lib/json_patch.dart b/sdk/lib/_internal/lib/convert_patch.dart
similarity index 92%
rename from sdk/lib/_internal/lib/json_patch.dart
rename to sdk/lib/_internal/lib/convert_patch.dart
index ad22ae7..1a84485 100644
--- a/sdk/lib/_internal/lib/json_patch.dart
+++ b/sdk/lib/_internal/lib/convert_patch.dart
@@ -10,7 +10,7 @@
 /**
  * Parses [json] and builds the corresponding parsed JSON value.
  *
- * Parsed JSON values are of the types [num], [String], [bool], [Null],
+ * Parsed JSON values Nare of the types [num], [String], [bool], [Null],
  * [List]s of parsed JSON values or [Map]s from [String] to parsed
  * JSON values.
  *
@@ -23,14 +23,14 @@
  *
  * Throws [FormatException] if the input is not valid JSON text.
  */
-patch parse(String json, [reviver(var key, var value)]) {
-  if (json is! String) throw new ArgumentError(json);
+patch _parseJson(String source, reviver(var key, var value)) {
+  if (source is! String) throw new ArgumentError(source);
 
   var parsed;
   try {
     parsed = JS('=Object|JSExtendableArray|Null|bool|num|String',
                 'JSON.parse(#)',
-                json);
+                source);
   } catch (e) {
     throw new FormatException(JS('String', 'String(#)', e));
   }
@@ -90,5 +90,5 @@
     return map;
   }
 
-  return revive('', walk(json));
+  return revive(null, walk(json));
 }
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index e5ec91f..412c9b4 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -124,21 +124,24 @@
   bool get isAccessor => _kind != METHOD;
 
   List get positionalArguments {
-    if (isGetter) return null;
-    var list = [];
+    if (isGetter) return const [];
     var argumentCount =
         _arguments.length - _namedArgumentNames.length;
+    if (argumentCount == 0) return const [];
+    var list = [];
     for (var index = 0 ; index < argumentCount ; index++) {
       list.add(_arguments[index]);
     }
-    return list;
+    return makeLiteralListConst(list);
   }
 
   Map<Symbol,dynamic> get namedArguments {
-    if (isAccessor) return null;
-    var map = new Map<Symbol, dynamic>();
+    // TODO: Make maps const (issue 10471)
+    if (isAccessor) return <Symbol, dynamic>{};
     int namedArgumentCount = _namedArgumentNames.length;
     int namedArgumentsStartIndex = _arguments.length - namedArgumentCount;
+    if (namedArgumentCount == 0) return <Symbol, dynamic>{};
+    var map = new Map<Symbol, dynamic>();
     for (int i = 0; i < namedArgumentCount; i++) {
       map[new _symbol_dev.Symbol.unvalidated(_namedArgumentNames[i])] =
           _arguments[namedArgumentsStartIndex + i];
diff --git a/sdk/lib/_internal/lib/mirror_helper.dart b/sdk/lib/_internal/lib/mirror_helper.dart
new file mode 100644
index 0000000..9c3024f
--- /dev/null
+++ b/sdk/lib/_internal/lib/mirror_helper.dart
@@ -0,0 +1,25 @@
+// 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.
+/**
+ * Helps dealing with reflection in the case that the source code has been
+ * changed as a result of compiling with dart2dart.
+ */
+library _mirror_helper;
+
+import 'dart:mirrors';
+
+/// The compiler will replace this variable with a map containing all the
+/// renames made in dart2dart.
+const Map<String, String> _SYMBOLS = null;
+
+/// This method is a wrapper for MirrorSystem.getName() and will be inlined and
+/// called in the generated output Dart code.
+String helperGetName(Symbol sym) {
+  var name = MirrorSystem.getName(sym);
+  if (_SYMBOLS.containsKey(name)) {
+    return _SYMBOLS[name];
+  } else {
+    return name;
+  }
+}
diff --git a/sdk/lib/_internal/lib/scalarlist_patch.dart b/sdk/lib/_internal/lib/scalarlist_patch.dart
deleted file mode 100644
index 326b892..0000000
--- a/sdk/lib/_internal/lib/scalarlist_patch.dart
+++ /dev/null
@@ -1,130 +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.
-
-// This is an empty dummy patch file for the VM dart:scalarlist library.
-// This is needed in order to be able to generate documentation for the
-// scalarlist library.
-
-patch class Int8List {
-  patch factory Int8List(int length) {
-    throw new UnsupportedError('Int8List');
-  }
-
-  patch factory Int8List.view(ByteArray array, [int start = 0, int length]) {
-    throw new UnsupportedError('Int8List.view');
-  }
-}
-
-
-patch class Uint8List {
-  patch factory Uint8List(int length) {
-    throw new UnsupportedError('Uint8List');
-  }
-
-  patch factory Uint8List.view(ByteArray array,
-                               [int start = 0, int length]) {
-    throw new UnsupportedError('Uint8List.view');
-  }
-}
-
-
-patch class Uint8ClampedList {
-  patch factory Uint8ClampedList(int length) {
-    throw new UnsupportedError('Uint8ClampedList');
-  }
-
-  patch factory Uint8ClampedList.view(ByteArray array,
-                                      [int start = 0, int length]) {
-    throw new UnsupportedError('Uint8ClampedList.view');
-  }
-}
-
-
-patch class Int16List {
-  patch factory Int16List(int length) {
-    throw new UnsupportedError('Int16List');
-
-  }
-
-  patch factory Int16List.view(ByteArray array, [int start = 0, int length]) {
-    throw new UnsupportedError('Int16List.view');
-  }
-}
-
-
-patch class Uint16List {
-  patch factory Uint16List(int length) {
-    throw new UnsupportedError('Uint16List');
-  }
-
-  patch factory Uint16List.view(ByteArray array, [int start = 0, int length]) {
-    throw new UnsupportedError('Uint16List.view');
-  }
-}
-
-
-patch class Int32List {
-  patch factory Int32List(int length) {
-    throw new UnsupportedError('Int32List');
-  }
-
-  patch factory Int32List.view(ByteArray array, [int start = 0, int length]) {
-    throw new UnsupportedError('Int32List.view');
-  }
-}
-
-
-patch class Uint32List {
-  patch factory Uint32List(int length) {
-    throw new UnsupportedError('Uint32List');
-  }
-
-  patch factory Uint32List.view(ByteArray array, [int start = 0, int length]) {
-    throw new UnsupportedError('Uint32List.view');
-  }
-}
-
-
-patch class Int64List {
-  patch factory Int64List(int length) {
-    throw new UnsupportedError('Int64List');
-  }
-
-  patch factory Int64List.view(ByteArray array, [int start = 0, int length]) {
-    throw new UnsupportedError('Int64List.view');
-  }
-}
-
-
-patch class Uint64List {
-  patch factory Uint64List(int length) {
-    throw new UnsupportedError('Uint64List');
-  }
-
-  patch factory Uint64List.view(ByteArray array, [int start = 0, int length]) {
-    throw new UnsupportedError('Uint64List.view');
-  }
-}
-
-
-patch class Float32List {
-  patch factory Float32List(int length) {
-    throw new UnsupportedError('Float32List');
-  }
-
-  patch factory Float32List.view(ByteArray array, [int start = 0, int length]) {
-    throw new UnsupportedError('Float32List.view');
-  }
-}
-
-
-patch class Float64List {
-  patch factory Float64List(int length) {
-    throw new UnsupportedError('Float64List');
-  }
-
-  patch factory Float64List.view(ByteArray array, [int start = 0, int length]) {
-    throw new UnsupportedError('Float64List.view');
-  }
-}
diff --git a/sdk/lib/_internal/lib/typed_data_patch.dart b/sdk/lib/_internal/lib/typed_data_patch.dart
deleted file mode 100644
index 1f32792..0000000
--- a/sdk/lib/_internal/lib/typed_data_patch.dart
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This is an empty dummy patch file for the VM dart:typed_data library.
-// This is needed in order to be able to generate documentation for the
-// typed_data library.
-
-patch class Int8List {
-  patch factory Int8List(int length) {
-    throw new UnsupportedError('Int8List');
-  }
-
-  patch factory Int8List.fromList(List<int> elements) {
-    throw new UnsupportedError('Int8List.fromList');
-  }
-
-  patch factory Int8List.view(ByteBuffer buffer,
-                              [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('Int8List.view');
-  }
-}
-
-
-patch class Uint8List {
-  patch factory Uint8List(int length) {
-    throw new UnsupportedError('Uint8List');
-  }
-
-  patch factory Uint8List.fromList(List<int> elements) {
-    throw new UnsupportedError('Uint8List.fromList');
-  }
-
-  patch factory Uint8List.view(ByteBuffer buffer,
-                               [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('Uint8List.view');
-  }
-}
-
-
-patch class Uint8ClampedList {
-  patch factory Uint8ClampedList(int length) {
-    throw new UnsupportedError('Uint8ClampedList');
-  }
-
-  patch factory Uint8ClampedList.fromList(List<int> elements) {
-    throw new UnsupportedError('Uint8ClampedList.fromList');
-  }
-
-  patch factory Uint8ClampedList.view(ByteBuffer buffer,
-                                      [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('Uint8ClampedList.view');
-  }
-}
-
-
-patch class Int16List {
-  patch factory Int16List(int length) {
-    throw new UnsupportedError('Int16List');
-
-  }
-
-  patch factory Int16List.fromList(List<int> elements) {
-    throw new UnsupportedError('Int16List.fromList');
-  }
-
-  patch factory Int16List.view(ByteBuffer buffer,
-                               [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('Int16List.view');
-  }
-}
-
-
-patch class Uint16List {
-  patch factory Uint16List(int length) {
-    throw new UnsupportedError('Uint16List');
-  }
-
-  patch factory Uint16List.fromList(List<int> elements) {
-    throw new UnsupportedError('Uint16List.fromList');
-  }
-
-  patch factory Uint16List.view(ByteBuffer buffer,
-                                [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('Uint16List.view');
-  }
-}
-
-
-patch class Int32List {
-  patch factory Int32List(int length) {
-    throw new UnsupportedError('Int32List');
-  }
-
-  patch factory Int32List.fromList(List<int> elements) {
-    throw new UnsupportedError('Int32List.fromList');
-  }
-
-  patch factory Int32List.view(ByteBuffer buffer,
-                               [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('Int32List.view');
-  }
-}
-
-
-patch class Uint32List {
-  patch factory Uint32List(int length) {
-    throw new UnsupportedError('Uint32List');
-  }
-
-  patch factory Uint32List.fromList(List<int> elements) {
-    throw new UnsupportedError('Uint32List.fromList');
-  }
-
-  patch factory Uint32List.view(ByteBuffer buffer,
-                                [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('Uint32List.view');
-  }
-}
-
-
-patch class Int64List {
-  patch factory Int64List(int length) {
-    throw new UnsupportedError('Int64List');
-  }
-
-  patch factory Int64List.fromList(List<int> elements) {
-    throw new UnsupportedError('Int64List.fromList');
-  }
-
-  patch factory Int64List.view(ByteBuffer buffer,
-                               [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('Int64List.view');
-  }
-}
-
-
-patch class Uint64List {
-  patch factory Uint64List(int length) {
-    throw new UnsupportedError('Uint64List');
-  }
-
-  patch factory Uint64List.fromList(List<int> elements) {
-    throw new UnsupportedError('Uint64List.fromList');
-  }
-
-  patch factory Uint64List.view(ByteBuffer buffer,
-                                [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('Uint64List.view');
-  }
-}
-
-
-patch class Float32List {
-  patch factory Float32List(int length) {
-    throw new UnsupportedError('Float32List');
-  }
-
-  patch factory Float32List.fromList(List<double> elements) {
-    throw new UnsupportedError('Float32List.fromList');
-  }
-
-  patch factory Float32List.view(ByteBuffer buffer,
-                                 [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('Float32List.view');
-  }
-}
-
-
-patch class Float64List {
-  patch factory Float64List(int length) {
-    throw new UnsupportedError('Float64List');
-  }
-
-  patch factory Float64List.fromList(List<double> elements) {
-    throw new UnsupportedError('Float64List.fromList');
-  }
-
-  patch factory Float64List.view(ByteBuffer buffer,
-                                 [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('Float64List.view');
-  }
-}
-
-
-patch class Float32x4List {
-  patch factory Float32x4List(int length) {
-    throw new UnsupportedError('Float32x4List');
-  }
-
-  patch factory Float32x4List.view(ByteBuffer buffer,
-                                      [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('Float32x4List.view');
-  }
-}
-
-
-patch class Float32x4 {
-  patch factory Float32x4(double x, double y, double z, double w) {
-    throw new UnsupportedError('Float32x4');
-  }
-  patch factory Float32x4.splat(double v) {
-    throw new UnsupportedError('Float32x4.splat');
-  }
-  patch factory Float32x4.zero() {
-    throw new UnsupportedError('Float32x4.zero');
-  }
-}
-
-
-patch class Uint32x4 {
-  patch factory Uint32x4(int x, int y, int z, int w) {
-    throw new UnsupportedError('Uint32x4');
-  }
-  patch factory Uint32x4.bool(bool x, bool y, bool z, bool w) {
-    throw new UnsupportedError('Uint32x4.bool');
-  }
-}
-
-
-patch class ByteData {
-  patch factory ByteData(int length) {
-    throw new UnsupportedError('ByteData');
-  }
-
-  patch factory ByteData.view(ByteBuffer buffer,
-                              [int offsetInBytes = 0, int length]) {
-    throw new UnsupportedError('ByteData.view');
-  }
-}
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index 59639f9..bf796ac 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -35,7 +35,8 @@
       dart2jsPatchPath: "_internal/lib/collection_patch.dart"),
 
   "convert": const LibraryInfo(
-      "convert/convert.dart"),
+      "convert/convert.dart",
+      dart2jsPatchPath: "_internal/lib/convert_patch.dart"),
 
   "core": const LibraryInfo(
       "core/core.dart",
@@ -73,8 +74,7 @@
       dart2jsPath: "js/dart2js/js_dart2js.dart"),
 
   "json": const LibraryInfo(
-      "json/json.dart",
-      dart2jsPatchPath: "_internal/lib/json_patch.dart"),
+      "json/json.dart"),
 
   "math": const LibraryInfo(
       "math/math.dart",
@@ -160,6 +160,12 @@
       category: "Internal",
       documented: false,
       platforms: DART2JS_PLATFORM),
+
+   "_mirror_helper": const LibraryInfo(
+      "_internal/lib/mirror_helper.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM)
 };
 
 /**
diff --git a/sdk/lib/_internal/pub/lib/src/http.dart b/sdk/lib/_internal/pub/lib/src/http.dart
index b23dfd0..a54f02f 100644
--- a/sdk/lib/_internal/pub/lib/src/http.dart
+++ b/sdk/lib/_internal/pub/lib/src/http.dart
@@ -204,8 +204,7 @@
   var value;
   try {
     value = json.parse(response.body);
-  } catch (e) {
-    // TODO(nweiz): narrow this catch clause once issue 6775 is fixed.
+  } on FormatException catch (e) {
     invalidServerResponse(response);
   }
   if (value is! Map) invalidServerResponse(response);
diff --git a/sdk/lib/_internal/pub/lib/src/validator/utf8_readme.dart b/sdk/lib/_internal/pub/lib/src/validator/utf8_readme.dart
index 28cccbd..9f30d65 100644
--- a/sdk/lib/_internal/pub/lib/src/validator/utf8_readme.dart
+++ b/sdk/lib/_internal/pub/lib/src/validator/utf8_readme.dart
@@ -5,7 +5,7 @@
 library pub.validator.utf8_readme;
 
 import 'dart:async';
-import 'dart:utf';
+import 'dart:convert';
 
 import '../entrypoint.dart';
 import '../io.dart';
@@ -22,11 +22,9 @@
       if (readme == null) return;
       var bytes = readBinaryFile(readme);
       try {
-        // The second and third arguments here are the default values. The
-        // fourth tells [decodeUtf8] to throw an ArgumentError if `bytes` isn't
-        // valid utf-8.
-        decodeUtf8(bytes, 0, null, null);
-      } on ArgumentError catch (_) {
+        // UTF8.decode doesn't allow invalid UTF-8.
+        UTF8.decode(bytes);
+      } on FormatException catch (_) {
         warnings.add("$readme contains invalid UTF-8.\n"
             "This will cause it to be displayed incorrectly on "
                 "pub.dartlang.org.");
diff --git a/sdk/lib/_internal/pub/pub.status b/sdk/lib/_internal/pub/pub.status
index 56f997a..276a0d5 100644
--- a/sdk/lib/_internal/pub/pub.status
+++ b/sdk/lib/_internal/pub/pub.status
@@ -2,16 +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.
 
-test/serve/missing_file_test: Pass, Fail # 12570
-test/oauth2/with_an_expired_credentials_refreshes_and_saves_test: Pass, Fail # 12581
-test/hosted/remove_removed_dependency_test: Pass, Fail # 12582
-test/hosted/remove_removed_transitive_dependency_test: Pass, Fail # 12582
-test/install/hosted/cached_pubspec_test: Pass, Fail # 12678
-test/install/hosted/do_not_update_on_removed_constraints_test: Pass, Fail # 12680
-test/install/hosted/install_test: Pass, Fail # 12682
-test/install/hosted/install_transitive_test: Pass, Fail # 12683
-test/install/hosted/repair_cache_test: Pass, Fail # 12684
-pub/test/serve/serve_from_dependency_asset_test: Pass, Fail # 12686
+test/serve/missing_file_test: Pass, Fail # Issue 12570
+test/oauth2/with_an_expired_credentials_refreshes_and_saves_test: Pass, Fail # Issue 12581
+test/hosted/remove_removed_dependency_test: Pass, Fail # Issue 12582
+test/hosted/remove_removed_transitive_dependency_test: Pass, Fail # Issue 12582
+test/install/hosted/cached_pubspec_test: Pass, Fail # Issue 12678
+test/install/hosted/do_not_update_on_removed_constraints_test: Pass, Fail # Issue 12680
+test/install/hosted/install_test: Pass, Fail # Issue 12682
+test/install/hosted/install_transitive_test: Pass, Fail # Issue 12683
+test/install/hosted/repair_cache_test: Pass, Fail # Issue 12684
+test/serve/serve_from_dependency_asset_test: Pass, Fail # Issue 12686
+test/install/hosted/stay_locked_if_new_is_satisfied_test: Pass, Fail # Issue 12837
+test/install/hosted/unlock_if_incompatible_test: Pass, Fail # Issue 12837
+test/install/hosted/unlock_if_new_is_unsatisfied_test: Pass, Fail # Issue 12837
+test/install/hosted/stay_locked_test: Pass, Fail # Issue 12837
 
 # Pub only runs on the VM, so just rule out all compilers.
 [ $compiler == dart2js || $compiler == dart2dart ]
diff --git a/sdk/lib/_internal/pub/test/test_pub.dart b/sdk/lib/_internal/pub/test/test_pub.dart
index 81e74e8..bf51392 100644
--- a/sdk/lib/_internal/pub/test/test_pub.dart
+++ b/sdk/lib/_internal/pub/test/test_pub.dart
@@ -39,6 +39,7 @@
 /// test configuration for the machine running the tests.
 initConfig() {
   useCompactVMConfiguration();
+  filterStacks = true;
 }
 
 /// Returns whether we're running on a Dart build bot.
@@ -573,13 +574,8 @@
   }
 }
 
-// TODO(nweiz): use the built-in mechanism for accessing this once it exists
-// (issue 9119).
 /// The path to the `packages` directory from which pub loads its dependencies.
-String get _packageRoot {
-  return path.absolute(path.join(
-      path.dirname(Platform.executable), '..', '..', 'packages'));
-}
+String get _packageRoot => path.absolute(Platform.packageRoot);
 
 /// Skips the current test if Git is not installed. This validates that the
 /// current test is running on a buildbot in which case we expect git to be
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 02e51a0..4904415 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -406,7 +406,7 @@
   /**
    * Completes [future] with the supplied values.
    *
-   * All listeners on the future will be immediately informed about the value.
+   * All listeners on the future are informed about the value.
    */
   void complete([T value]);
 
@@ -416,7 +416,7 @@
    * Completing a future with an error indicates that an exception was thrown
    * while trying to produce a value.
    *
-   * The argument [exception] should not be `null`.
+   * The argument [exception] must not be `null`.
    */
   void completeError(Object exception, [Object stackTrace]);
 
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 222ad8d..4242e4f 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -233,7 +233,7 @@
    * or simply return to make the stream forget the error.
    *
    * If you need to transform an error into a data event, use the more generic
-   * [Stream.transformEvent] to handle the event by writing a data event to
+   * [Stream.transform] to handle the event by writing a data event to
    * the output sink
    */
   Stream<T> handleError(void handle( error), { bool test(error) }) {
@@ -592,7 +592,7 @@
    *
    * Error and done events are provided by the returned stream unmodified.
    *
-   * Starting with the first data event where [test] returns true for the
+   * Starting with the first data event where [test] returns false for the
    * event data, the returned stream will have the same events as this stream.
    */
   Stream<T> skipWhile(bool test(T element)) {
@@ -613,10 +613,18 @@
   }
 
   /**
-   * Returns the first element.
+   * Returns the first element of the stream.
    *
-   * If [this] is empty throws a [StateError]. Otherwise this method is
-   * equivalent to [:this.elementAt(0):]
+   * Stops listening to the stream after the first element has been received.
+   *
+   * If an error event occurs before the first data event, the resulting future
+   * is completed with that error.
+   *
+   * If this stream is empty (a done event occurs before the first data event),
+   * the resulting future completes with a [StateError].
+   *
+   * Except for the type of the error, this method is equivalent to
+   * [:this.elementAt(0):].
    */
   Future<T> get first {
     _FutureImpl<T> future = new _FutureImpl<T>();
@@ -636,9 +644,13 @@
   }
 
   /**
-   * Returns the last element.
+   * Returns the last element of the stream.
    *
-   * If [this] is empty throws a [StateError].
+   * If an error event occurs before the first data event, the resulting future
+   * is completed with that error.
+   *
+   * If this stream is empty (a done event occurs before the first data event),
+   * the resulting future completes with a [StateError].
    */
   Future<T> get last {
     _FutureImpl<T> future = new _FutureImpl<T>();
@@ -824,10 +836,13 @@
   /**
    * Returns the value of the [index]th data event of this stream.
    *
-   * If an error event occurs, the future will end with this error.
+   * Stops listening to the stream after a value has been found.
    *
-   * If this stream provides fewer than [index] elements before closing,
-   * an error is reported.
+   * If an error event occurs before the value is found, the future completes
+   * with this error.
+   *
+   * If a done event occurs before the value is found, the future completes
+   * with a [RangeError].
    */
   Future<T> elementAt(int index) {
     if (index is! int || index < 0) throw new ArgumentError(index);
@@ -844,7 +859,7 @@
       },
       onError: future._setError,
       onDone: () {
-        future._setError(new StateError("Not enough elements for elementAt"));
+        future._setError(new RangeError.value(index));
       },
       cancelOnError: true);
     return future;
@@ -1018,7 +1033,7 @@
    * Example use:
    *
    *     stringStream.transform(new StreamTransformer<String, String>(
-   *         handleData: (Strung value, EventSink<String> sink) {
+   *         handleData: (String value, EventSink<String> sink) {
    *           sink.add(value);
    *           sink.add(value);  // Duplicate the incoming events.
    *         }));
diff --git a/sdk/lib/collection/iterable.dart b/sdk/lib/collection/iterable.dart
index 6dbf92d..9cbdf89 100644
--- a/sdk/lib/collection/iterable.dart
+++ b/sdk/lib/collection/iterable.dart
@@ -54,7 +54,7 @@
     return true;
   }
 
-  String join([String separator]) {
+  String join([String separator = ""]) {
     Iterator<E> iterator = this.iterator;
     if (!iterator.moveNext()) return "";
     StringBuffer buffer = new StringBuffer();
@@ -245,7 +245,7 @@
     return true;
   }
 
-  String join([String separator]) {
+  String join([String separator = ""]) {
     Iterator<E> iterator = this.iterator;
     if (!iterator.moveNext()) return "";
     StringBuffer buffer = new StringBuffer();
diff --git a/sdk/lib/collection/linked_hash_map.dart b/sdk/lib/collection/linked_hash_map.dart
index 4ace589..ee38ae7 100644
--- a/sdk/lib/collection/linked_hash_map.dart
+++ b/sdk/lib/collection/linked_hash_map.dart
@@ -10,7 +10,7 @@
  * Keys insertion order is remembered, and keys are iterated in insertion order.
  * Values are iterated in their corresponding key's order.
  *
- * The keys of a `HashMap` must have consistent [Object.operator==]
+ * The keys of a `LinkedHashMap` must have consistent [Object.operator==]
  * and [Object.hashCode] implementations. This means that the `==` operator
  * must define a stable equivalence relation on the keys (reflexive,
  * anti-symmetric, transitive, and consistent over time), and that `hashCode`
@@ -18,7 +18,7 @@
  *
  * The map allows `null` as a key.
  */
-class LinkedHashMap<K, V> implements Map<K, V> {
+class LinkedHashMap<K, V> implements HashMap<K, V> {
   external LinkedHashMap();
 
   /**
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index 035a89e..845d53f 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -5,6 +5,47 @@
 part of dart.convert;
 
 /**
+ * Error thrown by JSON serialization if an object cannot be serialized.
+ *
+ * The [unsupportedObject] field holds that object that failed to be serialized.
+ *
+ * If an object isn't directly serializable, the serializer calls the 'toJson'
+ * method on the object. If that call fails, the error will be stored in the
+ * [cause] field. If the call returns an object that isn't directly
+ * serializable, the [cause] is be null.
+ */
+class JsonUnsupportedObjectError extends Error {
+  /** The object that could not be serialized. */
+  final unsupportedObject;
+  /** The exception thrown by object's [:toJson:] method, if any. */
+  final cause;
+
+  JsonUnsupportedObjectError(this.unsupportedObject, { this.cause });
+
+  String toString() {
+    if (cause != null) {
+      return "Calling toJson method on object failed.";
+    } else {
+      return "Object toJson method returns non-serializable value.";
+    }
+  }
+}
+
+
+/**
+ * Reports that an object could not be stringified due to cyclic references.
+ *
+ * An object that references itself cannot be serialized by [stringify].
+ * When the cycle is detected, a [JsonCyclicError] is thrown.
+ */
+class JsonCyclicError extends JsonUnsupportedObjectError {
+  /** The first object that was detected as part of a cycle. */
+  JsonCyclicError(Object object): super(object);
+  String toString() => "Cyclic error in JSON stringify";
+}
+
+
+/**
  * An instance of the default implementation of the [JsonCodec].
  *
  * This instance provides a convenient access to the most common JSON
@@ -181,7 +222,7 @@
    *
    * Throws [FormatException] if the input is not valid JSON text.
    */
-  Object convert(String input) => OLD_JSON_LIB.parse(input, _reviver);
+  Object convert(String input) => _parseJson(input, _reviver);
 
   /**
    * Starts a conversion from a chunked JSON string to its corresponding
@@ -217,8 +258,11 @@
     StringBuffer buffer = _stringSink;
     String accumulated = buffer.toString();
     buffer.clear();
-    Object decoded = OLD_JSON_LIB.parse(accumulated, _reviver);
+    Object decoded = _parseJson(accumulated, _reviver);
     _chunkedSink.add(decoded);
     _chunkedSink.close();
   }
 }
+
+// Internal optimized JSON parsing implementation.
+external _parseJson(String source, reviver(key, value));
diff --git a/sdk/lib/core/invocation.dart b/sdk/lib/core/invocation.dart
index 0388e21..7deaeec 100644
--- a/sdk/lib/core/invocation.dart
+++ b/sdk/lib/core/invocation.dart
@@ -15,10 +15,19 @@
   /** The name of the invoked member. */
   Symbol get memberName;
 
-  /** An unmodifiable view of the positional arguments of the call. */
+  /**
+   * An unmodifiable view of the positional arguments of the call.
+   *
+   * If the member is a getter, the positional arguments is empty.
+   */
   List get positionalArguments;
 
-  /** An unmodifiable view of the named arguments of the call. */
+  /**
+   * An unmodifiable view of the named arguments of the call.
+   *
+   * If the member is a getter, setter or operator, the named arguments
+   * is empty.
+   */
   Map<Symbol, dynamic> get namedArguments;
 
   /** Whether the invocation was a method call. */
@@ -26,15 +35,15 @@
 
   /**
    * Whether the invocation was a getter call.
-   * If so, both types of arguments will be null.
+   * If so, both types of arguments is empty.
    */
   bool get isGetter;
 
   /**
    * Whether the invocation was a setter call.
    *
-   * If so, [arguments] will have exactly one positonal argument,
-   * and namedArguments will be null.
+   * If so, [arguments] has exactly one positonal argument,
+   * and [namedArguments] is empty.
    */
   bool get isSetter;
 
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 9d919ae..0e1f05a 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -5,28 +5,38 @@
 part of dart.core;
 
 /**
- * The [Iterable] interface allows to get an [Iterator] out of an
- * [Iterable] object.
+ * An object that uses an [Iterator] to serve objects one at a time.
  *
- * This interface is used by the for-in construct to iterate over an
- * [Iterable] object.
- * The for-in construct takes an [Iterable] object at the right-hand
- * side, and calls its [iterator] method to get an [Iterator] on it.
+ * You can iterate over all objects served by an Iterable object
+ * using the for-in loop construct.
+ * For example, you can iterate over all of the keys in a [Map],
+ * because Map keys are iterable.
  *
- * A user-defined class that implements the [Iterable] interface can
- * be used as the right-hand side of a for-in construct.
+ *     Map kidsBooks = {'Matilda': 'Roald Dahl',
+ *                      'Green Eggs and Ham': 'Dr Seuss',
+ *                      'Where the Wild Things Are': 'Maurice Sendak'};
+ *     for (var book in kidsBooks.keys) {
+ *       print('$book was written by ${kidsBooks[book]}');
+ *     }
+ *
+ * The [List] class and the [Set] class implement this interface,
+ * as do classes in the [dart:collection](#dart-collection) library.
+ *
+ * You can implement Iterable in your own class.
+ * If you do, then an instance of your Iterable class
+ * can be the right-hand side of a for-in construct.
  */
 abstract class Iterable<E> {
   const Iterable();
 
   /**
-   * Create an [Iterable] that generates its elements dynamically.
+   * Creates an Iterable that generates its elements dynamically.
    *
-   * The [Iterators] created by the [Iterable] will count from
+   * The Iterators created by the Iterable count from
    * zero to [:count - 1:] while iterating, and call [generator]
    * with that index to create the next value.
    *
-   * As an [Iterable], [:new Iterable.generate(n, generator)):] is equivalent to
+   * As an Iterable, [:new Iterable.generate(n, generator)):] is equivalent to
    * [:const [0, ..., n - 1].map(generator):]
    */
   factory Iterable.generate(int count, E generator(int index)) {
@@ -34,7 +44,7 @@
   }
 
   /**
-   * Returns an [Iterator] that iterates over this [Iterable] object.
+   * Returns an Iterator that iterates over this Iterable object.
    */
   Iterator<E> get iterator;
 
@@ -57,24 +67,24 @@
    * This method returns a view of the mapped elements. As long as the
    * returned [Iterable] is not iterated over, the supplied function [test] will
    * not be invoked. Iterating will not cache results, and thus iterating
-   * multiple times over the the returned [Iterable] will invoke the supplied
+   * multiple times over the returned [Iterable] will invoke the supplied
    * function [test] multiple times on the same element.
    */
   Iterable<E> where(bool test(E element));
 
   /**
-   * Expand each element of this [Iterable] into zero or more elements.
+   * Expands each element of this [Iterable] into zero or more elements.
    *
-   * The resulting Iterable will run through the elements returned
+   * The resulting Iterable runs through the elements returned
    * by [f] for each element of this, in order.
    *
-   * The returned [Iterable] is lazy, and will call [f] for each element
+   * The returned [Iterable] is lazy, and calls [f] for each element
    * of this every time it's iterated.
    */
   Iterable expand(Iterable f(E element));
 
   /**
-   * Check whether the collection contains an element equal to [element].
+   * Returns true if the collection contains an element equal to [element].
    */
   bool contains(Object element);
 
@@ -138,7 +148,7 @@
   /**
    * Creates a [List] containing the elements of this [Iterable].
    *
-   * The elements will be in iteration order. The list is fixed-length
+   * The elements are in iteration order. The list is fixed-length
    * if [growable] is false.
    */
   List<E> toList({ bool growable: true });
@@ -177,37 +187,37 @@
   Iterable<E> take(int n);
 
   /**
-   * Returns an [Iterable] that stops once [test] is not satisfied anymore.
+   * Returns an Iterable that stops once [test] is not satisfied anymore.
    *
-   * The filtering happens lazily. Every new [Iterator] of the returned
-   * [Iterable] will start iterating over the elements of `this`.
+   * The filtering happens lazily. Every new Iterator of the returned
+   * Iterable starts iterating over the elements of `this`.
    *
    * When the iterator encounters an element `e` that does not satisfy [test],
-   * it discards `e` and moves into the finished state. That is, it will not
-   * ask or provide any more elements.
+   * it discards `e` and moves into the finished state. That is, it does not
+   * get or provide any more elements.
    */
   Iterable<E> takeWhile(bool test(E value));
 
   /**
-   * Returns an [Iterable] that skips the first [n] elements.
+   * Returns an Iterable that skips the first [n] elements.
    *
-   * If `this` has fewer than [n] elements, then the resulting [Iterable] will
-   * be empty.
+   * If `this` has fewer than [n] elements, then the resulting Iterable is 
+   * empty.
    *
    * It is an error if [n] is negative.
    */
   Iterable<E> skip(int n);
 
   /**
-   * Returns an [Iterable] that skips elements while [test] is satisfied.
+   * Returns an Iterable that skips elements while [test] is satisfied.
    *
-   * The filtering happens lazily. Every new [Iterator] of the returned
-   * [Iterable] iterates over all elements of `this`.
+   * The filtering happens lazily. Every new Iterator of the returned
+   * Iterable iterates over all elements of `this`.
    *
    * As long as the iterator's elements satisfy [test] they are
    * discarded. Once an element does not satisfy the [test] the iterator stops
    * testing and uses every later element unconditionally. That is, the elements
-   * of the returned [Iterable] are the elements of `this` starting from the
+   * of the returned Iterable are the elements of `this` starting from the
    * first element that does not satisfy [test].
    */
   Iterable<E> skipWhile(bool test(E value));
@@ -303,7 +313,7 @@
 }
 
 /**
- * An [Iterator] that allows moving backwards as well as forwards.
+ * An Iterator that allows moving backwards as well as forwards.
  */
 abstract class BidirectionalIterator<E> implements Iterator<E> {
   /**
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index e5ccb87..79e81e4 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.dart
@@ -15,12 +15,12 @@
   /**
    * Creates a Map instance with the default implementation.
    */
-  factory Map() => new HashMap<K, V>();
+  factory Map() = LinkedHashMap<K, V>;
 
   /**
    * Creates a Map instance that contains all key-value pairs of [other].
    */
-  factory Map.from(Map<K, V> other) => new HashMap<K, V>.from(other);
+  factory Map.from(Map<K, V> other) = LinkedHashMap<K, V>.from;
 
   /**
    * Creates a Map instance
@@ -29,7 +29,7 @@
    * For each element of the [iterable] this constructor computes a key-value
    * pair, by applying [key] and [value] respectively.
    *
-   * The keys computed by the source [iterable] 
+   * The keys computed by the source [iterable]
    * do not need to be unique. The last
    * occurrence of a key will simply overwrite any previous value.
    *
@@ -37,7 +37,7 @@
    * identity function.
    */
   factory Map.fromIterable(Iterable<K> iterable,
-      {K key(element), V value(element)}) = HashMap<K, V>.fromIterable;
+      {K key(element), V value(element)}) = LinkedHashMap<K, V>.fromIterable;
 
   /**
    * Creates a Map instance associating the given [keys] to [values].
@@ -51,7 +51,7 @@
    * It is an error if the two [Iterable]s don't have the same length.
    */
   factory Map.fromIterables(Iterable<K> keys, Iterable<V> values)
-      = HashMap<K, V>.fromIterables;
+      = LinkedHashMap<K, V>.fromIterables;
 
   /**
    * Returns true if this map contains the given value.
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 85e76ba..30057f1 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -158,7 +158,7 @@
        this.host: "",
        port: 0,
        String path,
-       List<String> pathSegments,
+       Iterable<String> pathSegments,
        String query,
        Map<String, String> queryParameters,
        fragment: ""}) :
@@ -501,7 +501,7 @@
     return allLowercase ? scheme : scheme.toLowerCase();
   }
 
-  String _makePath(String path, List<String> pathSegments) {
+  String _makePath(String path, Iterable<String> pathSegments) {
     if (path == null && pathSegments == null) return "";
     if (path != null && pathSegments != null) {
       throw new ArgumentError('Both path and pathSegments specified');
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index b527e44..919675d 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -898,49 +898,9 @@
   CanvasRenderingContext _getContext_2(contextId) native;
 
   @JSName('toDataURL')
-  /**
-   * Returns a data URI containing a representation of the image in the
-   * format specified by type (defaults to 'image/png').
-   *
-   * Data Uri format is as follow `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
-   *
-   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when requesting [type]
-   * 'image/jpeg' or 'image/webp'. If [quality] is not passed the default
-   * value is used. Note: the default value varies by browser.
-   *
-   * If the height or width of this canvas element is 0, then 'data:' is returned,
-   * representing no data.
-   *
-   * If the type requested is not 'image/png', and the returned value is
-   * 'data:image/png', then the requested type is not supported.
-   *
-   * Example usage:
-   *
-   *     CanvasElement canvas = new CanvasElement();
-   *     var ctx = canvas.context2D
-   *     ..fillStyle = "rgb(200,0,0)"
-   *     ..fillRect(10, 10, 55, 50);
-   *     var dataUrl = canvas.toDataUrl("image/jpeg", 0.95);
-   *     // The Data Uri would look similar to
-   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
-   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
-   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
-   *     //Create a new image element from the data URI.
-   *     var img = new ImageElement();
-   *     img.src = dataUrl;
-   *     document.body.children.add(img);
-   *
-   * See also:
-   *
-   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
-   *
-   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
-   *
-   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
-   */
   @DomName('HTMLCanvasElement.toDataURL')
   @DocsEditable()
-  String $dom_toDataUrl(String type, [num quality]) native;
+  String _toDataUrl(String type, [num quality]) native;
 
   @DomName('HTMLCanvasElement.onwebglcontextlost')
   @DocsEditable()
@@ -978,8 +938,49 @@
     return context;
   }
 
-  String toDataUrl([String type = 'image/png', num quality]) => 
-      $dom_toDataUrl(type, quality);
+  /**
+   * Returns a data URI containing a representation of the image in the
+   * format specified by type (defaults to 'image/png').
+   *
+   * Data Uri format is as follow
+   * `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
+   *
+   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when
+   * requesting [type] 'image/jpeg' or 'image/webp'. If [quality] is not passed
+   * the default value is used. Note: the default value varies by browser.
+   *
+   * If the height or width of this canvas element is 0, then 'data:' is
+   * returned, representing no data.
+   *
+   * If the type requested is not 'image/png', and the returned value is
+   * 'data:image/png', then the requested type is not supported.
+   *
+   * Example usage:
+   *
+   *     CanvasElement canvas = new CanvasElement();
+   *     var ctx = canvas.context2D
+   *     ..fillStyle = "rgb(200,0,0)"
+   *     ..fillRect(10, 10, 55, 50);
+   *     var dataUrl = canvas.toDataUrl("image/jpeg", 0.95);
+   *     // The Data Uri would look similar to
+   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
+   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
+   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
+   *     //Create a new image element from the data URI.
+   *     var img = new ImageElement();
+   *     img.src = dataUrl;
+   *     document.body.children.add(img);
+   *
+   * See also:
+   *
+   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
+   *
+   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
+   *
+   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
+   */
+  String toDataUrl([String type = 'image/png', num quality]) =>
+      _toDataUrl(type, quality);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -1184,7 +1185,7 @@
   @JSName('arc')
   @DomName('CanvasRenderingContext2D.arc')
   @DocsEditable()
-  void $dom_arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native;
+  void _arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native;
 
   @DomName('CanvasRenderingContext2D.arcTo')
   @DocsEditable()
@@ -1483,7 +1484,7 @@
   @DomName('CanvasRenderingContext2D.arc')
   void arc(num x,  num y,  num radius,  num startAngle, num endAngle,
       [bool anticlockwise = false]) {
-    $dom_arc(x, y, radius, startAngle, endAngle, anticlockwise);
+    _arc(x, y, radius, startAngle, endAngle, anticlockwise);
   }
 
   /**
@@ -1807,8 +1808,8 @@
     if (view == null) {
       view = window;
     }
-    var e = document.$dom_createEvent("CompositionEvent");
-    e.$dom_initCompositionEvent(type, canBubble, cancelable, view, data);
+    var e = document._createEvent("CompositionEvent");
+    e._initCompositionEvent(type, canBubble, cancelable, view, data);
     return e;
   }
   // To suppress missing implicit constructor warnings.
@@ -1821,7 +1822,7 @@
   @JSName('initCompositionEvent')
   @DomName('CompositionEvent.initCompositionEvent')
   @DocsEditable()
-  void $dom_initCompositionEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window 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
@@ -6276,10 +6277,10 @@
   factory CustomEvent(String type,
       {bool canBubble: true, bool cancelable: true, Object detail}) {
 
-    final CustomEvent e = document.$dom_createEvent('CustomEvent');
+    final CustomEvent e = document._createEvent('CustomEvent');
 
     detail = convertDartToNative_SerializedScriptValue(detail);
-    e.$dom_initCustomEvent(type, canBubble, cancelable, detail);
+    e._initCustomEvent(type, canBubble, cancelable, detail);
 
     return e;
   }
@@ -6296,7 +6297,7 @@
   @JSName('initCustomEvent')
   @DomName('CustomEvent.initCustomEvent')
   @DocsEditable()
-  void $dom_initCustomEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object detailArg) native;
+  void _initCustomEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object detailArg) native;
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6614,8 +6615,8 @@
   factory DeviceOrientationEvent(String type,
       {bool canBubble: true, bool cancelable: true, num alpha: 0, num beta: 0,
       num gamma: 0, bool absolute: false}) {
-    var e = document.$dom_createEvent("DeviceOrientationEvent");
-    e.$dom_initDeviceOrientationEvent(type, canBubble, cancelable, alpha, beta,
+    var e = document._createEvent("DeviceOrientationEvent");
+    e._initDeviceOrientationEvent(type, canBubble, cancelable, alpha, beta,
         gamma, absolute);
     return e;
   }
@@ -6641,7 +6642,7 @@
   @JSName('initDeviceOrientationEvent')
   @DomName('DeviceOrientationEvent.initDeviceOrientationEvent')
   @DocsEditable()
-  void $dom_initDeviceOrientationEvent(String type, bool bubbles, bool cancelable, num alpha, num beta, num gamma, bool absolute) native;
+  void _initDeviceOrientationEvent(String type, bool bubbles, bool cancelable, num alpha, num beta, num gamma, bool absolute) native;
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6984,10 +6985,9 @@
   static const EventStreamProvider<Event> pointerLockErrorEvent = const EventStreamProvider<Event>('webkitpointerlockerror');
 
   @JSName('body')
-  /// Moved to [HtmlDocument].
   @DomName('Document.body')
   @DocsEditable()
-  HtmlElement $dom_body;
+  HtmlElement _body;
 
   @DomName('Document.charset')
   @DocsEditable()
@@ -7029,35 +7029,32 @@
   final FontLoader fontloader;
 
   @JSName('head')
-  /// Moved to [HtmlDocument].
   @DomName('Document.head')
   @DocsEditable()
-  final HeadElement $dom_head;
+  final HeadElement _head;
 
   @DomName('Document.implementation')
   @DocsEditable()
   final DomImplementation implementation;
 
   @JSName('lastModified')
-  /// Moved to [HtmlDocument].
   @DomName('Document.lastModified')
   @DocsEditable()
-  final String $dom_lastModified;
+  final String _lastModified;
 
   @JSName('preferredStylesheetSet')
   @DomName('Document.preferredStylesheetSet')
   @DocsEditable()
-  final String $dom_preferredStylesheetSet;
+  final String _preferredStylesheetSet;
 
   @DomName('Document.readyState')
   @DocsEditable()
   final String readyState;
 
   @JSName('referrer')
-  /// Moved to [HtmlDocument].
   @DomName('Document.referrer')
   @DocsEditable()
-  final String $dom_referrer;
+  final String _referrer;
 
   @DomName('Document.securityPolicy')
   @DocsEditable()
@@ -7068,54 +7065,48 @@
   @JSName('selectedStylesheetSet')
   @DomName('Document.selectedStylesheetSet')
   @DocsEditable()
-  String $dom_selectedStylesheetSet;
+  String _selectedStylesheetSet;
 
   @JSName('styleSheets')
-  /// Moved to [HtmlDocument]
   @DomName('Document.styleSheets')
   @DocsEditable()
   @Returns('_StyleSheetList')
   @Creates('_StyleSheetList')
-  final List<StyleSheet> $dom_styleSheets;
+  final List<StyleSheet> _styleSheets;
 
   @JSName('title')
-  /// Moved to [HtmlDocument].
   @DomName('Document.title')
   @DocsEditable()
-  String $dom_title;
+  String _title;
 
   @JSName('webkitFullscreenElement')
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitFullscreenElement')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-fullscreenelement
-  final Element $dom_webkitFullscreenElement;
+  final Element _webkitFullscreenElement;
 
   @JSName('webkitFullscreenEnabled')
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitFullscreenEnabled')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-fullscreenenabled
-  final bool $dom_webkitFullscreenEnabled;
+  final bool _webkitFullscreenEnabled;
 
   @JSName('webkitHidden')
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitHidden')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#document
-  final bool $dom_webkitHidden;
+  final bool _webkitHidden;
 
   @JSName('webkitIsFullScreen')
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitIsFullScreen')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -7123,17 +7114,16 @@
   @Experimental()
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
   @deprecated // deprecated
-  final bool $dom_webkitIsFullScreen;
+  final bool _webkitIsFullScreen;
 
   @JSName('webkitPointerLockElement')
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitPointerLockElement')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-pointerLockElement
-  final Element $dom_webkitPointerLockElement;
+  final Element _webkitPointerLockElement;
 
   @JSName('webkitVisibilityState')
   @DomName('Document.webkitVisibilityState')
@@ -7142,19 +7132,18 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#dom-document-visibilitystate
-  final String $dom_webkitVisibilityState;
+  final String _webkitVisibilityState;
 
   @DomName('Document.adoptNode')
   @DocsEditable()
   Node adoptNode(Node source) native;
 
   @JSName('caretRangeFromPoint')
-  /// Use the [Range] constructor instead.
   @DomName('Document.caretRangeFromPoint')
   @DocsEditable()
   // http://www.w3.org/TR/2009/WD-cssom-view-20090804/#dom-documentview-caretrangefrompoint
   @Experimental()
-  Range $dom_caretRangeFromPoint(int x, int y) native;
+  Range _caretRangeFromPoint(int x, int y) native;
 
   @JSName('createCDATASection')
   @DomName('Document.createCDATASection')
@@ -7181,13 +7170,13 @@
   @JSName('createEvent')
   @DomName('Document.createEvent')
   @DocsEditable()
-  Event $dom_createEvent(String eventType) native;
+  Event _createEvent(String eventType) native;
 
   @JSName('createNodeIterator')
   @DomName('Document.createNodeIterator')
   @DocsEditable()
   @Unstable()
-  NodeIterator $dom_createNodeIterator(Node root, [int whatToShow, NodeFilter filter, bool expandEntityReferences]) native;
+  NodeIterator _createNodeIterator(Node root, [int whatToShow, NodeFilter filter, bool expandEntityReferences]) native;
 
   @JSName('createRange')
   @DomName('Document.createRange')
@@ -7197,52 +7186,50 @@
   @JSName('createTextNode')
   @DomName('Document.createTextNode')
   @DocsEditable()
-  Text $dom_createTextNode(String data) native;
+  Text _createTextNode(String data) native;
 
   @DomName('Document.createTouch')
   @DocsEditable()
   // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
   @Experimental()
-  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) {
+  Touch _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);
+    return _createTouch_1(window, target_1, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce);
   }
   @JSName('createTouch')
   @DomName('Document.createTouch')
   @DocsEditable()
   // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
   @Experimental()
-  Touch _$dom_createTouch_1(Window window, target, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce) native;
+  Touch _createTouch_1(Window window, target, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce) native;
 
   @JSName('createTouchList')
-  /// Use the [TouchList] constructor instead.
   @DomName('Document.createTouchList')
   @DocsEditable()
   // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
   @Experimental()
-  TouchList $dom_createTouchList() native;
+  TouchList _createTouchList() native;
 
   @JSName('createTreeWalker')
   @DomName('Document.createTreeWalker')
   @DocsEditable()
-  TreeWalker $dom_createTreeWalker(Node root, [int whatToShow, NodeFilter filter, bool expandEntityReferences]) native;
+  TreeWalker _createTreeWalker(Node root, [int whatToShow, NodeFilter filter, bool expandEntityReferences]) native;
 
   @JSName('elementFromPoint')
   @DomName('Document.elementFromPoint')
   @DocsEditable()
-  Element $dom_elementFromPoint(int x, int y) native;
+  Element _elementFromPoint(int x, int y) native;
 
   @DomName('Document.execCommand')
   @DocsEditable()
   bool execCommand(String command, bool userInterface, String value) native;
 
   @JSName('getCSSCanvasContext')
-  /// Moved to [HtmlDocument].
   @DomName('Document.getCSSCanvasContext')
   @DocsEditable()
   // https://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariCSSRef/Articles/Functions.html
   @Experimental() // non-standard
-  CanvasRenderingContext $dom_getCssCanvasContext(String contextId, String name, int width, int height) native;
+  CanvasRenderingContext _getCssCanvasContext(String contextId, String name, int width, int height) native;
 
   @DomName('Document.getElementById')
   @DocsEditable()
@@ -7311,15 +7298,13 @@
   Element query(String selectors) native;
 
   @JSName('querySelectorAll')
-  /// Deprecated: use query("#$elementId") instead.
   @DomName('Document.querySelectorAll')
   @DocsEditable()
   @Returns('NodeList')
   @Creates('NodeList')
-  List<Node> $dom_querySelectorAll(String selectors) native;
+  List<Node> _querySelectorAll(String selectors) native;
 
   @JSName('webkitCancelFullScreen')
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitCancelFullScreen')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -7327,27 +7312,25 @@
   @Experimental()
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
   @deprecated // deprecated
-  void $dom_webkitCancelFullScreen() native;
+  void _webkitCancelFullScreen() native;
 
   @JSName('webkitExitFullscreen')
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitExitFullscreen')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-exitfullscreen
-  void $dom_webkitExitFullscreen() native;
+  void _webkitExitFullscreen() native;
 
   @JSName('webkitExitPointerLock')
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitExitPointerLock')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-exitPointerLock-void
-  void $dom_webkitExitPointerLock() native;
+  void _webkitExitPointerLock() native;
 
   @JSName('webkitGetNamedFlows')
   @DomName('Document.webkitGetNamedFlows')
@@ -7363,22 +7346,22 @@
   @JSName('childElementCount')
   @DomName('Document.childElementCount')
   @DocsEditable()
-  final int $dom_childElementCount;
+  final int _childElementCount;
 
   @JSName('children')
   @DomName('Document.children')
   @DocsEditable()
-  final HtmlCollection $dom_children;
+  final HtmlCollection _children;
 
   @JSName('firstElementChild')
   @DomName('Document.firstElementChild')
   @DocsEditable()
-  final Element $dom_firstElementChild;
+  final Element _firstElementChild;
 
   @JSName('lastElementChild')
   @DomName('Document.lastElementChild')
   @DocsEditable()
-  final Element $dom_lastElementChild;
+  final Element _lastElementChild;
 
   @DomName('Document.onabort')
   @DocsEditable()
@@ -7626,7 +7609,7 @@
    * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
    */
   ElementList queryAll(String selectors) {
-    return new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
+    return new _FrozenElementList._wrap(_querySelectorAll(selectors));
   }
 
   /// Checks if [register] is supported on the current platform.
@@ -7643,21 +7626,18 @@
 class DocumentFragment extends Node implements ParentNode native "DocumentFragment" {
   factory DocumentFragment() => document.createDocumentFragment();
 
-  factory DocumentFragment.html(String html) {
-    final fragment = new DocumentFragment();
-    fragment.innerHtml = html;
-    return fragment;
+  factory DocumentFragment.html(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+
+    return document.body.createFragment(html,
+      validator: validator, treeSanitizer: treeSanitizer);
   }
 
-  factory DocumentFragment.svg(String svgContent) {
-    final fragment = new DocumentFragment();
-    final e = new svg.SvgSvgElement();
-    e.innerHtml = svgContent;
+  factory DocumentFragment.svg(String svgContent,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
 
-    // Copy list first since we don't want liveness during iteration.
-    final List nodes = new List.from(e.nodes);
-    fragment.nodes.addAll(nodes);
-    return fragment;
+    return new svg.SvgSvgElement().createFragment(svgContent,
+        validator: validator, treeSanitizer: treeSanitizer);
   }
 
   // Native field is used only by Dart code so does not lead to instantiation
@@ -7680,10 +7660,10 @@
     children.addAll(copy);
   }
 
-  Element query(String selectors) => $dom_querySelector(selectors);
+  Element query(String selectors) => _querySelector(selectors);
 
   List<Element> queryAll(String selectors) =>
-    new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
+    new _FrozenElementList._wrap(_querySelectorAll(selectors));
 
   String get innerHtml {
     final e = new Element.tag("div");
@@ -7691,17 +7671,16 @@
     return e.innerHtml;
   }
 
-  // TODO(nweiz): Do we want to support some variant of innerHtml for XML and/or
-  // SVG strings?
   void set innerHtml(String value) {
+    this.setInnerHtml(value);
+  }
+
+  void setInnerHtml(String html,
+    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+
     this.nodes.clear();
-
-    final e = new Element.tag("div");
-    e.innerHtml = value;
-
-    // Copy list first since we don't want liveness during iteration.
-    List nodes = new List.from(e.nodes, growable: false);
-    this.nodes.addAll(nodes);
+    append(document.body.createFragment(
+        html, validator: validator, treeSanitizer: treeSanitizer));
   }
 
   /**
@@ -7727,31 +7706,31 @@
   @JSName('querySelector')
   @DomName('DocumentFragment.querySelector')
   @DocsEditable()
-  Element $dom_querySelector(String selectors) native;
+  Element _querySelector(String selectors) native;
 
   @JSName('querySelectorAll')
   @DomName('DocumentFragment.querySelectorAll')
   @DocsEditable()
   @Returns('NodeList')
   @Creates('NodeList')
-  List<Node> $dom_querySelectorAll(String selectors) native;
+  List<Node> _querySelectorAll(String selectors) native;
 
   // From ParentNode
 
   @JSName('childElementCount')
   @DomName('DocumentFragment.childElementCount')
   @DocsEditable()
-  final int $dom_childElementCount;
+  final int _childElementCount;
 
   @JSName('firstElementChild')
   @DomName('DocumentFragment.firstElementChild')
   @DocsEditable()
-  final Element $dom_firstElementChild;
+  final Element _firstElementChild;
 
   @JSName('lastElementChild')
   @DomName('DocumentFragment.lastElementChild')
   @DocsEditable()
-  final Element $dom_lastElementChild;
+  final Element _lastElementChild;
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -8029,14 +8008,14 @@
   final HtmlCollection _childElements;
 
   _ChildrenElementList._wrap(Element element)
-    : _childElements = element.$dom_children,
+    : _childElements = element._children,
       _element = element;
 
   bool contains(Object element) => _childElements.contains(element);
 
 
   bool get isEmpty {
-    return _element.$dom_firstElementChild == null;
+    return _element._firstElementChild == null;
   }
 
   int get length {
@@ -8048,7 +8027,7 @@
   }
 
   void operator []=(int index, Element value) {
-    _element.$dom_replaceChild(value, _childElements[index]);
+    _element._replaceChild(value, _childElements[index]);
   }
 
   void set length(int newLength) {
@@ -8112,7 +8091,7 @@
     if (object is Element) {
       Element element = object;
       if (identical(element.parentNode, _element)) {
-        _element.$dom_removeChild(element);
+        _element._removeChild(element);
         return true;
       }
     }
@@ -8142,7 +8121,7 @@
   Element removeAt(int index) {
     final result = this[index];
     if (result != null) {
-      _element.$dom_removeChild(result);
+      _element._removeChild(result);
     }
     return result;
   }
@@ -8150,20 +8129,20 @@
   Element removeLast() {
     final result = this.last;
     if (result != null) {
-      _element.$dom_removeChild(result);
+      _element._removeChild(result);
     }
     return result;
   }
 
   Element get first {
-    Element result = _element.$dom_firstElementChild;
+    Element result = _element._firstElementChild;
     if (result == null) throw new StateError("No elements");
     return result;
   }
 
 
   Element get last {
-    Element result = _element.$dom_lastElementChild;
+    Element result = _element._lastElementChild;
     if (result == null) throw new StateError("No elements");
     return result;
   }
@@ -8783,20 +8762,31 @@
   /**
    * Creates an HTML element from a valid fragment of HTML.
    *
-   * The [html] fragment must represent valid HTML with a single element root,
-   * which will be parsed and returned.
-   *
-   * Important: the contents of [html] should not contain any user-supplied
-   * data. Without strict data validation it is impossible to prevent script
-   * injection exploits.
-   *
-   * It is instead recommended that elements be constructed via [Element.tag]
-   * and text be added via [text].
-   *
    *     var element = new Element.html('<div class="foo">content</div>');
+   *
+   * The HTML fragment should contain only one single root element, any
+   * leading or trailing text nodes will be removed.
+   *
+   * The HTML fragment is parsed as if it occurred within the context of a
+   * `<body>` tag, this means that special elements such as `<caption>` which
+   * must be parsed within the scope of a `<table>` element will be dropped. Use
+   * [createFragment] to parse contextual HTML fragments.
+   *
+   * Unless a validator is provided this will perform the default validation
+   * and remove all scriptable elements and attributes.
+   *
+   * See also:
+   *
+   * * [NodeValidator]
+   *
    */
-  factory Element.html(String html) =>
-      _ElementFactoryProvider.createElement_html(html);
+  factory Element.html(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    var fragment = document.body.createFragment(html, validator: validator,
+        treeSanitizer: treeSanitizer);
+
+    return fragment.nodes.where((e) => e is Element).single;
+  }
 
   /**
    * Creates the HTML element specified by the tag name.
@@ -9016,7 +9006,7 @@
    *     var items = element.query('.itemClassName');
    */
   ElementList queryAll(String selectors) =>
-    new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
+    new _FrozenElementList._wrap(_querySelectorAll(selectors));
 
   /**
    * The set of CSS classes applied to this element.
@@ -9101,7 +9091,7 @@
       pseudoElement = '';
     }
     // TODO(jacobr): last param should be null, see b/5045788
-    return window.$dom_getComputedStyle(this, pseudoElement);
+    return window._getComputedStyle(this, pseudoElement);
   }
 
   /**
@@ -9143,7 +9133,7 @@
    * Called by the DOM when this element has been instantiated.
    */
   @Experimental()
-  void onCreated() {}
+  void created() {}
 
   // Hooks to support custom WebComponents.
 
@@ -9172,11 +9162,11 @@
 
   @DomName('Element.localName')
   @DocsEditable()
-  String get localName => $dom_localName;
+  String get localName => _localName;
 
   @DomName('Element.namespaceUri')
   @DocsEditable()
-  String get namespaceUri => $dom_namespaceUri;
+  String get namespaceUri => _namespaceUri;
 
   String toString() => localName;
 
@@ -9202,17 +9192,17 @@
     hasScrollIntoViewIfNeeded =
         JS('bool', '!!(#.scrollIntoViewIfNeeded)', this);
     if (alignment == ScrollAlignment.TOP) {
-      this.$dom_scrollIntoView(true);
+      this._scrollIntoView(true);
     } else if (alignment == ScrollAlignment.BOTTOM) {
-      this.$dom_scrollIntoView(false);
+      this._scrollIntoView(false);
     } else if (hasScrollIntoViewIfNeeded) {
       if (alignment == ScrollAlignment.CENTER) {
-        this.$dom_scrollIntoViewIfNeeded(true);
+        this._scrollIntoViewIfNeeded(true);
       } else {
-        this.$dom_scrollIntoViewIfNeeded();
+        this._scrollIntoViewIfNeeded();
       }
     } else {
-      this.$dom_scrollIntoView();
+      this._scrollIntoView();
     }
   }
 
@@ -9632,15 +9622,127 @@
     return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
   }
 
-  @JSName('innerHTML')
-  @DomName('HTMLElement.innerHTML')
-  String get innerHtml => JS('String', '#.innerHTML', this);
+  static HtmlDocument _parseDocument;
+  static NodeValidatorBuilder _defaultValidator;
+  static _ValidatingTreeSanitizer _defaultSanitizer;
 
-  void set innerHtml(String value) {
-    JS('', '#.innerHTML = #', this, value);
-    // Polyfill relies on mutation observers for upgrading, but we want it
-    // immediate.
-    Platform.upgradeCustomElements(this);
+  /**
+   * Create a DocumentFragment from the HTML fragment and ensure that it follows
+   * the sanitization rules specified by the validator or treeSanitizer.
+   *
+   * If the default validation behavior is too restrictive then a new
+   * NodeValidator should be created, either extending or wrapping a default
+   * validator and overriding the validation APIs.
+   *
+   * The treeSanitizer is used to walk the generated node tree and sanitize it.
+   * A custom treeSanitizer can also be provided to perform special validation
+   * rules but since the API is more complex to implement this is discouraged.
+   *
+   * The returned tree is guaranteed to only contain nodes and attributes which
+   * are allowed by the provided validator.
+   *
+   * See also:
+   *
+   * * [NodeValidator]
+   * * [NodeTreeSanitizer]
+   */
+  DocumentFragment createFragment(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    if (treeSanitizer == null) {
+      if (validator == null) {
+        if (_defaultValidator == null) {
+          _defaultValidator = new NodeValidatorBuilder.common();
+        }
+        validator = _defaultValidator;
+      }
+      if (_defaultSanitizer == null) {
+        _defaultSanitizer = new _ValidatingTreeSanitizer(validator);
+      } else {
+        _defaultSanitizer.validator = validator;
+      }
+      treeSanitizer = _defaultSanitizer;
+    } else if (validator != null) {
+      throw new ArgumentError(
+          'validator can only be passed if treeSanitizer is null');
+    }
+
+    if (_parseDocument == null) {
+      _parseDocument = document.implementation.createHtmlDocument('');
+    }
+    var contextElement;
+    if (this is BodyElement) {
+      contextElement = _parseDocument.body;
+    } else {
+      contextElement = _parseDocument.$dom_createElement(tagName);
+      _parseDocument.body.append(contextElement);
+    }
+    var fragment;
+    if (Range.supportsCreateContextualFragment) {
+      var range = _parseDocument.$dom_createRange();
+      range.selectNodeContents(contextElement);
+      fragment = range.createContextualFragment(html);
+    } else {
+      contextElement._innerHtml = html;
+
+      fragment = _parseDocument.createDocumentFragment();
+      while (contextElement.firstChild != null) {
+        fragment.append(contextElement.firstChild);
+      }
+    }
+    if (contextElement != _parseDocument.body) {
+      contextElement.remove();
+    }
+
+    treeSanitizer.sanitizeTree(fragment);
+    return fragment;
+  }
+
+  /**
+   * Parses the HTML fragment and sets it as the contents of this element.
+   *
+   * This uses the default sanitization behavior to sanitize the HTML fragment,
+   * use [setInnerHtml] to override the default behavior.
+   */
+  void set innerHtml(String html) {
+    this.setInnerHtml(html);
+  }
+
+  /**
+   * Parses the HTML fragment and sets it as the contents of this element.
+   * This ensures that the generated content follows the sanitization rules
+   * specified by the validator or treeSanitizer.
+   *
+   * If the default validation behavior is too restrictive then a new
+   * NodeValidator should be created, either extending or wrapping a default
+   * validator and overriding the validation APIs.
+   *
+   * The treeSanitizer is used to walk the generated node tree and sanitize it.
+   * A custom treeSanitizer can also be provided to perform special validation
+   * rules but since the API is more complex to implement this is discouraged.
+   *
+   * The resulting tree is guaranteed to only contain nodes and attributes which
+   * are allowed by the provided validator.
+   *
+   * See also:
+   *
+   * * [NodeValidator]
+   * * [NodeTreeSanitizer]
+   */
+  void setInnerHtml(String html,
+    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    text = null;
+    append(createFragment(
+        html, validator: validator, treeSanitizer: treeSanitizer));
+  }
+  String get innerHtml => _innerHtml;
+
+  /**
+   * For use while transitioning to the safe [innerHtml] or [setInnerHtml].
+   * Unsafe because it opens the app to cross-site scripting vulnerabilities.
+   */
+  @deprecated
+  void set unsafeInnerHtml(String html) {
+    _innerHtml = html;
   }
 
   // To suppress missing implicit constructor warnings.
@@ -9879,6 +9981,11 @@
   @DocsEditable()
   bool hidden;
 
+  @JSName('innerHTML')
+  @DomName('Element.innerHTML')
+  @DocsEditable()
+  String _innerHtml;
+
   @DomName('Element.inputMethodContext')
   @DocsEditable()
   @Experimental() // untriaged
@@ -9939,7 +10046,7 @@
   @JSName('attributes')
   @DomName('Element.attributes')
   @DocsEditable()
-  final _NamedNodeMap $dom_attributes;
+  final _NamedNodeMap _attributes;
 
   @DomName('Element.className')
   @DocsEditable()
@@ -10075,17 +10182,17 @@
   @DocsEditable()
   @Returns('NodeList')
   @Creates('NodeList')
-  List<Node> $dom_getElementsByTagName(String name) native;
+  List<Node> _getElementsByTagName(String name) native;
 
   @JSName('hasAttribute')
   @DomName('Element.hasAttribute')
   @DocsEditable()
-  bool $dom_hasAttribute(String name) native;
+  bool _hasAttribute(String name) native;
 
   @JSName('hasAttributeNS')
   @DomName('Element.hasAttributeNS')
   @DocsEditable()
-  bool $dom_hasAttributeNS(String namespaceURI, String localName) native;
+  bool _hasAttributeNS(String namespaceURI, String localName) native;
 
   @JSName('querySelector')
   /**
@@ -10114,17 +10221,17 @@
   @DocsEditable()
   @Returns('NodeList')
   @Creates('NodeList')
-  List<Node> $dom_querySelectorAll(String selectors) native;
+  List<Node> _querySelectorAll(String selectors) native;
 
   @JSName('removeAttribute')
   @DomName('Element.removeAttribute')
   @DocsEditable()
-  void $dom_removeAttribute(String name) native;
+  void _removeAttribute(String name) native;
 
   @JSName('removeAttributeNS')
   @DomName('Element.removeAttributeNS')
   @DocsEditable()
-  void $dom_removeAttributeNS(String namespaceURI, String localName) native;
+  void _removeAttributeNS(String namespaceURI, String localName) native;
 
   @DomName('Element.scrollByLines')
   @DocsEditable()
@@ -10137,14 +10244,14 @@
   @JSName('scrollIntoView')
   @DomName('Element.scrollIntoView')
   @DocsEditable()
-  void $dom_scrollIntoView([bool alignWithTop]) native;
+  void _scrollIntoView([bool alignWithTop]) native;
 
   @JSName('scrollIntoViewIfNeeded')
   @DomName('Element.scrollIntoViewIfNeeded')
   @DocsEditable()
   // http://docs.webplatform.org/wiki/dom/methods/scrollIntoViewIfNeeded
   @Experimental() // non-standard
-  void $dom_scrollIntoViewIfNeeded([bool centerIfNeeded]) native;
+  void _scrollIntoViewIfNeeded([bool centerIfNeeded]) native;
 
   @JSName('setAttribute')
   @DomName('Element.setAttribute')
@@ -10208,22 +10315,22 @@
   @JSName('childElementCount')
   @DomName('Element.childElementCount')
   @DocsEditable()
-  final int $dom_childElementCount;
+  final int _childElementCount;
 
   @JSName('children')
   @DomName('Element.children')
   @DocsEditable()
-  final HtmlCollection $dom_children;
+  final HtmlCollection _children;
 
   @JSName('firstElementChild')
   @DomName('Element.firstElementChild')
   @DocsEditable()
-  final Element $dom_firstElementChild;
+  final Element _firstElementChild;
 
   @JSName('lastElementChild')
   @DomName('Element.lastElementChild')
   @DocsEditable()
-  final Element $dom_lastElementChild;
+  final Element _lastElementChild;
 
   @DomName('Element.onabort')
   @DocsEditable()
@@ -10454,119 +10561,8 @@
 
 }
 
-final _START_TAG_REGEXP = new RegExp('<(\\w+)');
+
 class _ElementFactoryProvider {
-  static const _CUSTOM_PARENT_TAG_MAP = const {
-    'body' : 'html',
-    'head' : 'html',
-    'caption' : 'table',
-    'td': 'tr',
-    'th': 'tr',
-    'colgroup': 'table',
-    'col' : 'colgroup',
-    'tr' : 'tbody',
-    'tbody' : 'table',
-    'tfoot' : 'table',
-    'thead' : 'table',
-    'track' : 'audio',
-  };
-
-  @DomName('Document.createElement')
-  static Element createElement_html(String html) {
-    // TODO(jacobr): this method can be made more robust and performant.
-    // 1) Cache the dummy parent elements required to use innerHTML rather than
-    //    creating them every call.
-    // 2) Verify that the html does not contain leading or trailing text nodes.
-    // 3) Verify that the html does not contain both <head> and <body> tags.
-    // 4) Detatch the created element from its dummy parent.
-    String parentTag = 'div';
-    String tag;
-    final match = _START_TAG_REGEXP.firstMatch(html);
-    if (match != null) {
-      tag = match.group(1).toLowerCase();
-      if (Device.isIE && Element._TABLE_TAGS.containsKey(tag)) {
-        return _createTableForIE(html, tag);
-      }
-      parentTag = _CUSTOM_PARENT_TAG_MAP[tag];
-      if (parentTag == null) parentTag = 'div';
-    }
-
-    final temp = new Element.tag(parentTag);
-    temp.innerHtml = html;
-
-    Element element;
-    if (temp.children.length == 1) {
-      element = temp.children[0];
-    } else if (parentTag == 'html' && temp.children.length == 2) {
-      // In html5 the root <html> tag will always have a <body> and a <head>,
-      // even though the inner html only contains one of them.
-      element = temp.children[tag == 'head' ? 0 : 1];
-    } else {
-      _singleNode(temp.children);
-    }
-    element.remove();
-    return element;
-  }
-
-  /**
-   * IE table elements don't support innerHTML (even in standards mode).
-   * Instead we use a div and inject the table element in the innerHtml string.
-   * This technique works on other browsers too, but it's probably slower,
-   * so we only use it when running on IE.
-   *
-   * See also innerHTML:
-   * <http://msdn.microsoft.com/en-us/library/ie/ms533897(v=vs.85).aspx>
-   * and Building Tables Dynamically:
-   * <http://msdn.microsoft.com/en-us/library/ie/ms532998(v=vs.85).aspx>.
-   */
-  static Element _createTableForIE(String html, String tag) {
-    var div = new Element.tag('div');
-    div.innerHtml = '<table>$html</table>';
-    var table = _singleNode(div.children);
-    Element element;
-    switch (tag) {
-      case 'td':
-      case 'th':
-        TableRowElement row = _singleNode(table.rows);
-        element = _singleNode(row.cells);
-        break;
-      case 'tr':
-        element = _singleNode(table.rows);
-        break;
-      case 'tbody':
-        element = _singleNode(table.tBodies);
-        break;
-      case 'thead':
-        element = table.tHead;
-        break;
-      case 'tfoot':
-        element = table.tFoot;
-        break;
-      case 'caption':
-        element = table.caption;
-        break;
-      case 'colgroup':
-        element = _getColgroup(table);
-        break;
-      case 'col':
-        element = _singleNode(_getColgroup(table).children);
-        break;
-    }
-    element.remove();
-    return element;
-  }
-
-  static TableColElement _getColgroup(TableElement table) {
-    // TODO(jmesserly): is there a better way to do this?
-    return _singleNode(table.children.where((n) => n.tagName == 'COLGROUP')
-        .toList());
-  }
-
-  static Node _singleNode(List<Node> list) {
-    if (list.length == 1) return list[0];
-    throw new ArgumentError('HTML had ${list.length} '
-        'top level elements but 1 expected');
-  }
 
   @DomName('Document.createElement')
   // Optimization to improve performance until the dart2js compiler inlines this
@@ -10863,8 +10859,8 @@
    */
   factory Event.eventType(String type, String name, {bool canBubble: true,
       bool cancelable: true}) {
-    final Event e = document.$dom_createEvent(type);
-    e.$dom_initEvent(name, canBubble, cancelable);
+    final Event e = document._createEvent(type);
+    e._initEvent(name, canBubble, cancelable);
     return e;
   }
 
@@ -11048,7 +11044,7 @@
   @JSName('initEvent')
   @DomName('Event.initEvent')
   @DocsEditable()
-  void $dom_initEvent(String eventTypeArg, bool canBubbleArg, bool cancelableArg) native;
+  void _initEvent(String eventTypeArg, bool canBubbleArg, bool cancelableArg) native;
 
   @DomName('Event.preventDefault')
   @DocsEditable()
@@ -11216,6 +11212,7 @@
   @JSName('addEventListener')
   @DomName('EventTarget.addEventListener')
   @DocsEditable()
+  @deprecated
   void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
 
   @DomName('EventTarget.dispatchEvent')
@@ -11225,6 +11222,7 @@
   @JSName('removeEventListener')
   @DomName('EventTarget.removeEventListener')
   @DocsEditable()
+  @deprecated
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
 }
@@ -12064,7 +12062,7 @@
     }
     var completer = new Completer<Geoposition>();
     try {
-      $dom_getCurrentPosition(
+      _getCurrentPosition(
           (position) {
             completer.complete(_ensurePosition(position));
           },
@@ -12098,7 +12096,7 @@
     controller = new StreamController<Geoposition>(sync: true,
       onListen: () {
         assert(watchId == null);
-        watchId = $dom_watchPosition(
+        watchId = _watchPosition(
             (position) {
               controller.add(_ensurePosition(position));
             },
@@ -12109,7 +12107,7 @@
       },
       onCancel: () {
         assert(watchId != null);
-        $dom_clearWatch(watchId);
+        _clearWatch(watchId);
       });
 
     return controller.stream;
@@ -12129,17 +12127,17 @@
   @JSName('clearWatch')
   @DomName('Geolocation.clearWatch')
   @DocsEditable()
-  void $dom_clearWatch(int watchID) native;
+  void _clearWatch(int watchID) native;
 
   @JSName('getCurrentPosition')
   @DomName('Geolocation.getCurrentPosition')
   @DocsEditable()
-  void $dom_getCurrentPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Object options]) native;
+  void _getCurrentPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Object options]) native;
 
   @JSName('watchPosition')
   @DomName('Geolocation.watchPosition')
   @DocsEditable()
-  int $dom_watchPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Object options]) native;
+  int _watchPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Object options]) native;
 }
 
 /**
@@ -12207,8 +12205,8 @@
   factory HashChangeEvent(String type,
       {bool canBubble: true, bool cancelable: true, String oldUrl,
       String newUrl}) {
-    var event = document.$dom_createEvent("HashChangeEvent");
-    event.$dom_initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
+    var event = document._createEvent("HashChangeEvent");
+    event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
     return event;
   }
   // To suppress missing implicit constructor warnings.
@@ -12230,7 +12228,7 @@
   @JSName('initHashChangeEvent')
   @DomName('HashChangeEvent.initHashChangeEvent')
   @DocsEditable()
-  void $dom_initHashChangeEvent(String type, bool canBubble, bool cancelable, String oldURL, String newURL) native;
+  void _initHashChangeEvent(String type, bool canBubble, bool cancelable, String oldURL, String newURL) native;
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -12539,12 +12537,12 @@
 
   @DomName('Document.caretRangeFromPoint')
   Range caretRangeFromPoint(int x, int y) {
-    return $dom_caretRangeFromPoint(x, y);
+    return _caretRangeFromPoint(x, y);
   }
 
   @DomName('Document.elementFromPoint')
   Element elementFromPoint(int x, int y) {
-    return $dom_elementFromPoint(x, y);
+    return _elementFromPoint(x, y);
   }
 
   /**
@@ -12584,36 +12582,36 @@
   @DomName('Document.getCSSCanvasContext')
   CanvasRenderingContext getCssCanvasContext(String contextId, String name,
       int width, int height) {
-    return $dom_getCssCanvasContext(contextId, name, width, height);
+    return _getCssCanvasContext(contextId, name, width, height);
   }
 
   @DomName('Document.head')
-  HeadElement get head => $dom_head;
+  HeadElement get head => _head;
 
   @DomName('Document.lastModified')
-  String get lastModified => $dom_lastModified;
+  String get lastModified => _lastModified;
 
   @DomName('Document.preferredStylesheetSet')
-  String get preferredStylesheetSet => $dom_preferredStylesheetSet;
+  String get preferredStylesheetSet => _preferredStylesheetSet;
 
   @DomName('Document.referrer')
-  String get referrer => $dom_referrer;
+  String get referrer => _referrer;
 
   @DomName('Document.selectedStylesheetSet')
-  String get selectedStylesheetSet => $dom_selectedStylesheetSet;
+  String get selectedStylesheetSet => _selectedStylesheetSet;
   void set selectedStylesheetSet(String value) {
-    $dom_selectedStylesheetSet = value;
+    _selectedStylesheetSet = value;
   }
 
   @DomName('Document.styleSheets')
-  List<StyleSheet> get styleSheets => $dom_styleSheets;
+  List<StyleSheet> get styleSheets => _styleSheets;
 
   @DomName('Document.title')
-  String get title => $dom_title;
+  String get title => _title;
 
   @DomName('Document.title')
   void set title(String value) {
-    $dom_title = value;
+    _title = value;
   }
 
   @DomName('Document.webkitCancelFullScreen')
@@ -12621,7 +12619,7 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   void cancelFullScreen() {
-    $dom_webkitCancelFullScreen();
+    _webkitCancelFullScreen();
   }
 
   @DomName('Document.webkitExitFullscreen')
@@ -12629,7 +12627,7 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   void exitFullscreen() {
-    $dom_webkitExitFullscreen();
+    _webkitExitFullscreen();
   }
 
   @DomName('Document.webkitExitPointerLock')
@@ -12637,45 +12635,45 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   void exitPointerLock() {
-    $dom_webkitExitPointerLock();
+    _webkitExitPointerLock();
   }
 
   @DomName('Document.webkitFullscreenElement')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  Element get fullscreenElement => $dom_webkitFullscreenElement;
+  Element get fullscreenElement => _webkitFullscreenElement;
 
   @DomName('Document.webkitFullscreenEnabled')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  bool get fullscreenEnabled => $dom_webkitFullscreenEnabled;
+  bool get fullscreenEnabled => _webkitFullscreenEnabled;
 
   @DomName('Document.webkitHidden')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  bool get hidden => $dom_webkitHidden;
+  bool get hidden => _webkitHidden;
 
   @DomName('Document.webkitIsFullScreen')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  bool get isFullScreen => $dom_webkitIsFullScreen;
+  bool get isFullScreen => _webkitIsFullScreen;
 
   @DomName('Document.webkitPointerLockElement')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   Element get pointerLockElement =>
-      $dom_webkitPointerLockElement;
+      _webkitPointerLockElement;
 
   @DomName('Document.webkitVisibilityState')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  String get visibilityState => $dom_webkitVisibilityState;
+  String get visibilityState => _webkitVisibilityState;
 
   @Experimental
   void register(String tag, Type customElementClass) {
@@ -12934,6 +12932,43 @@
     return JS('bool', '("overrideMimeType" in #)', xhr);
   }
 
+  /**
+   * Makes a cross-origin request to the specified URL.
+   *
+   * This API provides a subset of [request] which works on IE9. If IE9
+   * cross-origin support is not required then [request] should be used instead.
+   */
+  @Experimental()
+  static Future<String> requestCrossOrigin(String url,
+      {String method, String sendData}) {
+    if (supportsCrossOrigin) {
+      return request(url, method: method, sendData: sendData).then((xhr) {
+        return xhr.responseText;
+      });
+    }
+    var completer = new Completer<String>();
+    if (method == null) {
+      method = 'GET';
+    }
+    var xhr = JS('var', 'new XDomainRequest()');
+    JS('', '#.open(#, #)', xhr, method, url);
+    JS('', '#.onload = #', xhr, convertDartClosureToJS((e) {
+      var response = JS('String', '#.responseText', xhr);
+      completer.complete(response);
+    }, 1));
+    JS('', '#.onerror = #', xhr, convertDartClosureToJS((e) {
+      completer.completeError(e);
+    }, 1));
+
+    if (sendData != null) {
+      JS('', '#.send(#)', xhr, sendData);
+    } else {
+      JS('', '#.send()', xhr);
+    }
+
+    return completer.future;
+  }
+
   // To suppress missing implicit constructor warnings.
   factory HttpRequest._() { throw new UnsupportedError("Not supported"); }
 
@@ -14479,22 +14514,32 @@
 @DomName('KeyboardEvent')
 class KeyboardEvent extends UIEvent native "KeyboardEvent" {
 
+  /** 
+   * Programmatically create a KeyboardEvent. 
+   *
+   * Due to browser differences, keyCode, charCode, or keyIdentifier values
+   * cannot be specified in this base level constructor. This constructor
+   * enables the user to programmatically create and dispatch a [KeyboardEvent],
+   * but it will not contain any particular key content. For programmatically
+   * creating keyboard events with specific key value contents, see the custom
+   * Event [KeyEvent]. 
+   */
   factory KeyboardEvent(String type,
       {Window view, bool canBubble: true, bool cancelable: true,
-      String keyIdentifier: "", int keyLocation: 1, bool ctrlKey: false,
+      int keyLocation: 1, bool ctrlKey: false,
       bool altKey: false, bool shiftKey: false, bool metaKey: false,
       bool altGraphKey: false}) {
     if (view == null) {
       view = window;
     }
-    final e = document.$dom_createEvent("KeyboardEvent");
-    e.$dom_initKeyboardEvent(type, canBubble, cancelable, view, keyIdentifier,
+    final e = document._createEvent("KeyboardEvent");
+    e._initKeyboardEvent(type, canBubble, cancelable, view, "",
         keyLocation, ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
     return e;
   }
 
   @DomName('KeyboardEvent.initKeyboardEvent')
-  void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
+  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
       Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
       bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) {
     if (JS('bool', 'typeof(#.initKeyEvent) == "function"', this)) {
@@ -14514,10 +14559,10 @@
   }
 
   @DomName('KeyboardEvent.keyCode')
-  int get keyCode => $dom_keyCode;
+  int get keyCode => _keyCode;
 
   @DomName('KeyboardEvent.charCode')
-  int get charCode => $dom_charCode;
+  int get charCode => _charCode;
   // To suppress missing implicit constructor warnings.
   factory KeyboardEvent._() { throw new UnsupportedError("Not supported"); }
 
@@ -14558,7 +14603,7 @@
   @DomName('KeyboardEvent.keyIdentifier')
   @DocsEditable()
   @Experimental() // nonstandard
-  final String $dom_keyIdentifier;
+  final String _keyIdentifier;
 
   @DomName('KeyboardEvent.keyLocation')
   @DocsEditable()
@@ -16152,8 +16197,8 @@
     if (source == null) {
       source = window;
     }
-    var event = document.$dom_createEvent("MessageEvent");
-    event.$dom_initMessageEvent(type, canBubble, cancelable, data, origin,
+    var event = document._createEvent("MessageEvent");
+    event._initMessageEvent(type, canBubble, cancelable, data, origin,
         lastEventId, source, messagePorts);
     return event;
   }
@@ -16194,7 +16239,7 @@
   @JSName('initMessageEvent')
   @DomName('MessageEvent.initMessageEvent')
   @DocsEditable()
-  void $dom_initMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, Window sourceArg, List messagePorts) native;
+  void _initMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, Window sourceArg, List messagePorts) native;
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -16660,8 +16705,8 @@
     if (view == null) {
       view = window;
     }
-    var event = document.$dom_createEvent('MouseEvent');
-    event.$dom_initMouseEvent(type, canBubble, cancelable, view, detail,
+    var event = document._createEvent('MouseEvent');
+    event._initMouseEvent(type, canBubble, cancelable, view, detail,
         screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
         button, relatedTarget);
     return event;
@@ -16680,12 +16725,12 @@
   @JSName('clientX')
   @DomName('MouseEvent.clientX')
   @DocsEditable()
-  final int $dom_clientX;
+  final int _clientX;
 
   @JSName('clientY')
   @DomName('MouseEvent.clientY')
   @DocsEditable()
-  final int $dom_clientY;
+  final int _clientY;
 
   @DomName('MouseEvent.ctrlKey')
   @DocsEditable()
@@ -16716,12 +16761,12 @@
   @JSName('screenX')
   @DomName('MouseEvent.screenX')
   @DocsEditable()
-  final int $dom_screenX;
+  final int _screenX;
 
   @JSName('screenY')
   @DomName('MouseEvent.screenY')
   @DocsEditable()
-  final int $dom_screenY;
+  final int _screenY;
 
   @DomName('MouseEvent.shiftKey')
   @DocsEditable()
@@ -16738,7 +16783,7 @@
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  final int $dom_webkitMovementX;
+  final int _webkitMovementX;
 
   @JSName('webkitMovementY')
   @DomName('MouseEvent.webkitMovementY')
@@ -16746,19 +16791,19 @@
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  final int $dom_webkitMovementY;
+  final int _webkitMovementY;
 
   @DomName('MouseEvent.initMouseEvent')
   @DocsEditable()
-  void $dom_initMouseEvent(String type, bool canBubble, bool cancelable, Window view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, int button, EventTarget relatedTarget) {
+  void _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);
+    _initMouseEvent_1(type, canBubble, cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget_1);
     return;
   }
   @JSName('initMouseEvent')
   @DomName('MouseEvent.initMouseEvent')
   @DocsEditable()
-  void _$dom_initMouseEvent_1(type, canBubble, cancelable, Window view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) native;
+  void _initMouseEvent_1(type, canBubble, cancelable, Window view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget) native;
 
 
   @deprecated
@@ -16780,14 +16825,14 @@
 
   @DomName('MouseEvent.clientX')
   @DomName('MouseEvent.clientY')
-  Point get client => new Point($dom_clientX, $dom_clientY);
+  Point get client => new Point(_clientX, _clientY);
 
   @DomName('MouseEvent.movementX')
   @DomName('MouseEvent.movementY')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  Point get movement => new Point($dom_webkitMovementX, $dom_webkitMovementY);
+  Point get movement => new Point(_webkitMovementX, _webkitMovementY);
 
   /**
    * The coordinates of the mouse pointer in target node coordinates.
@@ -16814,7 +16859,7 @@
 
   @DomName('MouseEvent.screenX')
   @DomName('MouseEvent.screenY')
-  Point get screen => new Point($dom_screenX, $dom_screenY);
+  Point get screen => new Point(_screenX, _screenY);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -16838,8 +16883,8 @@
       {bool canBubble: false, bool cancelable: false, Node relatedNode,
       String prevValue, String newValue, String attrName, int attrChange: 0}) {
 
-    var event = document.$dom_createEvent('MutationEvent');
-    event.$dom_initMutationEvent(type, canBubble, cancelable, relatedNode,
+    var event = document._createEvent('MutationEvent');
+    event._initMutationEvent(type, canBubble, cancelable, relatedNode,
         prevValue, newValue, attrName, attrChange);
     return event;
   }
@@ -16881,7 +16926,7 @@
   @JSName('initMutationEvent')
   @DomName('MutationEvent.initMutationEvent')
   @DocsEditable()
-  void $dom_initMutationEvent(String type, bool canBubble, bool cancelable, Node relatedNode, String prevValue, String newValue, String attrName, int attrChange) native;
+  void _initMutationEvent(String type, bool canBubble, bool cancelable, Node relatedNode, String prevValue, String newValue, String attrName, int attrChange) native;
 
 }
 
@@ -17449,7 +17494,7 @@
   Node removeLast() {
     final result = last;
     if (result != null) {
-      _this.$dom_removeChild(result);
+      _this._removeChild(result);
     }
     return result;
   }
@@ -17457,7 +17502,7 @@
   Node removeAt(int index) {
     var result = this[index];
     if (result != null) {
-      _this.$dom_removeChild(result);
+      _this._removeChild(result);
     }
     return result;
   }
@@ -17466,7 +17511,7 @@
     if (object is! Node) return false;
     Node node = object;
     if (!identical(_this, node.parentNode)) return false;
-    _this.$dom_removeChild(node);
+    _this._removeChild(node);
     return true;
   }
 
@@ -17478,7 +17523,7 @@
     while (child != null) {
       Node nextChild = child.nextNode;
       if (test(child) == removeMatching) {
-        _this.$dom_removeChild(child);
+        _this._removeChild(child);
       }
       child = nextChild;
     }
@@ -17497,7 +17542,7 @@
   }
 
   void operator []=(int index, Node value) {
-    _this.$dom_replaceChild(value, this[index]);
+    _this._replaceChild(value, this[index]);
   }
 
   Iterator<Node> get iterator => _this.$dom_childNodes.iterator;
@@ -17580,7 +17625,7 @@
     // TODO(vsm): Use the native remove when available.
     if (this.parentNode != null) {
       final Node parent = this.parentNode;
-      parentNode.$dom_removeChild(this);
+      parentNode._removeChild(this);
     }
   }
 
@@ -17591,7 +17636,7 @@
   Node replaceWith(Node otherNode) {
     try {
       final Node parent = this.parentNode;
-      parent.$dom_replaceChild(otherNode, this);
+      parent._replaceChild(otherNode, this);
     } catch (e) {
 
     };
@@ -17744,14 +17789,14 @@
   @DocsEditable()
   // http://dom.spec.whatwg.org/#dom-node-localname
   @deprecated // deprecated
-  final String $dom_localName;
+  final String _localName;
 
   @JSName('namespaceURI')
   @DomName('Node.namespaceURI')
   @DocsEditable()
   // http://dom.spec.whatwg.org/#dom-node-namespaceuri
   @deprecated // deprecated
-  final String $dom_namespaceUri;
+  final String _namespaceUri;
 
   @JSName('nextSibling')
   @DomName('Node.nextSibling')
@@ -17828,12 +17873,12 @@
   @JSName('removeChild')
   @DomName('Node.removeChild')
   @DocsEditable()
-  Node $dom_removeChild(Node oldChild) native;
+  Node _removeChild(Node oldChild) native;
 
   @JSName('replaceChild')
   @DomName('Node.replaceChild')
   @DocsEditable()
-  Node $dom_replaceChild(Node newChild, Node oldChild) native;
+  Node _replaceChild(Node newChild, Node oldChild) native;
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -17924,7 +17969,7 @@
 @Unstable()
 class NodeIterator extends Interceptor native "NodeIterator" {
   factory NodeIterator(Node root, int whatToShow) {
-    return document.$dom_createNodeIterator(root, whatToShow, null, false);
+    return document._createNodeIterator(root, whatToShow, null, false);
   }
 
   @DomName('NodeIterator.pointerBeforeReferenceNode')
@@ -18587,13 +18632,13 @@
 @Experimental() // untriaged
 abstract class ParentNode extends Interceptor {
 
-  int $dom_childElementCount;
+  int _childElementCount;
 
-  HtmlCollection $dom_children;
+  HtmlCollection _children;
 
-  Element $dom_firstElementChild;
+  Element _firstElementChild;
 
-  Element $dom_lastElementChild;
+  Element _lastElementChild;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -19420,7 +19465,7 @@
   factory Range() => document.$dom_createRange();
 
   factory Range.fromPoint(Point point) =>
-      document.$dom_caretRangeFromPoint(point.x, point.y);
+      document._caretRangeFromPoint(point.x, point.y);
 
   @DomName('Range.END_TO_END')
   @DocsEditable()
@@ -20334,30 +20379,30 @@
   @DomName('Screen.availLeft')
   @DomName('Screen.availTop')
   @DomName('Screen.availWidth')
-  Rect get available => new Rect($dom_availLeft, $dom_availTop, $dom_availWidth,
-      $dom_availHeight);
+  Rect get available => new Rect(_availLeft, _availTop, _availWidth,
+      _availHeight);
 
   @JSName('availHeight')
   @DomName('Screen.availHeight')
   @DocsEditable()
-  final int $dom_availHeight;
+  final int _availHeight;
 
   @JSName('availLeft')
   @DomName('Screen.availLeft')
   @DocsEditable()
   @Experimental() // nonstandard
-  final int $dom_availLeft;
+  final int _availLeft;
 
   @JSName('availTop')
   @DomName('Screen.availTop')
   @DocsEditable()
   @Experimental() // nonstandard
-  final int $dom_availTop;
+  final int _availTop;
 
   @JSName('availWidth')
   @DomName('Screen.availWidth')
   @DocsEditable()
-  final int $dom_availWidth;
+  final int _availWidth;
 
   @DomName('Screen.colorDepth')
   @DocsEditable()
@@ -21734,11 +21779,11 @@
   // TODO(nweiz): update this when maps support lazy iteration
   bool containsValue(String value) => values.any((e) => e == value);
 
-  bool containsKey(String key) => $dom_getItem(key) != null;
+  bool containsKey(String key) => _getItem(key) != null;
 
-  String operator [](String key) => $dom_getItem(key);
+  String operator [](String key) => _getItem(key);
 
-  void operator []=(String key, String value) { $dom_setItem(key, value); }
+  void operator []=(String key, String value) { _setItem(key, value); }
 
   String putIfAbsent(String key, String ifAbsent()) {
     if (!containsKey(key)) this[key] = ifAbsent();
@@ -21747,15 +21792,15 @@
 
   String remove(String key) {
     final value = this[key];
-    $dom_removeItem(key);
+    _removeItem(key);
     return value;
   }
 
-  void clear() => $dom_clear();
+  void clear() => _clear();
 
   void forEach(void f(String key, String value)) {
     for (var i = 0; true; i++) {
-      final key = $dom_key(i);
+      final key = _key(i);
       if (key == null) return;
 
       f(key, this[key]);
@@ -21774,16 +21819,16 @@
     return values;
   }
 
-  int get length => $dom_length;
+  int get length => _length;
 
-  bool get isEmpty => $dom_key(0) == null;
+  bool get isEmpty => _key(0) == null;
 
   bool get isNotEmpty => !isEmpty;
 
   @JSName('length')
   @DomName('Storage.length')
   @DocsEditable()
-  final int $dom_length;
+  final int _length;
 
   @DomName('Storage.__delete__')
   @DocsEditable()
@@ -21800,27 +21845,27 @@
   @JSName('clear')
   @DomName('Storage.clear')
   @DocsEditable()
-  void $dom_clear() native;
+  void _clear() native;
 
   @JSName('getItem')
   @DomName('Storage.getItem')
   @DocsEditable()
-  String $dom_getItem(String key) native;
+  String _getItem(String key) native;
 
   @JSName('key')
   @DomName('Storage.key')
   @DocsEditable()
-  String $dom_key(int index) native;
+  String _key(int index) native;
 
   @JSName('removeItem')
   @DomName('Storage.removeItem')
   @DocsEditable()
-  void $dom_removeItem(String key) native;
+  void _removeItem(String key) native;
 
   @JSName('setItem')
   @DomName('Storage.setItem')
   @DocsEditable()
-  void $dom_setItem(String key, String data) native;
+  void _setItem(String key, String data) native;
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -21848,8 +21893,8 @@
     {bool canBubble: false, bool cancelable: false, String key, String oldValue,
     String newValue, String url, Storage storageArea}) {
 
-    var e = document.$dom_createEvent("StorageEvent");
-    e.$dom_initStorageEvent(type, canBubble, cancelable, key, oldValue,
+    var e = document._createEvent("StorageEvent");
+    e._initStorageEvent(type, canBubble, cancelable, key, oldValue,
         newValue, url, storageArea);
     return e;
   }
@@ -21879,7 +21924,7 @@
   @JSName('initStorageEvent')
   @DomName('StorageEvent.initStorageEvent')
   @DocsEditable()
-  void $dom_initStorageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, String keyArg, String oldValueArg, String newValueArg, String urlArg, Storage storageAreaArg) native;
+  void _initStorageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, String keyArg, String oldValueArg, String newValueArg, String urlArg, Storage storageAreaArg) native;
 
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
@@ -22262,25 +22307,25 @@
 
   @DomName('HTMLTableElement.tBodies')
   List<TableSectionElement> get tBodies =>
-  new _WrappedList<TableSectionElement>($dom_tBodies);
+  new _WrappedList<TableSectionElement>(_tBodies);
 
   @DomName('HTMLTableElement.rows')
   List<TableRowElement> get rows =>
-      new _WrappedList<TableRowElement>($dom_rows);
+      new _WrappedList<TableRowElement>(_rows);
 
   TableRowElement addRow() {
     return insertRow(-1);
   }
 
-  TableCaptionElement createCaption() => $dom_createCaption();
-  TableSectionElement createTBody() => $dom_createTBody();
-  TableSectionElement createTFoot() => $dom_createTFoot();
-  TableSectionElement createTHead() => $dom_createTHead();
-  TableRowElement insertRow(int index) => $dom_insertRow(index);
+  TableCaptionElement createCaption() => _createCaption();
+  TableSectionElement createTBody() => _createTBody();
+  TableSectionElement createTFoot() => _createTFoot();
+  TableSectionElement createTHead() => _createTHead();
+  TableRowElement insertRow(int index) => _insertRow(index);
 
-  TableSectionElement $dom_createTBody() {
+  TableSectionElement _createTBody() {
     if (JS('bool', '!!#.createTBody', this)) {
-      return this._createTBody();
+      return this._nativeCreateTBody();
     }
     var tbody = new Element.tag('tbody');
     this.children.add(tbody);
@@ -22288,7 +22333,7 @@
   }
 
   @JSName('createTBody')
-  TableSectionElement _createTBody() native;
+  TableSectionElement _nativeCreateTBody() native;
 
   // To suppress missing implicit constructor warnings.
   factory TableElement._() { throw new UnsupportedError("Not supported"); }
@@ -22310,12 +22355,12 @@
   @JSName('rows')
   @DomName('HTMLTableElement.rows')
   @DocsEditable()
-  final HtmlCollection $dom_rows;
+  final HtmlCollection _rows;
 
   @JSName('tBodies')
   @DomName('HTMLTableElement.tBodies')
   @DocsEditable()
-  final HtmlCollection $dom_tBodies;
+  final HtmlCollection _tBodies;
 
   @DomName('HTMLTableElement.tFoot')
   @DocsEditable()
@@ -22328,17 +22373,17 @@
   @JSName('createCaption')
   @DomName('HTMLTableElement.createCaption')
   @DocsEditable()
-  HtmlElement $dom_createCaption() native;
+  HtmlElement _createCaption() native;
 
   @JSName('createTFoot')
   @DomName('HTMLTableElement.createTFoot')
   @DocsEditable()
-  HtmlElement $dom_createTFoot() native;
+  HtmlElement _createTFoot() native;
 
   @JSName('createTHead')
   @DomName('HTMLTableElement.createTHead')
   @DocsEditable()
-  HtmlElement $dom_createTHead() native;
+  HtmlElement _createTHead() native;
 
   @DomName('HTMLTableElement.deleteCaption')
   @DocsEditable()
@@ -22359,7 +22404,7 @@
   @JSName('insertRow')
   @DomName('HTMLTableElement.insertRow')
   @DocsEditable()
-  HtmlElement $dom_insertRow(int index) native;
+  HtmlElement _insertRow(int index) native;
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -22372,13 +22417,13 @@
 
   @DomName('HTMLTableRowElement.cells')
   List<TableCellElement> get cells =>
-      new _WrappedList<TableCellElement>($dom_cells);
+      new _WrappedList<TableCellElement>(_cells);
 
   TableCellElement addCell() {
     return insertCell(-1);
   }
 
-  TableCellElement insertCell(int index) => $dom_insertCell(index);
+  TableCellElement insertCell(int index) => _insertCell(index);
 
   // To suppress missing implicit constructor warnings.
   factory TableRowElement._() { throw new UnsupportedError("Not supported"); }
@@ -22390,7 +22435,7 @@
   @JSName('cells')
   @DomName('HTMLTableRowElement.cells')
   @DocsEditable()
-  final HtmlCollection $dom_cells;
+  final HtmlCollection _cells;
 
   @DomName('HTMLTableRowElement.rowIndex')
   @DocsEditable()
@@ -22407,7 +22452,7 @@
   @JSName('insertCell')
   @DomName('HTMLTableRowElement.insertCell')
   @DocsEditable()
-  HtmlElement $dom_insertCell(int index) native;
+  HtmlElement _insertCell(int index) native;
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -22420,13 +22465,13 @@
 
   @DomName('HTMLTableSectionElement.rows')
   List<TableRowElement> get rows =>
-    new _WrappedList<TableRowElement>($dom_rows);
+    new _WrappedList<TableRowElement>(_rows);
 
   TableRowElement addRow() {
     return insertRow(-1);
   }
 
-  TableRowElement insertRow(int index) => $dom_insertRow(index);
+  TableRowElement insertRow(int index) => _insertRow(index);
 
   // To suppress missing implicit constructor warnings.
   factory TableSectionElement._() { throw new UnsupportedError("Not supported"); }
@@ -22434,7 +22479,7 @@
   @JSName('rows')
   @DomName('HTMLTableSectionElement.rows')
   @DocsEditable()
-  final HtmlCollection $dom_rows;
+  final HtmlCollection _rows;
 
   @DomName('HTMLTableSectionElement.deleteRow')
   @DocsEditable()
@@ -22443,7 +22488,7 @@
   @JSName('insertRow')
   @DomName('HTMLTableSectionElement.insertRow')
   @DocsEditable()
-  HtmlElement $dom_insertRow(int index) native;
+  HtmlElement _insertRow(int index) native;
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -22553,13 +22598,13 @@
   @JSName('content')
   @DomName('HTMLTemplateElement.content')
   @DocsEditable()
-  final DocumentFragment $dom_content;
+  final DocumentFragment _content;
 
 
   // For real TemplateElement use the actual DOM .content field instead of
   // our polyfilled expando.
   @Experimental()
-  DocumentFragment get content => $dom_content;
+  DocumentFragment get content => _content;
 
 
   /**
@@ -22753,6 +22798,22 @@
 }''';
     document.head.append(style);
   }
+
+  /**
+   * An override to place the contents into content rather than as child nodes.
+   *
+   * See also:
+   *
+   * * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#innerhtml-on-templates>
+   */
+  void setInnerHtml(String html,
+    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    text = null;
+    var fragment = createFragment(
+        html, validator: validator, treeSanitizer: treeSanitizer);
+
+    content.append(fragment);
+  }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -22763,7 +22824,7 @@
 
 @DomName('Text')
 class Text extends CharacterData native "Text" {
-  factory Text(String data) => document.$dom_createTextNode(data);
+  factory Text(String data) => document._createTextNode(data);
   // To suppress missing implicit constructor warnings.
   factory Text._() { throw new UnsupportedError("Not supported"); }
 
@@ -22943,8 +23004,8 @@
     if (view == null) {
       view = window;
     }
-    var e = document.$dom_createEvent("TextEvent");
-    e.$dom_initTextEvent(type, canBubble, cancelable, view, data);
+    var e = document._createEvent("TextEvent");
+    e._initTextEvent(type, canBubble, cancelable, view, data);
     return e;
   }
   // To suppress missing implicit constructor warnings.
@@ -22957,7 +23018,7 @@
   @JSName('initTextEvent')
   @DomName('TextEvent.initTextEvent')
   @DocsEditable()
-  void $dom_initTextEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window 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
@@ -23323,12 +23384,12 @@
   @JSName('clientX')
   @DomName('Touch.clientX')
   @DocsEditable()
-  final int $dom_clientX;
+  final int _clientX;
 
   @JSName('clientY')
   @DomName('Touch.clientY')
   @DocsEditable()
-  final int $dom_clientY;
+  final int _clientY;
 
   @DomName('Touch.identifier')
   @DocsEditable()
@@ -23337,22 +23398,22 @@
   @JSName('pageX')
   @DomName('Touch.pageX')
   @DocsEditable()
-  final int $dom_pageX;
+  final int _pageX;
 
   @JSName('pageY')
   @DomName('Touch.pageY')
   @DocsEditable()
-  final int $dom_pageY;
+  final int _pageY;
 
   @JSName('screenX')
   @DomName('Touch.screenX')
   @DocsEditable()
-  final int $dom_screenX;
+  final int _screenX;
 
   @JSName('screenY')
   @DomName('Touch.screenY')
   @DocsEditable()
-  final int $dom_screenY;
+  final int _screenY;
 
   EventTarget get target => _convertNativeToDart_EventTarget(this._get_target);
   @JSName('target')
@@ -23397,15 +23458,15 @@
 
   @DomName('Touch.clientX')
   @DomName('Touch.clientY')
-  Point get client => new Point($dom_clientX, $dom_clientY);
+  Point get client => new Point(_clientX, _clientY);
 
   @DomName('Touch.pageX')
   @DomName('Touch.pageY')
-  Point get page => new Point($dom_pageX, $dom_pageY);
+  Point get page => new Point(_pageX, _pageY);
 
   @DomName('Touch.screenX')
   @DomName('Touch.screenY')
-  Point get screen => new Point($dom_screenX, $dom_screenY);
+  Point get screen => new Point(_screenX, _screenY);
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -23426,8 +23487,8 @@
     if (view == null) {
       view = window;
     }
-    var e = document.$dom_createEvent("TouchEvent");
-    e.$dom_initTouchEvent(touches, targetTouches, changedTouches, type, view,
+    var e = document._createEvent("TouchEvent");
+    e._initTouchEvent(touches, targetTouches, changedTouches, type, view,
         screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey);
     return e;
   }
@@ -23465,7 +23526,7 @@
   @JSName('initTouchEvent')
   @DomName('TouchEvent.initTouchEvent')
   @DocsEditable()
-  void $dom_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;
+  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;
 
 
   /**
@@ -23495,7 +23556,7 @@
   /// NB: This constructor likely does not work as you might expect it to! This
   /// constructor will simply fail (returning null) if you are not on a device
   /// with touch enabled. See dartbug.com/8314.
-  factory TouchList() => document.$dom_createTouchList();
+  factory TouchList() => document._createTouchList();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => JS('bool', '!!document.createTouchList');
@@ -23670,7 +23731,7 @@
 @Unstable()
 class TreeWalker extends Interceptor native "TreeWalker" {
   factory TreeWalker(Node root, int whatToShow) {
-    return document.$dom_createTreeWalker(root, whatToShow, null, false);
+    return document._createTreeWalker(root, whatToShow, null, false);
   }
 
   @DomName('TreeWalker.currentNode')
@@ -23745,8 +23806,8 @@
     if (view == null) {
       view = window;
     }
-    final e = document.$dom_createEvent("UIEvent");
-    e.$dom_initUIEvent(type, canBubble, cancelable, view, detail);
+    final e = document._createEvent("UIEvent");
+    e._initUIEvent(type, canBubble, cancelable, view, detail);
     return e;
   }
   // To suppress missing implicit constructor warnings.
@@ -23756,7 +23817,7 @@
   @DomName('UIEvent.charCode')
   @DocsEditable()
   @Unstable()
-  final int $dom_charCode;
+  final int _charCode;
 
   @DomName('UIEvent.detail')
   @DocsEditable()
@@ -23766,35 +23827,35 @@
   @DomName('UIEvent.keyCode')
   @DocsEditable()
   @Unstable()
-  final int $dom_keyCode;
+  final int _keyCode;
 
   @JSName('layerX')
   @DomName('UIEvent.layerX')
   @DocsEditable()
   // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
   @Experimental() // nonstandard
-  final int $dom_layerX;
+  final int _layerX;
 
   @JSName('layerY')
   @DomName('UIEvent.layerY')
   @DocsEditable()
   // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
   @Experimental() // nonstandard
-  final int $dom_layerY;
+  final int _layerY;
 
   @JSName('pageX')
   @DomName('UIEvent.pageX')
   @DocsEditable()
   // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
   @Experimental() // nonstandard
-  final int $dom_pageX;
+  final int _pageX;
 
   @JSName('pageY')
   @DomName('UIEvent.pageY')
   @DocsEditable()
   // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
   @Experimental() // nonstandard
-  final int $dom_pageY;
+  final int _pageY;
 
   WindowBase get view => _convertNativeToDart_Window(this._get_view);
   @JSName('view')
@@ -23812,7 +23873,7 @@
   @JSName('initUIEvent')
   @DomName('UIEvent.initUIEvent')
   @DocsEditable()
-  void $dom_initUIEvent(String type, bool canBubble, bool cancelable, Window view, int detail) native;
+  void _initUIEvent(String type, bool canBubble, bool cancelable, Window view, int detail) native;
 
 
   @deprecated
@@ -23827,11 +23888,11 @@
 
   @DomName('UIEvent.layerX')
   @DomName('UIEvent.layerY')
-  Point get layer => new Point($dom_layerX, $dom_layerY);
+  Point get layer => new Point(_layerX, _layerY);
 
   @DomName('UIEvent.pageX')
   @DomName('UIEvent.pageY')
-  Point get page => new Point($dom_pageX, $dom_pageY);
+  Point get page => new Point(_pageX, _pageY);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -24294,7 +24355,7 @@
     if (Device.isFirefox) {
       eventType = 'MouseScrollEvents';
     }
-    final event = document.$dom_createEvent(eventType);
+    final event = document._createEvent(eventType);
     // If polyfilling, then flip these because we'll flip them back to match
     // the W3C standard:
     // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-WheelEvent-deltaY
@@ -24338,10 +24399,10 @@
           metaKey, button, relatedTarget, axis);
     } else {
       // Fallthrough for Dartium.
-      event.$dom_initMouseEvent(type, canBubble, cancelable, view, detail,
+      event._initMouseEvent(type, canBubble, cancelable, view, detail,
           screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
           metaKey, button, relatedTarget);
-      event.$dom_initWebKitWheelEvent(deltaX,
+      event._initWebKitWheelEvent(deltaX,
           deltaY ~/ 120, // Chrome does an auto-convert to pixels.
           view, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
           metaKey);
@@ -24377,7 +24438,7 @@
   @DomName('WheelEvent.initWebKitWheelEvent')
   @DocsEditable()
   @Experimental()
-  void $dom_initWebKitWheelEvent(int wheelDeltaX, int wheelDeltaY, Window 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;
 
 
   /**
@@ -24559,6 +24620,15 @@
   }
 
   /**
+   * Deregister 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 deregisterPort(String name) {
+    document.documentElement.attributes.remove('dart-port:$name');
+  }
+
+  /**
    * Returns a Future that completes just before the window is about to
    * repaint so the user can draw an animation frame.
    *
@@ -25129,7 +25199,7 @@
   @JSName('getComputedStyle')
   @DomName('Window.getComputedStyle')
   @DocsEditable()
-  CssStyleDeclaration $dom_getComputedStyle(Element element, String pseudoElement) native;
+  CssStyleDeclaration _getComputedStyle(Element element, String pseudoElement) native;
 
   @JSName('getMatchedCSSRules')
   @DomName('Window.getMatchedCSSRules')
@@ -25154,7 +25224,7 @@
   @JSName('moveTo')
   @DomName('Window.moveTo')
   @DocsEditable()
-  void $dom_moveTo(num x, num y) native;
+  void _moveTo(num x, num y) native;
 
   @DomName('Window.openDatabase')
   @DocsEditable()
@@ -25574,12 +25644,12 @@
   Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);
 
   void moveTo(Point p) {
-    $dom_moveTo(p.x, p.y);
+    _moveTo(p.x, p.y);
   }
 
-  int get scrollX => JS('bool', '("scrollX" in #)', this) ? JS('int', 
+  int get scrollX => JS('bool', '("scrollX" in #)', this) ? JS('int',
       '#.scrollX', this) : document.documentElement.scrollLeft;
-  int get scrollY => JS('bool', '("scrollY" in #)', this) ? JS('int', 
+  int get scrollY => JS('bool', '("scrollY" in #)', this) ? JS('int',
       '#.scrollY', this) : document.documentElement.scrollTop;
 }
 
@@ -27311,7 +27381,7 @@
 
   Iterable<String> get keys {
     // TODO: generate a lazy collection instead.
-    var attributes = _element.$dom_attributes;
+    var attributes = _element._attributes;
     var keys = new List<String>();
     for (int i = 0, len = attributes.length; i < len; i++) {
       if (_matches(attributes[i])) {
@@ -27323,7 +27393,7 @@
 
   Iterable<String> get values {
     // TODO: generate a lazy collection instead.
-    var attributes = _element.$dom_attributes;
+    var attributes = _element._attributes;
     var values = new List<String>();
     for (int i = 0, len = attributes.length; i < len; i++) {
       if (_matches(attributes[i])) {
@@ -27359,7 +27429,7 @@
   _ElementAttributeMap(Element element): super(element);
 
   bool containsKey(String key) {
-    return _element.$dom_hasAttribute(key);
+    return _element._hasAttribute(key);
   }
 
   String operator [](String key) {
@@ -27372,7 +27442,7 @@
 
   String remove(String key) {
     String value = _element.$dom_getAttribute(key);
-    _element.$dom_removeAttribute(key);
+    _element._removeAttribute(key);
     return value;
   }
 
@@ -27383,7 +27453,7 @@
     return keys.length;
   }
 
-  bool _matches(Node node) => node.$dom_namespaceUri == null;
+  bool _matches(Node node) => node._namespaceUri == null;
 }
 
 /**
@@ -27396,7 +27466,7 @@
   _NamespacedAttributeMap(Element element, this._namespace): super(element);
 
   bool containsKey(String key) {
-    return _element.$dom_hasAttributeNS(_namespace, key);
+    return _element._hasAttributeNS(_namespace, key);
   }
 
   String operator [](String key) {
@@ -27409,7 +27479,7 @@
 
   String remove(String key) {
     String value = this[key];
-    _element.$dom_removeAttributeNS(_namespace, key);
+    _element._removeAttributeNS(_namespace, key);
     return value;
   }
 
@@ -27420,7 +27490,7 @@
     return keys.length;
   }
 
-  bool _matches(Node node) => node.$dom_namespaceUri == _namespace;
+  bool _matches(Node node) => node._namespaceUri == _namespace;
 }
 
 
@@ -27430,27 +27500,27 @@
  */
 class _DataAttributeMap implements Map<String, String> {
 
-  final Map<String, String> $dom_attributes;
+  final Map<String, String> _attributes;
 
-  _DataAttributeMap(this.$dom_attributes);
+  _DataAttributeMap(this._attributes);
 
   // interface Map
 
   // TODO: Use lazy iterator when it is available on Map.
   bool containsValue(String value) => values.any((v) => v == value);
 
-  bool containsKey(String key) => $dom_attributes.containsKey(_attr(key));
+  bool containsKey(String key) => _attributes.containsKey(_attr(key));
 
-  String operator [](String key) => $dom_attributes[_attr(key)];
+  String operator [](String key) => _attributes[_attr(key)];
 
   void operator []=(String key, String value) {
-    $dom_attributes[_attr(key)] = value;
+    _attributes[_attr(key)] = value;
   }
 
   String putIfAbsent(String key, String ifAbsent()) =>
-    $dom_attributes.putIfAbsent(_attr(key), ifAbsent);
+    _attributes.putIfAbsent(_attr(key), ifAbsent);
 
-  String remove(String key) => $dom_attributes.remove(_attr(key));
+  String remove(String key) => _attributes.remove(_attr(key));
 
   void clear() {
     // Needs to operate on a snapshot since we are mutating the collection.
@@ -27460,7 +27530,7 @@
   }
 
   void forEach(void f(String key, String value)) {
-    $dom_attributes.forEach((String key, String value) {
+    _attributes.forEach((String key, String value) {
       if (_matches(key)) {
         f(_strip(key), value);
       }
@@ -27469,7 +27539,7 @@
 
   Iterable<String> get keys {
     final keys = new List<String>();
-    $dom_attributes.forEach((String key, String value) {
+    _attributes.forEach((String key, String value) {
       if (_matches(key)) {
         keys.add(_strip(key));
       }
@@ -27479,7 +27549,7 @@
 
   Iterable<String> get values {
     final values = new List<String>();
-    $dom_attributes.forEach((String key, String value) {
+    _attributes.forEach((String key, String value) {
       if (_matches(key)) {
         values.add(value);
       }
@@ -28498,6 +28568,455 @@
     return _eventTypeGetter(target);
   }
 }
+// DO NOT EDIT- this file is generated from running tool/generator.sh.
+
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+/**
+ * A Dart DOM validator generated from Caja whitelists.
+ *
+ * This contains a whitelist of known HTML tagNames and attributes and will only
+ * accept known good values.
+ *
+ * See also:
+ *
+ * * <https://code.google.com/p/google-caja/wiki/CajaWhitelists>
+ */
+class _Html5NodeValidator implements NodeValidator {
+
+  static final Set<String> _allowedElements = new Set.from([
+    'A',
+    'ABBR',
+    'ACRONYM',
+    'ADDRESS',
+    'AREA',
+    'ARTICLE',
+    'ASIDE',
+    'AUDIO',
+    'B',
+    'BDI',
+    'BDO',
+    'BIG',
+    'BLOCKQUOTE',
+    'BR',
+    'BUTTON',
+    'CANVAS',
+    'CAPTION',
+    'CENTER',
+    'CITE',
+    'CODE',
+    'COL',
+    'COLGROUP',
+    'COMMAND',
+    'DATA',
+    'DATALIST',
+    'DD',
+    'DEL',
+    'DETAILS',
+    'DFN',
+    'DIR',
+    'DIV',
+    'DL',
+    'DT',
+    'EM',
+    'FIELDSET',
+    'FIGCAPTION',
+    'FIGURE',
+    'FONT',
+    'FOOTER',
+    'FORM',
+    'H1',
+    'H2',
+    'H3',
+    'H4',
+    'H5',
+    'H6',
+    'HEADER',
+    'HGROUP',
+    'HR',
+    'I',
+    'IFRAME',
+    'IMG',
+    'INPUT',
+    'INS',
+    'KBD',
+    'LABEL',
+    'LEGEND',
+    'LI',
+    'MAP',
+    'MARK',
+    'MENU',
+    'METER',
+    'NAV',
+    'NOBR',
+    'OL',
+    'OPTGROUP',
+    'OPTION',
+    'OUTPUT',
+    'P',
+    'PRE',
+    'PROGRESS',
+    'Q',
+    'S',
+    'SAMP',
+    'SECTION',
+    'SELECT',
+    'SMALL',
+    'SOURCE',
+    'SPAN',
+    'STRIKE',
+    'STRONG',
+    'SUB',
+    'SUMMARY',
+    'SUP',
+    'TABLE',
+    'TBODY',
+    'TD',
+    'TEXTAREA',
+    'TFOOT',
+    'TH',
+    'THEAD',
+    'TIME',
+    'TR',
+    'TRACK',
+    'TT',
+    'U',
+    'UL',
+    'VAR',
+    'VIDEO',
+    'WBR',
+  ]);
+
+  static const _standardAttributes = const <String>[
+    '*::class',
+    '*::dir',
+    '*::draggable',
+    '*::hidden',
+    '*::id',
+    '*::inert',
+    '*::itemprop',
+    '*::itemref',
+    '*::itemscope',
+    '*::lang',
+    '*::spellcheck',
+    '*::title',
+    '*::translate',
+    'A::accesskey',
+    'A::coords',
+    'A::hreflang',
+    'A::name',
+    'A::shape',
+    'A::tabindex',
+    'A::target',
+    'A::type',
+    'AREA::accesskey',
+    'AREA::alt',
+    'AREA::coords',
+    'AREA::nohref',
+    'AREA::shape',
+    'AREA::tabindex',
+    'AREA::target',
+    'AUDIO::controls',
+    'AUDIO::loop',
+    'AUDIO::mediagroup',
+    'AUDIO::muted',
+    'AUDIO::preload',
+    'BDO::dir',
+    'BODY::alink',
+    'BODY::bgcolor',
+    'BODY::link',
+    'BODY::text',
+    'BODY::vlink',
+    'BR::clear',
+    'BUTTON::accesskey',
+    'BUTTON::disabled',
+    'BUTTON::name',
+    'BUTTON::tabindex',
+    'BUTTON::type',
+    'BUTTON::value',
+    'CANVAS::height',
+    'CANVAS::width',
+    'CAPTION::align',
+    'COL::align',
+    'COL::char',
+    'COL::charoff',
+    'COL::span',
+    'COL::valign',
+    'COL::width',
+    'COLGROUP::align',
+    'COLGROUP::char',
+    'COLGROUP::charoff',
+    'COLGROUP::span',
+    'COLGROUP::valign',
+    'COLGROUP::width',
+    'COMMAND::checked',
+    'COMMAND::command',
+    'COMMAND::disabled',
+    'COMMAND::label',
+    'COMMAND::radiogroup',
+    'COMMAND::type',
+    'DATA::value',
+    'DEL::datetime',
+    'DETAILS::open',
+    'DIR::compact',
+    'DIV::align',
+    'DL::compact',
+    'FIELDSET::disabled',
+    'FONT::color',
+    'FONT::face',
+    'FONT::size',
+    'FORM::accept',
+    'FORM::autocomplete',
+    'FORM::enctype',
+    'FORM::method',
+    'FORM::name',
+    'FORM::novalidate',
+    'FORM::target',
+    'FRAME::name',
+    'H1::align',
+    'H2::align',
+    'H3::align',
+    'H4::align',
+    'H5::align',
+    'H6::align',
+    'HR::align',
+    'HR::noshade',
+    'HR::size',
+    'HR::width',
+    'HTML::version',
+    'IFRAME::align',
+    'IFRAME::frameborder',
+    'IFRAME::height',
+    'IFRAME::marginheight',
+    'IFRAME::marginwidth',
+    'IFRAME::width',
+    'IMG::align',
+    'IMG::alt',
+    'IMG::border',
+    'IMG::height',
+    'IMG::hspace',
+    'IMG::ismap',
+    'IMG::name',
+    'IMG::usemap',
+    'IMG::vspace',
+    'IMG::width',
+    'INPUT::accept',
+    'INPUT::accesskey',
+    'INPUT::align',
+    'INPUT::alt',
+    'INPUT::autocomplete',
+    'INPUT::checked',
+    'INPUT::disabled',
+    'INPUT::inputmode',
+    'INPUT::ismap',
+    'INPUT::list',
+    'INPUT::max',
+    'INPUT::maxlength',
+    'INPUT::min',
+    'INPUT::multiple',
+    'INPUT::name',
+    'INPUT::placeholder',
+    'INPUT::readonly',
+    'INPUT::required',
+    'INPUT::size',
+    'INPUT::step',
+    'INPUT::tabindex',
+    'INPUT::type',
+    'INPUT::usemap',
+    'INPUT::value',
+    'INS::datetime',
+    'KEYGEN::disabled',
+    'KEYGEN::keytype',
+    'KEYGEN::name',
+    'LABEL::accesskey',
+    'LABEL::for',
+    'LEGEND::accesskey',
+    'LEGEND::align',
+    'LI::type',
+    'LI::value',
+    'LINK::sizes',
+    'MAP::name',
+    'MENU::compact',
+    'MENU::label',
+    'MENU::type',
+    'METER::high',
+    'METER::low',
+    'METER::max',
+    'METER::min',
+    'METER::value',
+    'OBJECT::typemustmatch',
+    'OL::compact',
+    'OL::reversed',
+    'OL::start',
+    'OL::type',
+    'OPTGROUP::disabled',
+    'OPTGROUP::label',
+    'OPTION::disabled',
+    'OPTION::label',
+    'OPTION::selected',
+    'OPTION::value',
+    'OUTPUT::for',
+    'OUTPUT::name',
+    'P::align',
+    'PRE::width',
+    'PROGRESS::max',
+    'PROGRESS::min',
+    'PROGRESS::value',
+    'SELECT::autocomplete',
+    'SELECT::disabled',
+    'SELECT::multiple',
+    'SELECT::name',
+    'SELECT::required',
+    'SELECT::size',
+    'SELECT::tabindex',
+    'SOURCE::type',
+    'TABLE::align',
+    'TABLE::bgcolor',
+    'TABLE::border',
+    'TABLE::cellpadding',
+    'TABLE::cellspacing',
+    'TABLE::frame',
+    'TABLE::rules',
+    'TABLE::summary',
+    'TABLE::width',
+    'TBODY::align',
+    'TBODY::char',
+    'TBODY::charoff',
+    'TBODY::valign',
+    'TD::abbr',
+    'TD::align',
+    'TD::axis',
+    'TD::bgcolor',
+    'TD::char',
+    'TD::charoff',
+    'TD::colspan',
+    'TD::headers',
+    'TD::height',
+    'TD::nowrap',
+    'TD::rowspan',
+    'TD::scope',
+    'TD::valign',
+    'TD::width',
+    'TEXTAREA::accesskey',
+    'TEXTAREA::autocomplete',
+    'TEXTAREA::cols',
+    'TEXTAREA::disabled',
+    'TEXTAREA::inputmode',
+    'TEXTAREA::name',
+    'TEXTAREA::placeholder',
+    'TEXTAREA::readonly',
+    'TEXTAREA::required',
+    'TEXTAREA::rows',
+    'TEXTAREA::tabindex',
+    'TEXTAREA::wrap',
+    'TFOOT::align',
+    'TFOOT::char',
+    'TFOOT::charoff',
+    'TFOOT::valign',
+    'TH::abbr',
+    'TH::align',
+    'TH::axis',
+    'TH::bgcolor',
+    'TH::char',
+    'TH::charoff',
+    'TH::colspan',
+    'TH::headers',
+    'TH::height',
+    'TH::nowrap',
+    'TH::rowspan',
+    'TH::scope',
+    'TH::valign',
+    'TH::width',
+    'THEAD::align',
+    'THEAD::char',
+    'THEAD::charoff',
+    'THEAD::valign',
+    'TR::align',
+    'TR::bgcolor',
+    'TR::char',
+    'TR::charoff',
+    'TR::valign',
+    'TRACK::default',
+    'TRACK::kind',
+    'TRACK::label',
+    'TRACK::srclang',
+    'UL::compact',
+    'UL::type',
+    'VIDEO::controls',
+    'VIDEO::height',
+    'VIDEO::loop',
+    'VIDEO::mediagroup',
+    'VIDEO::muted',
+    'VIDEO::preload',
+    'VIDEO::width',
+  ];
+
+  static const _uriAttributes = const <String>[
+    'A::href',
+    'AREA::href',
+    'BLOCKQUOTE::cite',
+    'BODY::background',
+    'COMMAND::icon',
+    'DEL::cite',
+    'FORM::action',
+    'IMG::src',
+    'INPUT::src',
+    'INS::cite',
+    'Q::cite',
+    'VIDEO::poster',
+  ];
+
+  final UriPolicy uriPolicy;
+
+  static final Map<String, Function> _attributeValidators = {};
+
+  /**
+   * All known URI attributes will be validated against the UriPolicy, if
+   * [uriPolicy] is null then a default UriPolicy will be used.
+   */
+  _Html5NodeValidator({UriPolicy uriPolicy})
+      :uriPolicy = uriPolicy != null ? uriPolicy : new UriPolicy() {
+
+    if (_attributeValidators.isEmpty) {
+      for (var attr in _standardAttributes) {
+        _attributeValidators[attr] = _standardAttributeValidator;
+      }
+
+      for (var attr in _uriAttributes) {
+        _attributeValidators[attr] = _uriAttributeValidator;
+      }
+    }
+  }
+
+  bool allowsElement(Element element) {
+    return _allowedElements.contains(element.tagName);
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    var tagName = element.tagName;
+    var validator = _attributeValidators['$tagName::$attributeName'];
+    if (validator == null) {
+      validator = _attributeValidators['*::$attributeName'];
+    }
+    if (validator == null) {
+      return false;
+    }
+    return validator(element, attributeName, value, this);
+  }
+
+  static bool _standardAttributeValidator(Element element, String attributeName,
+      String value, _Html5NodeValidator context) {
+    return true;
+  }
+
+  static bool _uriAttributeValidator(Element element, String attributeName,
+      String value, _Html5NodeValidator context) {
+    return context.uriPolicy.allowsUri(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.
@@ -28579,404 +29098,222 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-/**
- * Internal class that does the actual calculations to determine keyCode and
- * charCode for keydown, keypress, and keyup events for all browsers.
- */
-class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
-  // This code inspired by Closure's KeyHandling library.
-  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html
+_serialize(var message) {
+  return new _JsSerializer().traverse(message);
+}
 
-  /**
-   * The set of keys that have been pressed down without seeing their
-   * corresponding keyup event.
-   */
-  final List<KeyboardEvent> _keyDownList = <KeyboardEvent>[];
+class _JsSerializer extends _Serializer {
 
-  /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
-  final String _type;
-
-  /** The element we are watching for events to happen on. */
-  final EventTarget _target;
-
-  // The distance to shift from upper case alphabet Roman letters to lower case.
-  static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];
-
-  /** Controller to produce KeyEvents for the stream. */
-  final StreamController _controller = new StreamController(sync: true);
-
-  static const _EVENT_TYPE = 'KeyEvent';
-
-  /**
-   * An enumeration of key identifiers currently part of the W3C draft for DOM3
-   * and their mappings to keyCodes.
-   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
-   */
-  static const Map<String, int> _keyIdentifier = const {
-    'Up': KeyCode.UP,
-    'Down': KeyCode.DOWN,
-    'Left': KeyCode.LEFT,
-    'Right': KeyCode.RIGHT,
-    'Enter': KeyCode.ENTER,
-    'F1': KeyCode.F1,
-    'F2': KeyCode.F2,
-    'F3': KeyCode.F3,
-    'F4': KeyCode.F4,
-    'F5': KeyCode.F5,
-    'F6': KeyCode.F6,
-    'F7': KeyCode.F7,
-    'F8': KeyCode.F8,
-    'F9': KeyCode.F9,
-    'F10': KeyCode.F10,
-    'F11': KeyCode.F11,
-    'F12': KeyCode.F12,
-    'U+007F': KeyCode.DELETE,
-    'Home': KeyCode.HOME,
-    'End': KeyCode.END,
-    'PageUp': KeyCode.PAGE_UP,
-    'PageDown': KeyCode.PAGE_DOWN,
-    'Insert': KeyCode.INSERT
-  };
-
-  /** Return a stream for KeyEvents for the specified target. */
-  Stream<KeyEvent> forTarget(EventTarget e, {bool useCapture: false}) {
-    return new _KeyboardEventHandler.initializeAllEventListeners(
-        _type, e).stream;
+  visitSendPortSync(SendPortSync x) {
+    if (x is _JsSendPortSync) return visitJsSendPortSync(x);
+    if (x is _LocalSendPortSync) return visitLocalSendPortSync(x);
+    if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x);
+    throw "Unknown port type $x";
   }
 
-  /**
-   * Accessor to the stream associated with a particular KeyboardEvent
-   * EventTarget.
-   *
-   * [forTarget] must be called to initialize this stream to listen to a
-   * particular EventTarget.
-   */
-  Stream<KeyEvent> get stream {
-    if(_target != null) {
-      return _controller.stream;
+  visitJsSendPortSync(_JsSendPortSync x) {
+    return [ 'sendport', 'nativejs', x._id ];
+  }
+
+  visitLocalSendPortSync(_LocalSendPortSync x) {
+    return [ 'sendport', 'dart',
+             ReceivePortSync._isolateId, x._receivePort._portId ];
+  }
+
+  visitSendPort(SendPort x) {
+    throw new UnimplementedError('Asynchronous send port not yet implemented.');
+  }
+
+  visitRemoteSendPortSync(_RemoteSendPortSync x) {
+    return [ 'sendport', 'dart', x._isolateId, x._portId ];
+  }
+}
+
+_deserialize(var message) {
+  return new _JsDeserializer().deserialize(message);
+}
+
+
+class _JsDeserializer extends _Deserializer {
+
+  static const _UNSPECIFIED = const Object();
+
+  deserializeSendPort(List x) {
+    String tag = x[1];
+    switch (tag) {
+      case 'nativejs':
+        num id = x[2];
+        return new _JsSendPortSync(id);
+      case 'dart':
+        num isolateId = x[2];
+        num portId = x[3];
+        return ReceivePortSync._lookup(isolateId, portId);
+      default:
+        throw 'Illegal SendPortSync type: $tag';
+    }
+  }
+}
+
+// The receiver is JS.
+class _JsSendPortSync implements SendPortSync {
+
+  final num _id;
+  _JsSendPortSync(this._id);
+
+  callSync(var message) {
+    var serialized = _serialize(message);
+    var result = _callPortSync(_id, serialized);
+    return _deserialize(result);
+  }
+
+  bool operator==(var other) {
+    return (other is _JsSendPortSync) && (_id == other._id);
+  }
+
+  int get hashCode => _id;
+}
+
+// TODO(vsm): Differentiate between Dart2Js and Dartium isolates.
+// The receiver is a different Dart isolate, compiled to JS.
+class _RemoteSendPortSync implements SendPortSync {
+
+  int _isolateId;
+  int _portId;
+  _RemoteSendPortSync(this._isolateId, this._portId);
+
+  callSync(var message) {
+    var serialized = _serialize(message);
+    var result = _call(_isolateId, _portId, serialized);
+    return _deserialize(result);
+  }
+
+  static _call(int isolateId, int portId, var message) {
+    var target = 'dart-port-$isolateId-$portId';
+    // TODO(vsm): Make this re-entrant.
+    // TODO(vsm): Set this up set once, on the first call.
+    var source = '$target-result';
+    var result = null;
+    window.on[source].first.then((Event e) {
+      result = json.parse(_getPortSyncEventData(e));
+    });
+    _dispatchEvent(target, [source, message]);
+    return result;
+  }
+
+  bool operator==(var other) {
+    return (other is _RemoteSendPortSync) && (_isolateId == other._isolateId)
+      && (_portId == other._portId);
+  }
+
+  int get hashCode => _isolateId >> 16 + _portId;
+}
+
+// The receiver is in the same Dart isolate, compiled to JS.
+class _LocalSendPortSync implements SendPortSync {
+
+  ReceivePortSync _receivePort;
+
+  _LocalSendPortSync._internal(this._receivePort);
+
+  callSync(var message) {
+    // TODO(vsm): Do a more efficient deep copy.
+    var copy = _deserialize(_serialize(message));
+    var result = _receivePort._callback(copy);
+    return _deserialize(_serialize(result));
+  }
+
+  bool operator==(var other) {
+    return (other is _LocalSendPortSync)
+      && (_receivePort == other._receivePort);
+  }
+
+  int get hashCode => _receivePort.hashCode;
+}
+
+// TODO(vsm): Move this to dart:isolate.  This will take some
+// refactoring as there are dependences here on the DOM.  Users
+// interact with this class (or interface if we change it) directly -
+// new ReceivePortSync.  I think most of the DOM logic could be
+// delayed until the corresponding SendPort is registered on the
+// window.
+
+// A Dart ReceivePortSync (tagged 'dart' when serialized) is
+// identifiable / resolvable by the combination of its isolateid and
+// portid.  When a corresponding SendPort is used within the same
+// isolate, the _portMap below can be used to obtain the
+// ReceivePortSync directly.  Across isolates (or from JS), an
+// EventListener can be used to communicate with the port indirectly.
+class ReceivePortSync {
+
+  static Map<int, ReceivePortSync> _portMap;
+  static int _portIdCount;
+  static int _cachedIsolateId;
+
+  num _portId;
+  Function _callback;
+  StreamSubscription _portSubscription;
+
+  ReceivePortSync() {
+    if (_portIdCount == null) {
+      _portIdCount = 0;
+      _portMap = new Map<int, ReceivePortSync>();
+    }
+    _portId = _portIdCount++;
+    _portMap[_portId] = this;
+  }
+
+  static int get _isolateId {
+    // TODO(vsm): Make this coherent with existing isolate code.
+    if (_cachedIsolateId == null) {
+      _cachedIsolateId = _getNewIsolateId();
+    }
+    return _cachedIsolateId;
+  }
+
+  static String _getListenerName(isolateId, portId) =>
+      'dart-port-$isolateId-$portId';
+  String get _listenerName => _getListenerName(_isolateId, _portId);
+
+  void receive(callback(var message)) {
+    _callback = callback;
+    if (_portSubscription == null) {
+      _portSubscription = window.on[_listenerName].listen((Event e) {
+        var data = json.parse(_getPortSyncEventData(e));
+        var replyTo = data[0];
+        var message = _deserialize(data[1]);
+        var result = _callback(message);
+        _dispatchEvent(replyTo, _serialize(result));
+      });
+    }
+  }
+
+  void close() {
+    _portMap.remove(_portId);
+    if (_portSubscription != null) _portSubscription.cancel();
+  }
+
+  SendPortSync toSendPort() {
+    return new _LocalSendPortSync._internal(this);
+  }
+
+  static SendPortSync _lookup(int isolateId, int portId) {
+    if (isolateId == _isolateId) {
+      return _portMap[portId].toSendPort();
     } else {
-      throw new StateError("Not initialized. Call forTarget to access a stream "
-          "initialized with a particular EventTarget.");
+      return new _RemoteSendPortSync(isolateId, portId);
     }
   }
-
-  /**
-   * General constructor, performs basic initialization for our improved
-   * KeyboardEvent controller.
-   */
-  _KeyboardEventHandler(this._type) :
-    _target = null, super(_EVENT_TYPE) {
-  }
-
-  /**
-   * Hook up all event listeners under the covers so we can estimate keycodes
-   * and charcodes when they are not provided.
-   */
-  _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target) :
-    super(_EVENT_TYPE) {
-    Element.keyDownEvent.forTarget(_target, useCapture: true).listen(
-        processKeyDown);
-    Element.keyPressEvent.forTarget(_target, useCapture: true).listen(
-        processKeyPress);
-    Element.keyUpEvent.forTarget(_target, useCapture: true).listen(
-        processKeyUp);
-  }
-
-  /**
-   * Notify all callback listeners that a KeyEvent of the relevant type has
-   * occurred.
-   */
-  bool _dispatch(KeyEvent event) {
-    if (event.type == _type)
-      _controller.add(event);
-  }
-
-  /** Determine if caps lock is one of the currently depressed keys. */
-  bool get _capsLockOn =>
-      _keyDownList.any((var element) => element.keyCode == KeyCode.CAPS_LOCK);
-
-  /**
-   * Given the previously recorded keydown key codes, see if we can determine
-   * the keycode of this keypress [event]. (Generally browsers only provide
-   * charCode information for keypress events, but with a little
-   * reverse-engineering, we can also determine the keyCode.) Returns
-   * KeyCode.UNKNOWN if the keycode could not be determined.
-   */
-  int _determineKeyCodeForKeypress(KeyboardEvent event) {
-    // Note: This function is a work in progress. We'll expand this function
-    // once we get more information about other keyboards.
-    for (var prevEvent in _keyDownList) {
-      if (prevEvent._shadowCharCode == event.charCode) {
-        return prevEvent.keyCode;
-      }
-      if ((event.shiftKey || _capsLockOn) && event.charCode >= "A".codeUnits[0]
-          && event.charCode <= "Z".codeUnits[0] && event.charCode +
-          _ROMAN_ALPHABET_OFFSET == prevEvent._shadowCharCode) {
-        return prevEvent.keyCode;
-      }
-    }
-    return KeyCode.UNKNOWN;
-  }
-
-  /**
-   * Given the charater code returned from a keyDown [event], try to ascertain
-   * and return the corresponding charCode for the character that was pressed.
-   * This information is not shown to the user, but used to help polyfill
-   * keypress events.
-   */
-  int _findCharCodeKeyDown(KeyboardEvent event) {
-    if (event.keyLocation == 3) { // Numpad keys.
-      switch (event.keyCode) {
-        case KeyCode.NUM_ZERO:
-          // Even though this function returns _charCodes_, for some cases the
-          // KeyCode == the charCode we want, in which case we use the keycode
-          // constant for readability.
-          return KeyCode.ZERO;
-        case KeyCode.NUM_ONE:
-          return KeyCode.ONE;
-        case KeyCode.NUM_TWO:
-          return KeyCode.TWO;
-        case KeyCode.NUM_THREE:
-          return KeyCode.THREE;
-        case KeyCode.NUM_FOUR:
-          return KeyCode.FOUR;
-        case KeyCode.NUM_FIVE:
-          return KeyCode.FIVE;
-        case KeyCode.NUM_SIX:
-          return KeyCode.SIX;
-        case KeyCode.NUM_SEVEN:
-          return KeyCode.SEVEN;
-        case KeyCode.NUM_EIGHT:
-          return KeyCode.EIGHT;
-        case KeyCode.NUM_NINE:
-          return KeyCode.NINE;
-        case KeyCode.NUM_MULTIPLY:
-          return 42; // Char code for *
-        case KeyCode.NUM_PLUS:
-          return 43; // +
-        case KeyCode.NUM_MINUS:
-          return 45; // -
-        case KeyCode.NUM_PERIOD:
-          return 46; // .
-        case KeyCode.NUM_DIVISION:
-          return 47; // /
-      }
-    } else if (event.keyCode >= 65 && event.keyCode <= 90) {
-      // Set the "char code" for key down as the lower case letter. Again, this
-      // will not show up for the user, but will be helpful in estimating
-      // keyCode locations and other information during the keyPress event.
-      return event.keyCode + _ROMAN_ALPHABET_OFFSET;
-    }
-    switch(event.keyCode) {
-      case KeyCode.SEMICOLON:
-        return KeyCode.FF_SEMICOLON;
-      case KeyCode.EQUALS:
-        return KeyCode.FF_EQUALS;
-      case KeyCode.COMMA:
-        return 44; // Ascii value for ,
-      case KeyCode.DASH:
-        return 45; // -
-      case KeyCode.PERIOD:
-        return 46; // .
-      case KeyCode.SLASH:
-        return 47; // /
-      case KeyCode.APOSTROPHE:
-        return 96; // `
-      case KeyCode.OPEN_SQUARE_BRACKET:
-        return 91; // [
-      case KeyCode.BACKSLASH:
-        return 92; // \
-      case KeyCode.CLOSE_SQUARE_BRACKET:
-        return 93; // ]
-      case KeyCode.SINGLE_QUOTE:
-        return 39; // '
-    }
-    return event.keyCode;
-  }
-
-  /**
-   * Returns true if the key fires a keypress event in the current browser.
-   */
-  bool _firesKeyPressEvent(KeyEvent event) {
-    if (!Device.isIE && !Device.isWebKit) {
-      return true;
-    }
-
-    if (Device.userAgent.contains('Mac') && event.altKey) {
-      return KeyCode.isCharacterKey(event.keyCode);
-    }
-
-    // Alt but not AltGr which is represented as Alt+Ctrl.
-    if (event.altKey && !event.ctrlKey) {
-      return false;
-    }
-
-    // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
-    if (!event.shiftKey &&
-        (_keyDownList.last.keyCode == KeyCode.CTRL ||
-         _keyDownList.last.keyCode == KeyCode.ALT ||
-         Device.userAgent.contains('Mac') &&
-         _keyDownList.last.keyCode == KeyCode.META)) {
-      return false;
-    }
-
-    // Some keys with Ctrl/Shift do not issue keypress in WebKit.
-    if (Device.isWebKit && event.ctrlKey && event.shiftKey && (
-        event.keyCode == KeyCode.BACKSLASH ||
-        event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
-        event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
-        event.keyCode == KeyCode.TILDE ||
-        event.keyCode == KeyCode.SEMICOLON || event.keyCode == KeyCode.DASH ||
-        event.keyCode == KeyCode.EQUALS || event.keyCode == KeyCode.COMMA ||
-        event.keyCode == KeyCode.PERIOD || event.keyCode == KeyCode.SLASH ||
-        event.keyCode == KeyCode.APOSTROPHE ||
-        event.keyCode == KeyCode.SINGLE_QUOTE)) {
-      return false;
-    }
-
-    switch (event.keyCode) {
-      case KeyCode.ENTER:
-        // IE9 does not fire keypress on ENTER.
-        return !Device.isIE;
-      case KeyCode.ESC:
-        return !Device.isWebKit;
-    }
-
-    return KeyCode.isCharacterKey(event.keyCode);
-  }
-
-  /**
-   * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
-   * Opera all use).
-   */
-  int _normalizeKeyCodes(KeyboardEvent event) {
-    // Note: This may change once we get input about non-US keyboards.
-    if (Device.isFirefox) {
-      switch(event.keyCode) {
-        case KeyCode.FF_EQUALS:
-          return KeyCode.EQUALS;
-        case KeyCode.FF_SEMICOLON:
-          return KeyCode.SEMICOLON;
-        case KeyCode.MAC_FF_META:
-          return KeyCode.META;
-        case KeyCode.WIN_KEY_FF_LINUX:
-          return KeyCode.WIN_KEY;
-      }
-    }
-    return event.keyCode;
-  }
-
-  /** Handle keydown events. */
-  void processKeyDown(KeyboardEvent e) {
-    // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
-    // before we've caught a key-up event.  If the last-key was one of these
-    // we reset the state.
-    if (_keyDownList.length > 0 &&
-        (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
-         _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
-         Device.userAgent.contains('Mac') &&
-         _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
-      _keyDownList.clear();
-    }
-
-    var event = new KeyEvent(e);
-    event._shadowKeyCode = _normalizeKeyCodes(event);
-    // Technically a "keydown" event doesn't have a charCode. This is
-    // calculated nonetheless to provide us with more information in giving
-    // as much information as possible on keypress about keycode and also
-    // charCode.
-    event._shadowCharCode = _findCharCodeKeyDown(event);
-    if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode &&
-        !_firesKeyPressEvent(event)) {
-      // Some browsers have quirks not firing keypress events where all other
-      // browsers do. This makes them more consistent.
-      processKeyPress(e);
-    }
-    _keyDownList.add(event);
-    _dispatch(event);
-  }
-
-  /** Handle keypress events. */
-  void processKeyPress(KeyboardEvent event) {
-    var e = new KeyEvent(event);
-    // IE reports the character code in the keyCode field for keypress events.
-    // There are two exceptions however, Enter and Escape.
-    if (Device.isIE) {
-      if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
-        e._shadowCharCode = 0;
-      } else {
-        e._shadowCharCode = e.keyCode;
-      }
-    } else if (Device.isOpera) {
-      // Opera reports the character code in the keyCode field.
-      e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
-    }
-    // Now we guestimate about what the keycode is that was actually
-    // pressed, given previous keydown information.
-    e._shadowKeyCode = _determineKeyCodeForKeypress(e);
-
-    // Correct the key value for certain browser-specific quirks.
-    if (e._shadowKeyIdentifier != null &&
-        _keyIdentifier.containsKey(e._shadowKeyIdentifier)) {
-      // This is needed for Safari Windows because it currently doesn't give a
-      // keyCode/which for non printable keys.
-      e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier];
-    }
-    e._shadowAltKey = _keyDownList.any((var element) => element.altKey);
-    _dispatch(e);
-  }
-
-  /** Handle keyup events. */
-  void processKeyUp(KeyboardEvent event) {
-    var e = new KeyEvent(event);
-    KeyboardEvent toRemove = null;
-    for (var key in _keyDownList) {
-      if (key.keyCode == e.keyCode) {
-        toRemove = key;
-      }
-    }
-    if (toRemove != null) {
-      _keyDownList.removeWhere((element) => element == toRemove);
-    } else if (_keyDownList.length > 0) {
-      // This happens when we've reached some international keyboard case we
-      // haven't accounted for or we haven't correctly eliminated all browser
-      // inconsistencies. Filing bugs on when this is reached is welcome!
-      _keyDownList.removeLast();
-    }
-    _dispatch(e);
-  }
 }
 
+get _isolateId => ReceivePortSync._isolateId;
 
-/**
- * Records KeyboardEvents that occur on a particular element, and provides a
- * stream of outgoing KeyEvents with cross-browser consistent keyCode and
- * charCode values despite the fact that a multitude of browsers that have
- * varying keyboard default behavior.
- *
- * Example usage:
- *
- *     KeyboardEventStream.onKeyDown(document.body).listen(
- *         keydownHandlerTest);
- *
- * This class is very much a work in progress, and we'd love to get information
- * on how we can make this class work with as many international keyboards as
- * possible. Bugs welcome!
- */
-class KeyboardEventStream {
-
-  /** Named constructor to produce a stream for onKeyPress events. */
-  static Stream<KeyEvent> onKeyPress(EventTarget target) =>
-      new _KeyboardEventHandler('keypress').forTarget(target);
-
-  /** Named constructor to produce a stream for onKeyUp events. */
-  static Stream<KeyEvent> onKeyUp(EventTarget target) =>
-      new _KeyboardEventHandler('keyup').forTarget(target);
-
-  /** Named constructor to produce a stream for onKeyDown events. */
-  static Stream<KeyEvent> onKeyDown(EventTarget target) =>
-    new _KeyboardEventHandler('keydown').forTarget(target);
+void _dispatchEvent(String receiver, var message) {
+  var event = new CustomEvent(receiver, canBubble: false, cancelable:false,
+    detail: json.stringify(message));
+  window.dispatchEvent(event);
 }
+
+String _getPortSyncEventData(CustomEvent event) => event.detail;
 // Copyright (c) 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.
@@ -29744,6 +30081,1016 @@
    */
   static const String UNIDENTIFIED = "Unidentified";
 }
+// Copyright (c) 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.
+
+
+/**
+ * Internal class that does the actual calculations to determine keyCode and
+ * charCode for keydown, keypress, and keyup events for all browsers.
+ */
+class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
+  // This code inspired by Closure's KeyHandling library.
+  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html
+
+  /**
+   * The set of keys that have been pressed down without seeing their
+   * corresponding keyup event.
+   */
+  final List<KeyboardEvent> _keyDownList = <KeyboardEvent>[];
+
+  /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
+  final String _type;
+
+  /** The element we are watching for events to happen on. */
+  final EventTarget _target;
+
+  // The distance to shift from upper case alphabet Roman letters to lower case.
+  static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];
+
+  /** Controller to produce KeyEvents for the stream. */
+  final StreamController _controller = new StreamController(sync: true);
+
+  static const _EVENT_TYPE = 'KeyEvent';
+
+  /**
+   * An enumeration of key identifiers currently part of the W3C draft for DOM3
+   * and their mappings to keyCodes.
+   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
+   */
+  static const Map<String, int> _keyIdentifier = const {
+    'Up': KeyCode.UP,
+    'Down': KeyCode.DOWN,
+    'Left': KeyCode.LEFT,
+    'Right': KeyCode.RIGHT,
+    'Enter': KeyCode.ENTER,
+    'F1': KeyCode.F1,
+    'F2': KeyCode.F2,
+    'F3': KeyCode.F3,
+    'F4': KeyCode.F4,
+    'F5': KeyCode.F5,
+    'F6': KeyCode.F6,
+    'F7': KeyCode.F7,
+    'F8': KeyCode.F8,
+    'F9': KeyCode.F9,
+    'F10': KeyCode.F10,
+    'F11': KeyCode.F11,
+    'F12': KeyCode.F12,
+    'U+007F': KeyCode.DELETE,
+    'Home': KeyCode.HOME,
+    'End': KeyCode.END,
+    'PageUp': KeyCode.PAGE_UP,
+    'PageDown': KeyCode.PAGE_DOWN,
+    'Insert': KeyCode.INSERT
+  };
+
+  /** Return a stream for KeyEvents for the specified target. */
+  Stream<KeyEvent> forTarget(EventTarget e, {bool useCapture: false}) {
+    return new _KeyboardEventHandler.initializeAllEventListeners(
+        _type, e).stream;
+  }
+
+  /**
+   * Accessor to the stream associated with a particular KeyboardEvent
+   * EventTarget.
+   *
+   * [forTarget] must be called to initialize this stream to listen to a
+   * particular EventTarget.
+   */
+  Stream<KeyEvent> get stream {
+    if(_target != null) {
+      return _controller.stream;
+    } else {
+      throw new StateError("Not initialized. Call forTarget to access a stream "
+          "initialized with a particular EventTarget.");
+    }
+  }
+
+  /**
+   * General constructor, performs basic initialization for our improved
+   * KeyboardEvent controller.
+   */
+  _KeyboardEventHandler(this._type) :
+    _target = null, super(_EVENT_TYPE) {
+  }
+
+  /**
+   * Hook up all event listeners under the covers so we can estimate keycodes
+   * and charcodes when they are not provided.
+   */
+  _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target) :
+    super(_EVENT_TYPE) {
+    Element.keyDownEvent.forTarget(_target, useCapture: true).listen(
+        processKeyDown);
+    Element.keyPressEvent.forTarget(_target, useCapture: true).listen(
+        processKeyPress);
+    Element.keyUpEvent.forTarget(_target, useCapture: true).listen(
+        processKeyUp);
+  }
+
+  /**
+   * Notify all callback listeners that a KeyEvent of the relevant type has
+   * occurred.
+   */
+  bool _dispatch(KeyEvent event) {
+    if (event.type == _type)
+      _controller.add(event);
+  }
+
+  /** Determine if caps lock is one of the currently depressed keys. */
+  bool get _capsLockOn =>
+      _keyDownList.any((var element) => element.keyCode == KeyCode.CAPS_LOCK);
+
+  /**
+   * Given the previously recorded keydown key codes, see if we can determine
+   * the keycode of this keypress [event]. (Generally browsers only provide
+   * charCode information for keypress events, but with a little
+   * reverse-engineering, we can also determine the keyCode.) Returns
+   * KeyCode.UNKNOWN if the keycode could not be determined.
+   */
+  int _determineKeyCodeForKeypress(KeyboardEvent event) {
+    // Note: This function is a work in progress. We'll expand this function
+    // once we get more information about other keyboards.
+    for (var prevEvent in _keyDownList) {
+      if (prevEvent._shadowCharCode == event.charCode) {
+        return prevEvent.keyCode;
+      }
+      if ((event.shiftKey || _capsLockOn) && event.charCode >= "A".codeUnits[0]
+          && event.charCode <= "Z".codeUnits[0] && event.charCode +
+          _ROMAN_ALPHABET_OFFSET == prevEvent._shadowCharCode) {
+        return prevEvent.keyCode;
+      }
+    }
+    return KeyCode.UNKNOWN;
+  }
+
+  /**
+   * Given the charater code returned from a keyDown [event], try to ascertain
+   * and return the corresponding charCode for the character that was pressed.
+   * This information is not shown to the user, but used to help polyfill
+   * keypress events.
+   */
+  int _findCharCodeKeyDown(KeyboardEvent event) {
+    if (event.keyLocation == 3) { // Numpad keys.
+      switch (event.keyCode) {
+        case KeyCode.NUM_ZERO:
+          // Even though this function returns _charCodes_, for some cases the
+          // KeyCode == the charCode we want, in which case we use the keycode
+          // constant for readability.
+          return KeyCode.ZERO;
+        case KeyCode.NUM_ONE:
+          return KeyCode.ONE;
+        case KeyCode.NUM_TWO:
+          return KeyCode.TWO;
+        case KeyCode.NUM_THREE:
+          return KeyCode.THREE;
+        case KeyCode.NUM_FOUR:
+          return KeyCode.FOUR;
+        case KeyCode.NUM_FIVE:
+          return KeyCode.FIVE;
+        case KeyCode.NUM_SIX:
+          return KeyCode.SIX;
+        case KeyCode.NUM_SEVEN:
+          return KeyCode.SEVEN;
+        case KeyCode.NUM_EIGHT:
+          return KeyCode.EIGHT;
+        case KeyCode.NUM_NINE:
+          return KeyCode.NINE;
+        case KeyCode.NUM_MULTIPLY:
+          return 42; // Char code for *
+        case KeyCode.NUM_PLUS:
+          return 43; // +
+        case KeyCode.NUM_MINUS:
+          return 45; // -
+        case KeyCode.NUM_PERIOD:
+          return 46; // .
+        case KeyCode.NUM_DIVISION:
+          return 47; // /
+      }
+    } else if (event.keyCode >= 65 && event.keyCode <= 90) {
+      // Set the "char code" for key down as the lower case letter. Again, this
+      // will not show up for the user, but will be helpful in estimating
+      // keyCode locations and other information during the keyPress event.
+      return event.keyCode + _ROMAN_ALPHABET_OFFSET;
+    }
+    switch(event.keyCode) {
+      case KeyCode.SEMICOLON:
+        return KeyCode.FF_SEMICOLON;
+      case KeyCode.EQUALS:
+        return KeyCode.FF_EQUALS;
+      case KeyCode.COMMA:
+        return 44; // Ascii value for ,
+      case KeyCode.DASH:
+        return 45; // -
+      case KeyCode.PERIOD:
+        return 46; // .
+      case KeyCode.SLASH:
+        return 47; // /
+      case KeyCode.APOSTROPHE:
+        return 96; // `
+      case KeyCode.OPEN_SQUARE_BRACKET:
+        return 91; // [
+      case KeyCode.BACKSLASH:
+        return 92; // \
+      case KeyCode.CLOSE_SQUARE_BRACKET:
+        return 93; // ]
+      case KeyCode.SINGLE_QUOTE:
+        return 39; // '
+    }
+    return event.keyCode;
+  }
+
+  /**
+   * Returns true if the key fires a keypress event in the current browser.
+   */
+  bool _firesKeyPressEvent(KeyEvent event) {
+    if (!Device.isIE && !Device.isWebKit) {
+      return true;
+    }
+
+    if (Device.userAgent.contains('Mac') && event.altKey) {
+      return KeyCode.isCharacterKey(event.keyCode);
+    }
+
+    // Alt but not AltGr which is represented as Alt+Ctrl.
+    if (event.altKey && !event.ctrlKey) {
+      return false;
+    }
+
+    // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
+    if (!event.shiftKey &&
+        (_keyDownList.last.keyCode == KeyCode.CTRL ||
+         _keyDownList.last.keyCode == KeyCode.ALT ||
+         Device.userAgent.contains('Mac') &&
+         _keyDownList.last.keyCode == KeyCode.META)) {
+      return false;
+    }
+
+    // Some keys with Ctrl/Shift do not issue keypress in WebKit.
+    if (Device.isWebKit && event.ctrlKey && event.shiftKey && (
+        event.keyCode == KeyCode.BACKSLASH ||
+        event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
+        event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
+        event.keyCode == KeyCode.TILDE ||
+        event.keyCode == KeyCode.SEMICOLON || event.keyCode == KeyCode.DASH ||
+        event.keyCode == KeyCode.EQUALS || event.keyCode == KeyCode.COMMA ||
+        event.keyCode == KeyCode.PERIOD || event.keyCode == KeyCode.SLASH ||
+        event.keyCode == KeyCode.APOSTROPHE ||
+        event.keyCode == KeyCode.SINGLE_QUOTE)) {
+      return false;
+    }
+
+    switch (event.keyCode) {
+      case KeyCode.ENTER:
+        // IE9 does not fire keypress on ENTER.
+        return !Device.isIE;
+      case KeyCode.ESC:
+        return !Device.isWebKit;
+    }
+
+    return KeyCode.isCharacterKey(event.keyCode);
+  }
+
+  /**
+   * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
+   * Opera all use).
+   */
+  int _normalizeKeyCodes(KeyboardEvent event) {
+    // Note: This may change once we get input about non-US keyboards.
+    if (Device.isFirefox) {
+      switch(event.keyCode) {
+        case KeyCode.FF_EQUALS:
+          return KeyCode.EQUALS;
+        case KeyCode.FF_SEMICOLON:
+          return KeyCode.SEMICOLON;
+        case KeyCode.MAC_FF_META:
+          return KeyCode.META;
+        case KeyCode.WIN_KEY_FF_LINUX:
+          return KeyCode.WIN_KEY;
+      }
+    }
+    return event.keyCode;
+  }
+
+  /** Handle keydown events. */
+  void processKeyDown(KeyboardEvent e) {
+    // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
+    // before we've caught a key-up event.  If the last-key was one of these
+    // we reset the state.
+    if (_keyDownList.length > 0 &&
+        (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
+         _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
+         Device.userAgent.contains('Mac') &&
+         _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
+      _keyDownList.clear();
+    }
+
+    var event = new KeyEvent(e);
+    event._shadowKeyCode = _normalizeKeyCodes(event);
+    // Technically a "keydown" event doesn't have a charCode. This is
+    // calculated nonetheless to provide us with more information in giving
+    // as much information as possible on keypress about keycode and also
+    // charCode.
+    event._shadowCharCode = _findCharCodeKeyDown(event);
+    if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode &&
+        !_firesKeyPressEvent(event)) {
+      // Some browsers have quirks not firing keypress events where all other
+      // browsers do. This makes them more consistent.
+      processKeyPress(e);
+    }
+    _keyDownList.add(event);
+    _dispatch(event);
+  }
+
+  /** Handle keypress events. */
+  void processKeyPress(KeyboardEvent event) {
+    var e = new KeyEvent(event);
+    // IE reports the character code in the keyCode field for keypress events.
+    // There are two exceptions however, Enter and Escape.
+    if (Device.isIE) {
+      if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
+        e._shadowCharCode = 0;
+      } else {
+        e._shadowCharCode = e.keyCode;
+      }
+    } else if (Device.isOpera) {
+      // Opera reports the character code in the keyCode field.
+      e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
+    }
+    // Now we guestimate about what the keycode is that was actually
+    // pressed, given previous keydown information.
+    e._shadowKeyCode = _determineKeyCodeForKeypress(e);
+
+    // Correct the key value for certain browser-specific quirks.
+    if (e._shadowKeyIdentifier != null &&
+        _keyIdentifier.containsKey(e._shadowKeyIdentifier)) {
+      // This is needed for Safari Windows because it currently doesn't give a
+      // keyCode/which for non printable keys.
+      e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier];
+    }
+    e._shadowAltKey = _keyDownList.any((var element) => element.altKey);
+    _dispatch(e);
+  }
+
+  /** Handle keyup events. */
+  void processKeyUp(KeyboardEvent event) {
+    var e = new KeyEvent(event);
+    KeyboardEvent toRemove = null;
+    for (var key in _keyDownList) {
+      if (key.keyCode == e.keyCode) {
+        toRemove = key;
+      }
+    }
+    if (toRemove != null) {
+      _keyDownList.removeWhere((element) => element == toRemove);
+    } else if (_keyDownList.length > 0) {
+      // This happens when we've reached some international keyboard case we
+      // haven't accounted for or we haven't correctly eliminated all browser
+      // inconsistencies. Filing bugs on when this is reached is welcome!
+      _keyDownList.removeLast();
+    }
+    _dispatch(e);
+  }
+}
+
+
+/**
+ * Records KeyboardEvents that occur on a particular element, and provides a
+ * stream of outgoing KeyEvents with cross-browser consistent keyCode and
+ * charCode values despite the fact that a multitude of browsers that have
+ * varying keyboard default behavior.
+ *
+ * Example usage:
+ *
+ *     KeyboardEventStream.onKeyDown(document.body).listen(
+ *         keydownHandlerTest);
+ *
+ * This class is very much a work in progress, and we'd love to get information
+ * on how we can make this class work with as many international keyboards as
+ * possible. Bugs welcome!
+ */
+class KeyboardEventStream {
+
+  /** Named constructor to produce a stream for onKeyPress events. */
+  static Stream<KeyEvent> onKeyPress(EventTarget target) =>
+      new _KeyboardEventHandler('keypress').forTarget(target);
+
+  /** Named constructor to produce a stream for onKeyUp events. */
+  static Stream<KeyEvent> onKeyUp(EventTarget target) =>
+      new _KeyboardEventHandler('keyup').forTarget(target);
+
+  /** Named constructor to produce a stream for onKeyDown events. */
+  static Stream<KeyEvent> onKeyDown(EventTarget target) =>
+    new _KeyboardEventHandler('keydown').forTarget(target);
+}
+// Copyright (c) 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 _MicrotaskCallback();
+
+/**
+ * This class attempts to invoke a callback as soon as the current event stack
+ * unwinds, but before the browser repaints.
+ */
+abstract class _MicrotaskScheduler {
+  bool _nextMicrotaskFrameScheduled = false;
+  final _MicrotaskCallback _callback;
+
+  _MicrotaskScheduler(this._callback);
+
+  /**
+   * Creates the best possible microtask scheduler for the current platform.
+   */
+  factory _MicrotaskScheduler.best(_MicrotaskCallback callback) {
+    if (Window._supportsSetImmediate) {
+      return new _SetImmediateScheduler(callback);
+    } else if (MutationObserver.supported) {
+      return new _MutationObserverScheduler(callback);
+    }
+    return new _PostMessageScheduler(callback);
+  }
+
+  /**
+   * Schedules a microtask callback if one has not been scheduled already.
+   */
+  void maybeSchedule() {
+    if (this._nextMicrotaskFrameScheduled) {
+      return;
+    }
+    this._nextMicrotaskFrameScheduled = true;
+    this._schedule();
+  }
+
+  /**
+   * Does the actual scheduling of the callback.
+   */
+  void _schedule();
+
+  /**
+   * Handles the microtask callback and forwards it if necessary.
+   */
+  void _onCallback() {
+    // Ignore spurious messages.
+    if (!_nextMicrotaskFrameScheduled) {
+      return;
+    }
+    _nextMicrotaskFrameScheduled = false;
+    this._callback();
+  }
+}
+
+/**
+ * Scheduler which uses window.postMessage to schedule events.
+ */
+class _PostMessageScheduler extends _MicrotaskScheduler {
+  const _MICROTASK_MESSAGE = "DART-MICROTASK";
+
+  _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
+      // Messages from other windows do not cause a security risk as
+      // all we care about is that _handleMessage is called
+      // after the current event loop is unwound and calling the function is
+      // a noop when zero requests are pending.
+      window.onMessage.listen(this._handleMessage);
+  }
+
+  void _schedule() {
+    window.postMessage(_MICROTASK_MESSAGE, "*");
+  }
+
+  void _handleMessage(e) {
+    this._onCallback();
+  }
+}
+
+/**
+ * Scheduler which uses a MutationObserver to schedule events.
+ */
+class _MutationObserverScheduler extends _MicrotaskScheduler {
+  MutationObserver _observer;
+  Element _dummy;
+
+  _MutationObserverScheduler(_MicrotaskCallback callback): super(callback) {
+    // Mutation events get fired as soon as the current event stack is unwound
+    // so we just make a dummy event and listen for that.
+    _observer = new MutationObserver(this._handleMutation);
+    _dummy = new DivElement();
+    _observer.observe(_dummy, attributes: true);
+  }
+
+  void _schedule() {
+    // Toggle it to trigger the mutation event.
+    _dummy.hidden = !_dummy.hidden;
+  }
+
+  _handleMutation(List<MutationRecord> mutations, MutationObserver observer) {
+    this._onCallback();
+  }
+}
+
+/**
+ * Scheduler which uses window.setImmediate to schedule events.
+ */
+class _SetImmediateScheduler extends _MicrotaskScheduler {
+  _SetImmediateScheduler(_MicrotaskCallback callback): super(callback);
+
+  void _schedule() {
+    window._setImmediate(_handleImmediate);
+  }
+
+  void _handleImmediate() {
+    this._onCallback();
+  }
+}
+
+List<TimeoutHandler> _pendingMicrotasks;
+_MicrotaskScheduler _microtaskScheduler = null;
+
+void _maybeScheduleMicrotaskFrame() {
+  if (_microtaskScheduler == null) {
+    _microtaskScheduler =
+      new _MicrotaskScheduler.best(_completeMicrotasks);
+  }
+  _microtaskScheduler.maybeSchedule();
+}
+
+/**
+ * Registers a [callback] which is called after the current execution stack
+ * unwinds.
+ */
+void _addMicrotaskCallback(TimeoutHandler callback) {
+  if (_pendingMicrotasks == null) {
+    _pendingMicrotasks = <TimeoutHandler>[];
+    _maybeScheduleMicrotaskFrame();
+  }
+  _pendingMicrotasks.add(callback);
+}
+
+
+/**
+ * Complete all pending microtasks.
+ */
+void _completeMicrotasks() {
+  var callbacks = _pendingMicrotasks;
+  _pendingMicrotasks = null;
+  for (var callback in callbacks) {
+    callback();
+  }
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+
+/**
+ * Class which helps construct standard node validation policies.
+ *
+ * By default this will not accept anything, but the 'allow*' functions can be
+ * used to expand what types of elements or attributes are allowed.
+ *
+ * All allow functions are additive- elements will be accepted if they are
+ * accepted by any specific rule.
+ *
+ * It is important to remember that sanitization is not just intended to prevent
+ * cross-site scripting attacks, but also to prevent information from being
+ * displayed in unexpected ways. For example something displaying basic
+ * formatted text may not expect `<video>` tags to appear. In this case an
+ * empty NodeValidatorBuilder with just [allowTextElements] might be
+ * appropriate.
+ */
+class NodeValidatorBuilder implements NodeValidator {
+
+  final List<NodeValidator> _validators = <NodeValidator>[];
+
+  NodeValidatorBuilder() {
+  }
+
+  /**
+   * Creates a new NodeValidatorBuilder which accepts common constructs.
+   *
+   * By default this will accept HTML5 elements and attributes with the default
+   * [UriPolicy] and templating elements.
+   *
+   * Notable syntax which is filtered:
+   *
+   * * Only known-good HTML5 elements and attributes are allowed.
+   * * All URLs must be same-origin, use [allowNavigation] and [allowImages] to
+   * specify additional URI policies.
+   * * Inline-styles are not allowed.
+   * * Custom element tags are disallowed, use [allowCustomElement].
+   * * Custom tags extensions are disallowed, use [allowTagExtension].
+   * * SVG Elements are not allowed, use [allowSvg].
+   *
+   * For scenarios where the HTML should only contain formatted text
+   * [allowTextElements] is more appropriate.
+   *
+   * Use [allowSvg] to allow SVG elements.
+   */
+  NodeValidatorBuilder.common() {
+    allowHtml5();
+    allowTemplating();
+  }
+
+  /**
+   * Allows navigation elements- Form and Anchor tags, along with common
+   * attributes.
+   *
+   * The UriPolicy can be used to restrict the locations the navigation elements
+   * are allowed to direct to. By default this will use the default [UriPolicy].
+   */
+  void allowNavigation([UriPolicy uriPolicy]) {
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+    add(new _SimpleNodeValidator.allowNavigation(uriPolicy));
+  }
+
+  /**
+   * Allows image elements.
+   *
+   * The UriPolicy can be used to restrict the locations the images may be
+   * loaded from. By default this will use the default [UriPolicy].
+   */
+  void allowImages([UriPolicy uriPolicy]) {
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+    add(new _SimpleNodeValidator.allowImages(uriPolicy));
+  }
+
+  /**
+   * Allow basic text elements.
+   *
+   * This allows a subset of HTML5 elements, specifically just these tags and
+   * no attributes.
+   *
+   * * B
+   * * BLOCKQUOTE
+   * * BR
+   * * EM
+   * * H1
+   * * H2
+   * * H3
+   * * H4
+   * * H5
+   * * H6
+   * * HR
+   * * I
+   * * LI
+   * * OL
+   * * P
+   * * SPAN
+   * * UL
+   */
+  void allowTextElements() {
+    add(new _SimpleNodeValidator.allowTextElements());
+  }
+
+  /**
+   * Allow common safe HTML5 elements and attributes.
+   *
+   * This list is based off of the Caja whitelists at:
+   * https://code.google.com/p/google-caja/wiki/CajaWhitelists.
+   *
+   * Common things which are not allowed are script elements, style attributes
+   * and any script handlers.
+   */
+  void allowHtml5({UriPolicy uriPolicy}) {
+    add(new _Html5NodeValidator(uriPolicy: uriPolicy));
+  }
+
+  /**
+   * Allow SVG elements and attributes except for known bad ones.
+   */
+  void allowSvg() {
+    add(new _SvgNodeValidator());
+  }
+
+  /**
+   * Allow custom elements with the specified tag name and specified attributes.
+   *
+   * This will allow the elements as custom tags (such as <x-foo></x-foo>),
+   * but will not allow tag extensions. Use [allowTagExtension] to allow
+   * tag extensions.
+   */
+  void allowCustomElement(String tagName,
+      {UriPolicy uriPolicy,
+      Iterable<String> attributes,
+      Iterable<String> uriAttributes}) {
+
+    var tagNameUpper = tagName.toUpperCase();
+    var attrs;
+    if (attributes != null) {
+      attrs =
+          attributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
+    }
+    var uriAttrs;
+    if (uriAttributes != null) {
+      uriAttrs =
+          uriAttributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
+    }
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+
+    add(new _CustomElementNodeValidator(
+        uriPolicy,
+        [tagNameUpper],
+        attrs,
+        uriAttrs,
+        false,
+        true));
+  }
+
+  /**
+   * Allow custom tag extensions with the specified type name and specified
+   * attributes.
+   *
+   * This will allow tag extensions (such as <div is="x-foo"></div>),
+   * but will not allow custom tags. Use [allowCustomElement] to allow
+   * custom tags.
+   */
+  void allowTagExtension(String tagName, String baseName,
+      {UriPolicy uriPolicy,
+      Iterable<String> attributes,
+      Iterable<String> uriAttributes}) {
+
+    var baseNameUpper = baseName.toUpperCase();
+    var tagNameUpper = tagName.toUpperCase();
+    var attrs;
+    if (attributes != null) {
+      attrs =
+          attributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
+    }
+    var uriAttrs;
+    if (uriAttributes != null) {
+      uriAttrs =
+          uriAttributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
+    }
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+
+    add(new _CustomElementNodeValidator(
+        uriPolicy,
+        [tagNameUpper, baseNameUpper],
+        attrs,
+        uriAttrs,
+        true,
+        false));
+  }
+
+  void allowElement(String tagName, {UriPolicy uriPolicy,
+    Iterable<String> attributes,
+    Iterable<String> uriAttributes}) {
+
+    allowCustomElement(tagName, uriPolicy: uriPolicy,
+        attributes: attributes,
+        uriAttributes: uriAttributes);
+  }
+
+  /**
+   * Allow templating elements (such as <template> and template-related
+   * attributes.
+   *
+   * This still requires other validators to allow regular attributes to be
+   * bound (such as [allowHtml5]).
+   */
+  void allowTemplating() {
+    add(new _TemplatingNodeValidator());
+  }
+
+  /**
+   * Add an additional validator to the current list of validators.
+   *
+   * Elements and attributes will be accepted if they are accepted by any
+   * validators.
+   */
+  void add(NodeValidator validator) {
+    _validators.add(validator);
+  }
+
+  bool allowsElement(Element element) {
+    return _validators.any((v) => v.allowsElement(element));
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    return _validators.any(
+        (v) => v.allowsAttribute(element, attributeName, value));
+  }
+}
+
+class _SimpleNodeValidator implements NodeValidator {
+  final Set<String> allowedElements;
+  final Set<String> allowedAttributes;
+  final Set<String> allowedUriAttributes;
+  final UriPolicy uriPolicy;
+
+  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
+    return new _SimpleNodeValidator(uriPolicy,
+      allowedElements: [
+        'A',
+        'FORM'],
+      allowedAttributes: [
+        'A::accesskey',
+        'A::coords',
+        'A::hreflang',
+        'A::name',
+        'A::shape',
+        'A::tabindex',
+        'A::target',
+        'A::type',
+        'FORM::accept',
+        'FORM::autocomplete',
+        'FORM::enctype',
+        'FORM::method',
+        'FORM::name',
+        'FORM::novalidate',
+        'FORM::target',
+      ],
+      allowedUriAttributes: [
+        'A::href',
+        'FORM::action',
+      ]);
+  }
+
+  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
+    return new _SimpleNodeValidator(uriPolicy,
+      allowedElements: [
+        'IMG'
+      ],
+      allowedAttributes: [
+        'IMG::align',
+        'IMG::alt',
+        'IMG::border',
+        'IMG::height',
+        'IMG::hspace',
+        'IMG::ismap',
+        'IMG::name',
+        'IMG::usemap',
+        'IMG::vspace',
+        'IMG::width',
+      ],
+      allowedUriAttributes: [
+        'IMG::src',
+      ]);
+  }
+
+  factory _SimpleNodeValidator.allowTextElements() {
+    return new _SimpleNodeValidator(null,
+      allowedElements: [
+        'B',
+        'BLOCKQUOTE',
+        'BR',
+        'EM',
+        'H1',
+        'H2',
+        'H3',
+        'H4',
+        'H5',
+        'H6',
+        'HR',
+        'I',
+        'LI',
+        'OL',
+        'P',
+        'SPAN',
+        'UL',
+      ]);
+  }
+
+  /**
+   * Elements must be uppercased tag names. For example `'IMG'`.
+   * Attributes must be uppercased tag name followed by :: followed by
+   * lowercase attribute name. For example `'IMG:src'`.
+   */
+  _SimpleNodeValidator(this.uriPolicy,
+      {Iterable<String> allowedElements, Iterable<String> allowedAttributes,
+      Iterable<String> allowedUriAttributes}):
+      this.allowedElements = allowedElements != null ?
+          new Set.from(allowedElements) : new Set(),
+      this.allowedAttributes = allowedAttributes != null ?
+          new Set.from(allowedAttributes) : new Set(),
+      this.allowedUriAttributes = allowedUriAttributes != null ?
+          new Set.from(allowedUriAttributes) : new Set();
+
+  bool allowsElement(Element element) {
+    return allowedElements.contains(element.tagName);
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    var tagName = element.tagName;
+    if (allowedUriAttributes.contains('$tagName::$attributeName')) {
+      return uriPolicy.allowsUri(value);
+    } else if (allowedUriAttributes.contains('*::$attributeName')) {
+      return uriPolicy.allowsUri(value);
+    } else if (allowedAttributes.contains('$tagName::$attributeName')) {
+      return true;
+    } else if (allowedAttributes.contains('*::$attributeName')) {
+      return true;
+    } else if (allowedAttributes.contains('$tagName::*')) {
+      return true;
+    } else if (allowedAttributes.contains('*::*')) {
+      return true;
+    }
+    return false;
+  }
+}
+
+class _CustomElementNodeValidator extends _SimpleNodeValidator {
+  final bool allowTypeExtension;
+  final bool allowCustomTag;
+
+  _CustomElementNodeValidator(UriPolicy uriPolicy,
+      Iterable<String> allowedElements,
+      Iterable<String> allowedAttributes,
+      Iterable<String> allowedUriAttributes,
+      bool allowTypeExtension,
+      bool allowCustomTag):
+
+      super(uriPolicy,
+          allowedElements: allowedElements,
+          allowedAttributes: allowedAttributes,
+          allowedUriAttributes: allowedUriAttributes),
+      this.allowTypeExtension = allowTypeExtension == true,
+      this.allowCustomTag = allowCustomTag == true;
+
+  bool allowsElement(Element element) {
+    if (allowTypeExtension) {
+      var isAttr = element.attributes['is'];
+      if (isAttr != null) {
+        return allowedElements.contains(isAttr.toUpperCase()) &&
+          allowedElements.contains(element.tagName);
+      }
+    }
+    return allowCustomTag && allowedElements.contains(element.tagName);
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+   if (allowsElement(element)) {
+      if (allowTypeExtension && attributeName == 'is' &&
+          allowedElements.contains(value.toUpperCase())) {
+        return true;
+      }
+      return super.allowsAttribute(element, attributeName, value);
+    }
+    return false;
+  }
+}
+
+class _TemplatingNodeValidator extends _SimpleNodeValidator {
+  static const _TEMPLATE_ATTRS =
+      const <String>['bind', 'if', 'ref', 'repeat', 'syntax'];
+
+  final Set<String> _templateAttrs;
+
+  _TemplatingNodeValidator():
+      super(null,
+          allowedElements: [
+            'TEMPLATE'
+          ],
+          allowedAttributes: _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')),
+      _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS) {
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (super.allowsAttribute(element, attributeName, value)) {
+      return true;
+    }
+
+    if (attributeName == 'template' && value == "") {
+      return true;
+    }
+
+    if (element.attributes['template'] == "" ) {
+      return _templateAttrs.contains(attributeName);
+    }
+    return false;
+  }
+}
+
+
+class _SvgNodeValidator implements NodeValidator {
+  bool allowsElement(Element element) {
+    if (element is svg.ScriptElement) {
+      return false;
+    }
+    if (element is svg.SvgElement) {
+      return true;
+    }
+    return false;
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (attributeName == 'is' || attributeName.startsWith('on')) {
+      return false;
+    }
+    return allowsElement(element);
+  }
+}
 // 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.
@@ -30001,409 +31348,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 _HttpRequestUtils {
-
-  // Helper for factory HttpRequest.get
-  static HttpRequest get(String url,
-                            onComplete(HttpRequest request),
-                            bool withCredentials) {
-    final request = new HttpRequest();
-    request.open('GET', url, async: true);
-
-    request.withCredentials = withCredentials;
-
-    request.onReadyStateChange.listen((e) {
-      if (request.readyState == HttpRequest.DONE) {
-        onComplete(request);
-      }
-    });
-
-    request.send();
-
-    return request;
-  }
-}
-// Copyright (c) 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.
-
-
-_serialize(var message) {
-  return new _JsSerializer().traverse(message);
-}
-
-class _JsSerializer extends _Serializer {
-
-  visitSendPortSync(SendPortSync x) {
-    if (x is _JsSendPortSync) return visitJsSendPortSync(x);
-    if (x is _LocalSendPortSync) return visitLocalSendPortSync(x);
-    if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x);
-    throw "Unknown port type $x";
-  }
-
-  visitJsSendPortSync(_JsSendPortSync x) {
-    return [ 'sendport', 'nativejs', x._id ];
-  }
-
-  visitLocalSendPortSync(_LocalSendPortSync x) {
-    return [ 'sendport', 'dart',
-             ReceivePortSync._isolateId, x._receivePort._portId ];
-  }
-
-  visitSendPort(SendPort x) {
-    throw new UnimplementedError('Asynchronous send port not yet implemented.');
-  }
-
-  visitRemoteSendPortSync(_RemoteSendPortSync x) {
-    return [ 'sendport', 'dart', x._isolateId, x._portId ];
-  }
-}
-
-_deserialize(var message) {
-  return new _JsDeserializer().deserialize(message);
-}
-
-
-class _JsDeserializer extends _Deserializer {
-
-  static const _UNSPECIFIED = const Object();
-
-  deserializeSendPort(List x) {
-    String tag = x[1];
-    switch (tag) {
-      case 'nativejs':
-        num id = x[2];
-        return new _JsSendPortSync(id);
-      case 'dart':
-        num isolateId = x[2];
-        num portId = x[3];
-        return ReceivePortSync._lookup(isolateId, portId);
-      default:
-        throw 'Illegal SendPortSync type: $tag';
-    }
-  }
-}
-
-// The receiver is JS.
-class _JsSendPortSync implements SendPortSync {
-
-  final num _id;
-  _JsSendPortSync(this._id);
-
-  callSync(var message) {
-    var serialized = _serialize(message);
-    var result = _callPortSync(_id, serialized);
-    return _deserialize(result);
-  }
-
-  bool operator==(var other) {
-    return (other is _JsSendPortSync) && (_id == other._id);
-  }
-
-  int get hashCode => _id;
-}
-
-// TODO(vsm): Differentiate between Dart2Js and Dartium isolates.
-// The receiver is a different Dart isolate, compiled to JS.
-class _RemoteSendPortSync implements SendPortSync {
-
-  int _isolateId;
-  int _portId;
-  _RemoteSendPortSync(this._isolateId, this._portId);
-
-  callSync(var message) {
-    var serialized = _serialize(message);
-    var result = _call(_isolateId, _portId, serialized);
-    return _deserialize(result);
-  }
-
-  static _call(int isolateId, int portId, var message) {
-    var target = 'dart-port-$isolateId-$portId';
-    // TODO(vsm): Make this re-entrant.
-    // TODO(vsm): Set this up set once, on the first call.
-    var source = '$target-result';
-    var result = null;
-    window.on[source].first.then((Event e) {
-      result = json.parse(_getPortSyncEventData(e));
-    });
-    _dispatchEvent(target, [source, message]);
-    return result;
-  }
-
-  bool operator==(var other) {
-    return (other is _RemoteSendPortSync) && (_isolateId == other._isolateId)
-      && (_portId == other._portId);
-  }
-
-  int get hashCode => _isolateId >> 16 + _portId;
-}
-
-// The receiver is in the same Dart isolate, compiled to JS.
-class _LocalSendPortSync implements SendPortSync {
-
-  ReceivePortSync _receivePort;
-
-  _LocalSendPortSync._internal(this._receivePort);
-
-  callSync(var message) {
-    // TODO(vsm): Do a more efficient deep copy.
-    var copy = _deserialize(_serialize(message));
-    var result = _receivePort._callback(copy);
-    return _deserialize(_serialize(result));
-  }
-
-  bool operator==(var other) {
-    return (other is _LocalSendPortSync)
-      && (_receivePort == other._receivePort);
-  }
-
-  int get hashCode => _receivePort.hashCode;
-}
-
-// TODO(vsm): Move this to dart:isolate.  This will take some
-// refactoring as there are dependences here on the DOM.  Users
-// interact with this class (or interface if we change it) directly -
-// new ReceivePortSync.  I think most of the DOM logic could be
-// delayed until the corresponding SendPort is registered on the
-// window.
-
-// A Dart ReceivePortSync (tagged 'dart' when serialized) is
-// identifiable / resolvable by the combination of its isolateid and
-// portid.  When a corresponding SendPort is used within the same
-// isolate, the _portMap below can be used to obtain the
-// ReceivePortSync directly.  Across isolates (or from JS), an
-// EventListener can be used to communicate with the port indirectly.
-class ReceivePortSync {
-
-  static Map<int, ReceivePortSync> _portMap;
-  static int _portIdCount;
-  static int _cachedIsolateId;
-
-  num _portId;
-  Function _callback;
-  StreamSubscription _portSubscription;
-
-  ReceivePortSync() {
-    if (_portIdCount == null) {
-      _portIdCount = 0;
-      _portMap = new Map<int, ReceivePortSync>();
-    }
-    _portId = _portIdCount++;
-    _portMap[_portId] = this;
-  }
-
-  static int get _isolateId {
-    // TODO(vsm): Make this coherent with existing isolate code.
-    if (_cachedIsolateId == null) {
-      _cachedIsolateId = _getNewIsolateId();
-    }
-    return _cachedIsolateId;
-  }
-
-  static String _getListenerName(isolateId, portId) =>
-      'dart-port-$isolateId-$portId';
-  String get _listenerName => _getListenerName(_isolateId, _portId);
-
-  void receive(callback(var message)) {
-    _callback = callback;
-    if (_portSubscription == null) {
-      _portSubscription = window.on[_listenerName].listen((Event e) {
-        var data = json.parse(_getPortSyncEventData(e));
-        var replyTo = data[0];
-        var message = _deserialize(data[1]);
-        var result = _callback(message);
-        _dispatchEvent(replyTo, _serialize(result));
-      });
-    }
-  }
-
-  void close() {
-    _portMap.remove(_portId);
-    if (_portSubscription != null) _portSubscription.cancel();
-  }
-
-  SendPortSync toSendPort() {
-    return new _LocalSendPortSync._internal(this);
-  }
-
-  static SendPortSync _lookup(int isolateId, int portId) {
-    if (isolateId == _isolateId) {
-      return _portMap[portId].toSendPort();
-    } else {
-      return new _RemoteSendPortSync(isolateId, portId);
-    }
-  }
-}
-
-get _isolateId => ReceivePortSync._isolateId;
-
-void _dispatchEvent(String receiver, var message) {
-  var event = new CustomEvent(receiver, canBubble: false, cancelable:false,
-    detail: json.stringify(message));
-  window.dispatchEvent(event);
-}
-
-String _getPortSyncEventData(CustomEvent event) => event.detail;
-// Copyright (c) 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 _MicrotaskCallback();
-
-/**
- * This class attempts to invoke a callback as soon as the current event stack
- * unwinds, but before the browser repaints.
- */
-abstract class _MicrotaskScheduler {
-  bool _nextMicrotaskFrameScheduled = false;
-  final _MicrotaskCallback _callback;
-
-  _MicrotaskScheduler(this._callback);
-
-  /**
-   * Creates the best possible microtask scheduler for the current platform.
-   */
-  factory _MicrotaskScheduler.best(_MicrotaskCallback callback) {
-    if (Window._supportsSetImmediate) {
-      return new _SetImmediateScheduler(callback);
-    } else if (MutationObserver.supported) {
-      return new _MutationObserverScheduler(callback);
-    }
-    return new _PostMessageScheduler(callback);
-  }
-
-  /**
-   * Schedules a microtask callback if one has not been scheduled already.
-   */
-  void maybeSchedule() {
-    if (this._nextMicrotaskFrameScheduled) {
-      return;
-    }
-    this._nextMicrotaskFrameScheduled = true;
-    this._schedule();
-  }
-
-  /**
-   * Does the actual scheduling of the callback.
-   */
-  void _schedule();
-
-  /**
-   * Handles the microtask callback and forwards it if necessary.
-   */
-  void _onCallback() {
-    // Ignore spurious messages.
-    if (!_nextMicrotaskFrameScheduled) {
-      return;
-    }
-    _nextMicrotaskFrameScheduled = false;
-    this._callback();
-  }
-}
-
-/**
- * Scheduler which uses window.postMessage to schedule events.
- */
-class _PostMessageScheduler extends _MicrotaskScheduler {
-  const _MICROTASK_MESSAGE = "DART-MICROTASK";
-
-  _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
-      // Messages from other windows do not cause a security risk as
-      // all we care about is that _handleMessage is called
-      // after the current event loop is unwound and calling the function is
-      // a noop when zero requests are pending.
-      window.onMessage.listen(this._handleMessage);
-  }
-
-  void _schedule() {
-    window.postMessage(_MICROTASK_MESSAGE, "*");
-  }
-
-  void _handleMessage(e) {
-    this._onCallback();
-  }
-}
-
-/**
- * Scheduler which uses a MutationObserver to schedule events.
- */
-class _MutationObserverScheduler extends _MicrotaskScheduler {
-  MutationObserver _observer;
-  Element _dummy;
-
-  _MutationObserverScheduler(_MicrotaskCallback callback): super(callback) {
-    // Mutation events get fired as soon as the current event stack is unwound
-    // so we just make a dummy event and listen for that.
-    _observer = new MutationObserver(this._handleMutation);
-    _dummy = new DivElement();
-    _observer.observe(_dummy, attributes: true);
-  }
-
-  void _schedule() {
-    // Toggle it to trigger the mutation event.
-    _dummy.hidden = !_dummy.hidden;
-  }
-
-  _handleMutation(List<MutationRecord> mutations, MutationObserver observer) {
-    this._onCallback();
-  }
-}
-
-/**
- * Scheduler which uses window.setImmediate to schedule events.
- */
-class _SetImmediateScheduler extends _MicrotaskScheduler {
-  _SetImmediateScheduler(_MicrotaskCallback callback): super(callback);
-
-  void _schedule() {
-    window._setImmediate(_handleImmediate);
-  }
-
-  void _handleImmediate() {
-    this._onCallback();
-  }
-}
-
-List<TimeoutHandler> _pendingMicrotasks;
-_MicrotaskScheduler _microtaskScheduler = null;
-
-void _maybeScheduleMicrotaskFrame() {
-  if (_microtaskScheduler == null) {
-    _microtaskScheduler =
-      new _MicrotaskScheduler.best(_completeMicrotasks);
-  }
-  _microtaskScheduler.maybeSchedule();
-}
-
-/**
- * Registers a [callback] which is called after the current execution stack
- * unwinds.
- */
-void _addMicrotaskCallback(TimeoutHandler callback) {
-  if (_pendingMicrotasks == null) {
-    _pendingMicrotasks = <TimeoutHandler>[];
-    _maybeScheduleMicrotaskFrame();
-  }
-  _pendingMicrotasks.add(callback);
-}
-
-
-/**
- * Complete all pending microtasks.
- */
-void _completeMicrotasks() {
-  var callbacks = _pendingMicrotasks;
-  _pendingMicrotasks = null;
-  for (var callback in callbacks) {
-    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.
-
 // Patch file for the dart:isolate library.
 
 
@@ -30614,7 +31558,7 @@
 
   String get type => wrapped.type;
 
-  void $dom_initEvent(String eventTypeArg, bool canBubbleArg,
+  void _initEvent(String eventTypeArg, bool canBubbleArg,
       bool cancelableArg) {
     throw new UnsupportedError(
         'Cannot initialize this Event.');
@@ -30712,6 +31656,89 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+class _HttpRequestUtils {
+
+  // Helper for factory HttpRequest.get
+  static HttpRequest get(String url,
+                            onComplete(HttpRequest request),
+                            bool withCredentials) {
+    final request = new HttpRequest();
+    request.open('GET', url, async: true);
+
+    request.withCredentials = withCredentials;
+
+    request.onReadyStateChange.listen((e) {
+      if (request.readyState == HttpRequest.DONE) {
+        onComplete(request);
+      }
+    });
+
+    request.send();
+
+    return request;
+  }
+}
+// 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.
+
+
+// Iterator for arrays with fixed size.
+class FixedSizeListIterator<T> implements Iterator<T> {
+  final List<T> _array;
+  final int _length;  // Cache array length for faster access.
+  int _position;
+  T _current;
+  
+  FixedSizeListIterator(List<T> array)
+      : _array = array,
+        _position = -1,
+        _length = array.length;
+
+  bool moveNext() {
+    int nextPosition = _position + 1;
+    if (nextPosition < _length) {
+      _current = _array[nextPosition];
+      _position = nextPosition;
+      return true;
+    }
+    _current = null;
+    _position = _length;
+    return false;
+  }
+
+  T get current => _current;
+}
+
+// Iterator for arrays with variable size.
+class _VariableSizeListIterator<T> implements Iterator<T> {
+  final List<T> _array;
+  int _position;
+  T _current;
+
+  _VariableSizeListIterator(List<T> array)
+      : _array = array,
+        _position = -1;
+
+  bool moveNext() {
+    int nextPosition = _position + 1;
+    if (nextPosition < _array.length) {
+      _current = _array[nextPosition];
+      _position = nextPosition;
+      return true;
+    }
+    _current = null;
+    _position = _array.length;
+    return false;
+  }
+
+  T get current => _current;
+}
+// Copyright (c) 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.
+
+
 // Conversions for Window.  These check if the window is the local
 // window, and if it's not, wraps or unwraps it with a secure wrapper.
 // We need to test for EventTarget here as well as it's a base type.
@@ -30755,8 +31782,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-_callOnCreated(receiver) {
-  return receiver.onCreated();
+_callCreated(receiver) {
+  return receiver.created();
 }
 
 _makeCreatedCallbackMethod() {
@@ -30766,7 +31793,7 @@
                return invokeCallback(this);
              };
           })(#))''',
-      convertDartClosureToJS(_callOnCreated, 1));
+      convertDartClosureToJS(_callCreated, 1));
 }
 
 void _registerCustomElement(context, document, String tag, Type type) {
@@ -31000,18 +32027,18 @@
   /** True if the shift key was pressed during this event. */
   bool get shiftKey => _parent.shiftKey;
   Window get view => _parent.view;
-  void $dom_initUIEvent(String type, bool canBubble, bool cancelable,
+  void _initUIEvent(String type, bool canBubble, bool cancelable,
       Window view, int detail) {
     throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
   }
   String get _shadowKeyIdentifier => JS('String', '#.keyIdentifier', _parent);
 
-  int get $dom_charCode => charCode;
-  int get $dom_keyCode => keyCode;
-  String get $dom_keyIdentifier {
+  int get _charCode => charCode;
+  int get _keyCode => keyCode;
+  String get _keyIdentifier {
     throw new UnsupportedError("keyIdentifier is unsupported.");
   }
-  void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
+  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
       Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
       bool altKey, bool shiftKey, bool metaKey,
       bool altGraphKey) {
@@ -31140,59 +32167,207 @@
     }
   }
 }
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 
-// Iterator for arrays with fixed size.
-class FixedSizeListIterator<T> implements Iterator<T> {
-  final List<T> _array;
-  final int _length;  // Cache array length for faster access.
-  int _position;
-  T _current;
-  
-  FixedSizeListIterator(List<T> array)
-      : _array = array,
-        _position = -1,
-        _length = array.length;
 
-  bool moveNext() {
-    int nextPosition = _position + 1;
-    if (nextPosition < _length) {
-      _current = _array[nextPosition];
-      _position = nextPosition;
-      return true;
-    }
-    _current = null;
-    _position = _length;
-    return false;
-  }
+/**
+ * Interface used to validate that only accepted elements and attributes are
+ * allowed while parsing HTML strings into DOM nodes.
+ *
+ * In general, customization of validation behavior should be done via the
+ * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
+ * implementing validation rules.
+ */
+abstract class NodeValidator {
 
-  T get current => _current;
+  /**
+   * Construct a default NodeValidator which only accepts whitelisted HTML5
+   * elements and attributes.
+   *
+   * If a uriPolicy is not specified then the default uriPolicy will be used.
+   */
+  factory NodeValidator({UriPolicy uriPolicy}) =>
+      new _Html5NodeValidator(uriPolicy: uriPolicy);
+
+  factory NodeValidator.throws(NodeValidator base) =>
+      new _ThrowsNodeValidator(base);
+
+  /**
+   * Returns true if the tagName is an accepted type.
+   */
+  bool allowsElement(Element element);
+
+  /**
+   * Returns true if the attribute is allowed.
+   *
+   * The attributeName parameter will always be in lowercase.
+   *
+   * See [allowsElement] for format of tagName.
+   */
+  bool allowsAttribute(Element element, String attributeName, String value);
 }
 
-// Iterator for arrays with variable size.
-class _VariableSizeListIterator<T> implements Iterator<T> {
-  final List<T> _array;
-  int _position;
-  T _current;
+/**
+ * Performs sanitization of a node tree after construction to ensure that it
+ * does not contain any disallowed elements or attributes.
+ *
+ * In general custom implementations of this class should not be necessary and
+ * all validation customization should be done in custom NodeValidators, but
+ * custom implementations of this class can be created to perform more complex
+ * tree sanitization.
+ */
+abstract class NodeTreeSanitizer {
 
-  _VariableSizeListIterator(List<T> array)
-      : _array = array,
-        _position = -1;
+  /**
+   * Constructs a default tree sanitizer which will remove all elements and
+   * attributes which are not allowed by the provided validator.
+   */
+  factory NodeTreeSanitizer(NodeValidator validator) =>
+      new _ValidatingTreeSanitizer(validator);
 
-  bool moveNext() {
-    int nextPosition = _position + 1;
-    if (nextPosition < _array.length) {
-      _current = _array[nextPosition];
-      _position = nextPosition;
-      return true;
+  /**
+   * Called with the root of the tree which is to be sanitized.
+   *
+   * This method needs to walk the entire tree and either remove elements and
+   * attributes which are not recognized as safe or throw an exception which
+   * will mark the entire tree as unsafe.
+   */
+  void sanitizeTree(Node node);
+}
+
+/**
+ * Defines the policy for what types of uris are allowed for particular
+ * attribute values.
+ *
+ * This can be used to provide custom rules such as allowing all http:// URIs
+ * for image attributes but only same-origin URIs for anchor tags.
+ */
+abstract class UriPolicy {
+  /**
+   * Constructs the default UriPolicy which is to only allow Uris to the same
+   * origin as the application was launched from.
+   *
+   * This will block all ftp: mailto: URIs. It will also block accessing
+   * https://example.com if the app is running from http://example.com.
+   */
+  factory UriPolicy() => new _SameOriginUriPolicy();
+
+  /**
+   * Checks if the uri is allowed on the specified attribute.
+   *
+   * The uri provided may or may not be a relative path.
+   */
+  bool allowsUri(String uri);
+}
+
+/**
+ * Allows URIs to the same origin as the current application was loaded from
+ * (such as https://example.com:80).
+ */
+class _SameOriginUriPolicy implements UriPolicy {
+  final AnchorElement _hiddenAnchor = new AnchorElement();
+  final Location _loc = window.location;
+
+  bool allowsUri(String uri) {
+    _hiddenAnchor.href = uri;
+    // IE leaves an empty hostname for same-origin URIs.
+    return (_hiddenAnchor.hostname == _loc.hostname &&
+        _hiddenAnchor.port == _loc.port &&
+        _hiddenAnchor.protocol == _loc.protocol) ||
+        (_hiddenAnchor.hostname == '' &&
+        _hiddenAnchor.port == '' &&
+        _hiddenAnchor.protocol == ':');
+  }
+}
+
+
+class _ThrowsNodeValidator implements NodeValidator {
+  final NodeValidator validator;
+
+  _ThrowsNodeValidator(this.validator) {}
+
+  bool allowsElement(Element element) {
+    if (!validator.allowsElement(element)) {
+      throw new ArgumentError(element.tagName);
     }
-    _current = null;
-    _position = _array.length;
-    return false;
+    return true;
   }
 
-  T get current => _current;
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (!validator.allowsAttribute(element, attributeName, value)) {
+      throw new ArgumentError('${element.tagName}[$attributeName="$value"]');
+    }
+  }
+}
+
+
+/**
+ * Standard tree sanitizer which validates a node tree against the provided
+ * validator and removes any nodes or attributes which are not allowed.
+ */
+class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
+  NodeValidator validator;
+  _ValidatingTreeSanitizer(this.validator) {}
+
+  void sanitizeTree(Node node) {
+    void walk(Node node) {
+      sanitizeNode(node);
+
+      var child = node.lastChild;
+      while (child != null) {
+        // Child may be removed during the walk.
+        var nextChild = child.previousNode;
+        walk(child);
+        child = nextChild;
+      }
+    }
+    walk(node);
+  }
+
+  void sanitizeNode(Node node) {
+    switch (node.nodeType) {
+      case Node.ELEMENT_NODE:
+        Element element = node;
+        var attrs = element.attributes;
+        if (!validator.allowsElement(element)) {
+          element.remove();
+          break;
+        }
+
+        var isAttr = attrs['is'];
+        if (isAttr != null) {
+          if (!validator.allowsAttribute(element, 'is', isAttr)) {
+            element.remove();
+            break;
+          }
+        }
+
+        // TODO(blois): Need to be able to get all attributes, irrespective of
+        // XMLNS.
+        var keys = attrs.keys.toList();
+        for (var i = attrs.length - 1; i >= 0; --i) {
+          var name = keys[i];
+          if (!validator.allowsAttribute(element, name.toLowerCase(),
+              attrs[name])) {
+            attrs.remove(name);
+          }
+        }
+
+        if (element is TemplateElement) {
+          TemplateElement template = element;
+          sanitizeTree(template.content);
+        }
+        break;
+      case Node.COMMENT_NODE:
+      case Node.DOCUMENT_FRAGMENT_NODE:
+      case Node.TEXT_NODE:
+      case Node.CDATA_SECTION_NODE:
+        break;
+      default:
+        node.remove();
+    }
+  }
 }
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 1fe8297..bd228d2 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -1109,49 +1109,9 @@
   @DocsEditable()
   CanvasRenderingContext getContext(String contextId, [Map attrs]) native "HTMLCanvasElement_getContext_Callback";
 
-  /**
-   * Returns a data URI containing a representation of the image in the
-   * format specified by type (defaults to 'image/png').
-   *
-   * Data Uri format is as follow `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
-   *
-   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when requesting [type]
-   * 'image/jpeg' or 'image/webp'. If [quality] is not passed the default
-   * value is used. Note: the default value varies by browser.
-   *
-   * If the height or width of this canvas element is 0, then 'data:' is returned,
-   * representing no data.
-   *
-   * If the type requested is not 'image/png', and the returned value is
-   * 'data:image/png', then the requested type is not supported.
-   *
-   * Example usage:
-   *
-   *     CanvasElement canvas = new CanvasElement();
-   *     var ctx = canvas.context2D
-   *     ..fillStyle = "rgb(200,0,0)"
-   *     ..fillRect(10, 10, 55, 50);
-   *     var dataUrl = canvas.toDataUrl("image/jpeg", 0.95);
-   *     // The Data Uri would look similar to
-   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
-   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
-   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
-   *     //Create a new image element from the data URI.
-   *     var img = new ImageElement();
-   *     img.src = dataUrl;
-   *     document.body.children.add(img);
-   *
-   * See also:
-   *
-   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
-   *
-   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
-   *
-   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
-   */
   @DomName('HTMLCanvasElement.toDataURL')
   @DocsEditable()
-  String $dom_toDataUrl(String type, [num quality]) native "HTMLCanvasElement_toDataURL_Callback";
+  String _toDataUrl(String type, [num quality]) native "HTMLCanvasElement_toDataURL_Callback";
 
   @DomName('HTMLCanvasElement.onwebglcontextlost')
   @DocsEditable()
@@ -1188,8 +1148,49 @@
     return context;
   }
 
-  String toDataUrl([String type = 'image/png', num quality]) => 
-      $dom_toDataUrl(type, quality);
+  /**
+   * Returns a data URI containing a representation of the image in the
+   * format specified by type (defaults to 'image/png').
+   *
+   * Data Uri format is as follow
+   * `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
+   *
+   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when
+   * requesting [type] 'image/jpeg' or 'image/webp'. If [quality] is not passed
+   * the default value is used. Note: the default value varies by browser.
+   *
+   * If the height or width of this canvas element is 0, then 'data:' is
+   * returned, representing no data.
+   *
+   * If the type requested is not 'image/png', and the returned value is
+   * 'data:image/png', then the requested type is not supported.
+   *
+   * Example usage:
+   *
+   *     CanvasElement canvas = new CanvasElement();
+   *     var ctx = canvas.context2D
+   *     ..fillStyle = "rgb(200,0,0)"
+   *     ..fillRect(10, 10, 55, 50);
+   *     var dataUrl = canvas.toDataUrl("image/jpeg", 0.95);
+   *     // The Data Uri would look similar to
+   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
+   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
+   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
+   *     //Create a new image element from the data URI.
+   *     var img = new ImageElement();
+   *     img.src = dataUrl;
+   *     document.body.children.add(img);
+   *
+   * See also:
+   *
+   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
+   *
+   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
+   *
+   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
+   */
+  String toDataUrl([String type = 'image/png', num quality]) =>
+      _toDataUrl(type, quality);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -1476,7 +1477,7 @@
 
   @DomName('CanvasRenderingContext2D.arc')
   @DocsEditable()
-  void $dom_arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native "CanvasRenderingContext2D_arc_Callback";
+  void _arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native "CanvasRenderingContext2D_arc_Callback";
 
   @DomName('CanvasRenderingContext2D.arcTo')
   @DocsEditable()
@@ -1832,7 +1833,7 @@
   @DomName('CanvasRenderingContext2D.arc')
   void arc(num x,  num y,  num radius,  num startAngle, num endAngle,
       [bool anticlockwise = false]) {
-    $dom_arc(x, y, radius, startAngle, endAngle, anticlockwise);
+    _arc(x, y, radius, startAngle, endAngle, anticlockwise);
   }
 
   /**
@@ -2178,8 +2179,8 @@
     if (view == null) {
       view = window;
     }
-    var e = document.$dom_createEvent("CompositionEvent");
-    e.$dom_initCompositionEvent(type, canBubble, cancelable, view, data);
+    var e = document._createEvent("CompositionEvent");
+    e._initCompositionEvent(type, canBubble, cancelable, view, data);
     return e;
   }
   // To suppress missing implicit constructor warnings.
@@ -2191,7 +2192,7 @@
 
   @DomName('CompositionEvent.initCompositionEvent')
   @DocsEditable()
-  void $dom_initCompositionEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window 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
@@ -6828,9 +6829,9 @@
   factory CustomEvent(String type,
       {bool canBubble: true, bool cancelable: true, Object detail}) {
 
-    final CustomEvent e = document.$dom_createEvent('CustomEvent');
+    final CustomEvent e = document._createEvent('CustomEvent');
 
-    e.$dom_initCustomEvent(type, canBubble, cancelable, detail);
+    e._initCustomEvent(type, canBubble, cancelable, detail);
 
     return e;
   }
@@ -6843,7 +6844,7 @@
 
   @DomName('CustomEvent.initCustomEvent')
   @DocsEditable()
-  void $dom_initCustomEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object detailArg) native "CustomEvent_initCustomEvent_Callback";
+  void _initCustomEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object detailArg) native "CustomEvent_initCustomEvent_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -7203,8 +7204,8 @@
   factory DeviceOrientationEvent(String type,
       {bool canBubble: true, bool cancelable: true, num alpha: 0, num beta: 0,
       num gamma: 0, bool absolute: false}) {
-    var e = document.$dom_createEvent("DeviceOrientationEvent");
-    e.$dom_initDeviceOrientationEvent(type, canBubble, cancelable, alpha, beta,
+    var e = document._createEvent("DeviceOrientationEvent");
+    e._initDeviceOrientationEvent(type, canBubble, cancelable, alpha, beta,
         gamma, absolute);
     return e;
   }
@@ -7229,7 +7230,7 @@
 
   @DomName('DeviceOrientationEvent.initDeviceOrientationEvent')
   @DocsEditable()
-  void $dom_initDeviceOrientationEvent(String type, bool bubbles, bool cancelable, num alpha, num beta, num gamma, bool absolute) native "DeviceOrientationEvent_initDeviceOrientationEvent_Callback";
+  void _initDeviceOrientationEvent(String type, bool bubbles, bool cancelable, num alpha, num beta, num gamma, bool absolute) native "DeviceOrientationEvent_initDeviceOrientationEvent_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -7510,15 +7511,13 @@
   // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-onpointerlockerror
   static const EventStreamProvider<Event> pointerLockErrorEvent = const EventStreamProvider<Event>('webkitpointerlockerror');
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.body')
   @DocsEditable()
-  HtmlElement get $dom_body native "Document_body_Getter";
+  HtmlElement get _body native "Document_body_Getter";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.body')
   @DocsEditable()
-  void set $dom_body(HtmlElement value) native "Document_body_Setter";
+  void set _body(HtmlElement value) native "Document_body_Setter";
 
   @DomName('Document.charset')
   @DocsEditable()
@@ -7561,32 +7560,29 @@
   @Experimental()
   FontLoader get fontloader native "Document_fontloader_Getter";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.head')
   @DocsEditable()
-  HeadElement get $dom_head native "Document_head_Getter";
+  HeadElement get _head native "Document_head_Getter";
 
   @DomName('Document.implementation')
   @DocsEditable()
   DomImplementation get implementation native "Document_implementation_Getter";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.lastModified')
   @DocsEditable()
-  String get $dom_lastModified native "Document_lastModified_Getter";
+  String get _lastModified native "Document_lastModified_Getter";
 
   @DomName('Document.preferredStylesheetSet')
   @DocsEditable()
-  String get $dom_preferredStylesheetSet native "Document_preferredStylesheetSet_Getter";
+  String get _preferredStylesheetSet native "Document_preferredStylesheetSet_Getter";
 
   @DomName('Document.readyState')
   @DocsEditable()
   String get readyState native "Document_readyState_Getter";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.referrer')
   @DocsEditable()
-  String get $dom_referrer native "Document_referrer_Getter";
+  String get _referrer native "Document_referrer_Getter";
 
   @DomName('Document.securityPolicy')
   @DocsEditable()
@@ -7596,55 +7592,48 @@
 
   @DomName('Document.selectedStylesheetSet')
   @DocsEditable()
-  String get $dom_selectedStylesheetSet native "Document_selectedStylesheetSet_Getter";
+  String get _selectedStylesheetSet native "Document_selectedStylesheetSet_Getter";
 
   @DomName('Document.selectedStylesheetSet')
   @DocsEditable()
-  void set $dom_selectedStylesheetSet(String value) native "Document_selectedStylesheetSet_Setter";
+  void set _selectedStylesheetSet(String value) native "Document_selectedStylesheetSet_Setter";
 
-  /// Moved to [HtmlDocument]
   @DomName('Document.styleSheets')
   @DocsEditable()
-  List<StyleSheet> get $dom_styleSheets native "Document_styleSheets_Getter";
+  List<StyleSheet> get _styleSheets native "Document_styleSheets_Getter";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.title')
   @DocsEditable()
-  String get $dom_title native "Document_title_Getter";
+  String get _title native "Document_title_Getter";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.title')
   @DocsEditable()
-  void set $dom_title(String value) native "Document_title_Setter";
+  void set _title(String value) native "Document_title_Setter";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitFullscreenElement')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-fullscreenelement
-  Element get $dom_webkitFullscreenElement native "Document_webkitFullscreenElement_Getter";
+  Element get _webkitFullscreenElement native "Document_webkitFullscreenElement_Getter";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitFullscreenEnabled')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-fullscreenenabled
-  bool get $dom_webkitFullscreenEnabled native "Document_webkitFullscreenEnabled_Getter";
+  bool get _webkitFullscreenEnabled native "Document_webkitFullscreenEnabled_Getter";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitHidden')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#document
-  bool get $dom_webkitHidden native "Document_webkitHidden_Getter";
+  bool get _webkitHidden native "Document_webkitHidden_Getter";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitIsFullScreen')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -7652,16 +7641,15 @@
   @Experimental()
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
   @deprecated // deprecated
-  bool get $dom_webkitIsFullScreen native "Document_webkitIsFullScreen_Getter";
+  bool get _webkitIsFullScreen native "Document_webkitIsFullScreen_Getter";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitPointerLockElement')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-pointerLockElement
-  Element get $dom_webkitPointerLockElement native "Document_webkitPointerLockElement_Getter";
+  Element get _webkitPointerLockElement native "Document_webkitPointerLockElement_Getter";
 
   @DomName('Document.webkitVisibilityState')
   @DocsEditable()
@@ -7669,18 +7657,17 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#dom-document-visibilitystate
-  String get $dom_webkitVisibilityState native "Document_webkitVisibilityState_Getter";
+  String get _webkitVisibilityState native "Document_webkitVisibilityState_Getter";
 
   @DomName('Document.adoptNode')
   @DocsEditable()
   Node adoptNode(Node source) native "Document_adoptNode_Callback";
 
-  /// Use the [Range] constructor instead.
   @DomName('Document.caretRangeFromPoint')
   @DocsEditable()
   // http://www.w3.org/TR/2009/WD-cssom-view-20090804/#dom-documentview-caretrangefrompoint
   @Experimental()
-  Range $dom_caretRangeFromPoint(int x, int y) native "Document_caretRangeFromPoint_Callback";
+  Range _caretRangeFromPoint(int x, int y) native "Document_caretRangeFromPoint_Callback";
 
   @DomName('Document.createCDATASection')
   @DocsEditable()
@@ -7722,9 +7709,9 @@
 
   @DomName('Document.createEvent')
   @DocsEditable()
-  Event $dom_createEvent(String eventType) native "Document_createEvent_Callback";
+  Event _createEvent(String eventType) native "Document_createEvent_Callback";
 
-  NodeIterator $dom_createNodeIterator(Node root, [int whatToShow, NodeFilter filter, bool expandEntityReferences]) {
+  NodeIterator _createNodeIterator(Node root, [int whatToShow, NodeFilter filter, bool expandEntityReferences]) {
     if (expandEntityReferences != null) {
       return _createNodeIterator_1(root, whatToShow, filter, expandEntityReferences);
     }
@@ -7751,22 +7738,21 @@
 
   @DomName('Document.createTextNode')
   @DocsEditable()
-  Text $dom_createTextNode(String data) native "Document_createTextNode_Callback";
+  Text _createTextNode(String data) native "Document_createTextNode_Callback";
 
   @DomName('Document.createTouch')
   @DocsEditable()
   // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
   @Experimental()
-  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";
+  Touch _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";
 
-  /// Use the [TouchList] constructor instead.
   @DomName('Document.createTouchList')
   @DocsEditable()
   // http://www.w3.org/TR/touch-events/, http://www.chromestatus.com/features
   @Experimental()
-  TouchList $dom_createTouchList() native "Document_createTouchList_Callback";
+  TouchList _createTouchList() native "Document_createTouchList_Callback";
 
-  TreeWalker $dom_createTreeWalker(Node root, [int whatToShow, NodeFilter filter, bool expandEntityReferences]) {
+  TreeWalker _createTreeWalker(Node root, [int whatToShow, NodeFilter filter, bool expandEntityReferences]) {
     if (expandEntityReferences != null) {
       return _createTreeWalker_1(root, whatToShow, filter, expandEntityReferences);
     }
@@ -7789,18 +7775,17 @@
 
   @DomName('Document.elementFromPoint')
   @DocsEditable()
-  Element $dom_elementFromPoint(int x, int y) native "Document_elementFromPoint_Callback";
+  Element _elementFromPoint(int x, int y) native "Document_elementFromPoint_Callback";
 
   @DomName('Document.execCommand')
   @DocsEditable()
   bool execCommand(String command, bool userInterface, String value) native "Document_execCommand_Callback";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.getCSSCanvasContext')
   @DocsEditable()
   // https://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariCSSRef/Articles/Functions.html
   @Experimental() // non-standard
-  CanvasRenderingContext $dom_getCssCanvasContext(String contextId, String name, int width, int height) native "Document_getCSSCanvasContext_Callback";
+  CanvasRenderingContext _getCssCanvasContext(String contextId, String name, int width, int height) native "Document_getCSSCanvasContext_Callback";
 
   @DomName('Document.getElementById')
   @DocsEditable()
@@ -7868,12 +7853,10 @@
   @DocsEditable()
   Element query(String selectors) native "Document_querySelector_Callback";
 
-  /// Deprecated: use query("#$elementId") instead.
   @DomName('Document.querySelectorAll')
   @DocsEditable()
-  List<Node> $dom_querySelectorAll(String selectors) native "Document_querySelectorAll_Callback";
+  List<Node> _querySelectorAll(String selectors) native "Document_querySelectorAll_Callback";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitCancelFullScreen')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -7881,25 +7864,23 @@
   @Experimental()
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
   @deprecated // deprecated
-  void $dom_webkitCancelFullScreen() native "Document_webkitCancelFullScreen_Callback";
+  void _webkitCancelFullScreen() native "Document_webkitCancelFullScreen_Callback";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitExitFullscreen')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-document-exitfullscreen
-  void $dom_webkitExitFullscreen() native "Document_webkitExitFullscreen_Callback";
+  void _webkitExitFullscreen() native "Document_webkitExitFullscreen_Callback";
 
-  /// Moved to [HtmlDocument].
   @DomName('Document.webkitExitPointerLock')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // https://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html#widl-Document-exitPointerLock-void
-  void $dom_webkitExitPointerLock() native "Document_webkitExitPointerLock_Callback";
+  void _webkitExitPointerLock() native "Document_webkitExitPointerLock_Callback";
 
   @DomName('Document.webkitGetNamedFlows')
   @DocsEditable()
@@ -7911,19 +7892,19 @@
 
   @DomName('Document.childElementCount')
   @DocsEditable()
-  int get $dom_childElementCount native "Document_childElementCount_Getter";
+  int get _childElementCount native "Document_childElementCount_Getter";
 
   @DomName('Document.children')
   @DocsEditable()
-  HtmlCollection get $dom_children native "Document_children_Getter";
+  HtmlCollection get _children native "Document_children_Getter";
 
   @DomName('Document.firstElementChild')
   @DocsEditable()
-  Element get $dom_firstElementChild native "Document_firstElementChild_Getter";
+  Element get _firstElementChild native "Document_firstElementChild_Getter";
 
   @DomName('Document.lastElementChild')
   @DocsEditable()
-  Element get $dom_lastElementChild native "Document_lastElementChild_Getter";
+  Element get _lastElementChild native "Document_lastElementChild_Getter";
 
   @DomName('Document.onabort')
   @DocsEditable()
@@ -8171,7 +8152,7 @@
    * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
    */
   ElementList queryAll(String selectors) {
-    return new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
+    return new _FrozenElementList._wrap(_querySelectorAll(selectors));
   }
 
   /// Checks if [register] is supported on the current platform.
@@ -8188,21 +8169,18 @@
 class DocumentFragment extends Node implements ParentNode {
   factory DocumentFragment() => document.createDocumentFragment();
 
-  factory DocumentFragment.html(String html) {
-    final fragment = new DocumentFragment();
-    fragment.innerHtml = html;
-    return fragment;
+  factory DocumentFragment.html(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+
+    return document.body.createFragment(html,
+      validator: validator, treeSanitizer: treeSanitizer);
   }
 
-  factory DocumentFragment.svg(String svgContent) {
-    final fragment = new DocumentFragment();
-    final e = new svg.SvgSvgElement();
-    e.innerHtml = svgContent;
+  factory DocumentFragment.svg(String svgContent,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
 
-    // Copy list first since we don't want liveness during iteration.
-    final List nodes = new List.from(e.nodes);
-    fragment.nodes.addAll(nodes);
-    return fragment;
+    return new svg.SvgSvgElement().createFragment(svgContent,
+        validator: validator, treeSanitizer: treeSanitizer);
   }
 
   List<Element> _children;
@@ -8222,10 +8200,10 @@
     children.addAll(copy);
   }
 
-  Element query(String selectors) => $dom_querySelector(selectors);
+  Element query(String selectors) => _querySelector(selectors);
 
   List<Element> queryAll(String selectors) =>
-    new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
+    new _FrozenElementList._wrap(_querySelectorAll(selectors));
 
   String get innerHtml {
     final e = new Element.tag("div");
@@ -8233,17 +8211,16 @@
     return e.innerHtml;
   }
 
-  // TODO(nweiz): Do we want to support some variant of innerHtml for XML and/or
-  // SVG strings?
   void set innerHtml(String value) {
+    this.setInnerHtml(value);
+  }
+
+  void setInnerHtml(String html,
+    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+
     this.nodes.clear();
-
-    final e = new Element.tag("div");
-    e.innerHtml = value;
-
-    // Copy list first since we don't want liveness during iteration.
-    List nodes = new List.from(e.nodes, growable: false);
-    this.nodes.addAll(nodes);
+    append(document.body.createFragment(
+        html, validator: validator, treeSanitizer: treeSanitizer));
   }
 
   /**
@@ -8268,23 +8245,23 @@
 
   @DomName('DocumentFragment.querySelector')
   @DocsEditable()
-  Element $dom_querySelector(String selectors) native "DocumentFragment_querySelector_Callback";
+  Element _querySelector(String selectors) native "DocumentFragment_querySelector_Callback";
 
   @DomName('DocumentFragment.querySelectorAll')
   @DocsEditable()
-  List<Node> $dom_querySelectorAll(String selectors) native "DocumentFragment_querySelectorAll_Callback";
+  List<Node> _querySelectorAll(String selectors) native "DocumentFragment_querySelectorAll_Callback";
 
   @DomName('DocumentFragment.childElementCount')
   @DocsEditable()
-  int get $dom_childElementCount native "DocumentFragment_childElementCount_Getter";
+  int get _childElementCount native "DocumentFragment_childElementCount_Getter";
 
   @DomName('DocumentFragment.firstElementChild')
   @DocsEditable()
-  Element get $dom_firstElementChild native "DocumentFragment_firstElementChild_Getter";
+  Element get _firstElementChild native "DocumentFragment_firstElementChild_Getter";
 
   @DomName('DocumentFragment.lastElementChild')
   @DocsEditable()
-  Element get $dom_lastElementChild native "DocumentFragment_lastElementChild_Getter";
+  Element get _lastElementChild native "DocumentFragment_lastElementChild_Getter";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -8596,14 +8573,14 @@
   final HtmlCollection _childElements;
 
   _ChildrenElementList._wrap(Element element)
-    : _childElements = element.$dom_children,
+    : _childElements = element._children,
       _element = element;
 
   bool contains(Object element) => _childElements.contains(element);
 
 
   bool get isEmpty {
-    return _element.$dom_firstElementChild == null;
+    return _element._firstElementChild == null;
   }
 
   int get length {
@@ -8615,7 +8592,7 @@
   }
 
   void operator []=(int index, Element value) {
-    _element.$dom_replaceChild(value, _childElements[index]);
+    _element._replaceChild(value, _childElements[index]);
   }
 
   void set length(int newLength) {
@@ -8679,7 +8656,7 @@
     if (object is Element) {
       Element element = object;
       if (identical(element.parentNode, _element)) {
-        _element.$dom_removeChild(element);
+        _element._removeChild(element);
         return true;
       }
     }
@@ -8709,7 +8686,7 @@
   Element removeAt(int index) {
     final result = this[index];
     if (result != null) {
-      _element.$dom_removeChild(result);
+      _element._removeChild(result);
     }
     return result;
   }
@@ -8717,20 +8694,20 @@
   Element removeLast() {
     final result = this.last;
     if (result != null) {
-      _element.$dom_removeChild(result);
+      _element._removeChild(result);
     }
     return result;
   }
 
   Element get first {
-    Element result = _element.$dom_firstElementChild;
+    Element result = _element._firstElementChild;
     if (result == null) throw new StateError("No elements");
     return result;
   }
 
 
   Element get last {
-    Element result = _element.$dom_lastElementChild;
+    Element result = _element._lastElementChild;
     if (result == null) throw new StateError("No elements");
     return result;
   }
@@ -9350,20 +9327,31 @@
   /**
    * Creates an HTML element from a valid fragment of HTML.
    *
-   * The [html] fragment must represent valid HTML with a single element root,
-   * which will be parsed and returned.
-   *
-   * Important: the contents of [html] should not contain any user-supplied
-   * data. Without strict data validation it is impossible to prevent script
-   * injection exploits.
-   *
-   * It is instead recommended that elements be constructed via [Element.tag]
-   * and text be added via [text].
-   *
    *     var element = new Element.html('<div class="foo">content</div>');
+   *
+   * The HTML fragment should contain only one single root element, any
+   * leading or trailing text nodes will be removed.
+   *
+   * The HTML fragment is parsed as if it occurred within the context of a
+   * `<body>` tag, this means that special elements such as `<caption>` which
+   * must be parsed within the scope of a `<table>` element will be dropped. Use
+   * [createFragment] to parse contextual HTML fragments.
+   *
+   * Unless a validator is provided this will perform the default validation
+   * and remove all scriptable elements and attributes.
+   *
+   * See also:
+   *
+   * * [NodeValidator]
+   *
    */
-  factory Element.html(String html) =>
-      _ElementFactoryProvider.createElement_html(html);
+  factory Element.html(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    var fragment = document.body.createFragment(html, validator: validator,
+        treeSanitizer: treeSanitizer);
+
+    return fragment.nodes.where((e) => e is Element).single;
+  }
 
   /**
    * Creates the HTML element specified by the tag name.
@@ -9583,7 +9571,7 @@
    *     var items = element.query('.itemClassName');
    */
   ElementList queryAll(String selectors) =>
-    new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
+    new _FrozenElementList._wrap(_querySelectorAll(selectors));
 
   /**
    * The set of CSS classes applied to this element.
@@ -9668,7 +9656,7 @@
       pseudoElement = '';
     }
     // TODO(jacobr): last param should be null, see b/5045788
-    return window.$dom_getComputedStyle(this, pseudoElement);
+    return window._getComputedStyle(this, pseudoElement);
   }
 
   /**
@@ -9710,7 +9698,7 @@
    * Called by the DOM when this element has been instantiated.
    */
   @Experimental()
-  void onCreated() {}
+  void created() {}
 
   // Hooks to support custom WebComponents.
 
@@ -9738,11 +9726,11 @@
 
   @DomName('Element.localName')
   @DocsEditable()
-  String get localName => $dom_localName;
+  String get localName => _localName;
 
   @DomName('Element.namespaceUri')
   @DocsEditable()
-  String get namespaceUri => $dom_namespaceUri;
+  String get namespaceUri => _namespaceUri;
 
   String toString() => localName;
 
@@ -9766,17 +9754,17 @@
   void scrollIntoView([ScrollAlignment alignment]) {
     var hasScrollIntoViewIfNeeded = false;
     if (alignment == ScrollAlignment.TOP) {
-      this.$dom_scrollIntoView(true);
+      this._scrollIntoView(true);
     } else if (alignment == ScrollAlignment.BOTTOM) {
-      this.$dom_scrollIntoView(false);
+      this._scrollIntoView(false);
     } else if (hasScrollIntoViewIfNeeded) {
       if (alignment == ScrollAlignment.CENTER) {
-        this.$dom_scrollIntoViewIfNeeded(true);
+        this._scrollIntoViewIfNeeded(true);
       } else {
-        this.$dom_scrollIntoViewIfNeeded();
+        this._scrollIntoViewIfNeeded();
       }
     } else {
-      this.$dom_scrollIntoView();
+      this._scrollIntoView();
     }
   }
 
@@ -10041,6 +10029,128 @@
     return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
   }
 
+  static HtmlDocument _parseDocument;
+  static NodeValidatorBuilder _defaultValidator;
+  static _ValidatingTreeSanitizer _defaultSanitizer;
+
+  /**
+   * Create a DocumentFragment from the HTML fragment and ensure that it follows
+   * the sanitization rules specified by the validator or treeSanitizer.
+   *
+   * If the default validation behavior is too restrictive then a new
+   * NodeValidator should be created, either extending or wrapping a default
+   * validator and overriding the validation APIs.
+   *
+   * The treeSanitizer is used to walk the generated node tree and sanitize it.
+   * A custom treeSanitizer can also be provided to perform special validation
+   * rules but since the API is more complex to implement this is discouraged.
+   *
+   * The returned tree is guaranteed to only contain nodes and attributes which
+   * are allowed by the provided validator.
+   *
+   * See also:
+   *
+   * * [NodeValidator]
+   * * [NodeTreeSanitizer]
+   */
+  DocumentFragment createFragment(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    if (treeSanitizer == null) {
+      if (validator == null) {
+        if (_defaultValidator == null) {
+          _defaultValidator = new NodeValidatorBuilder.common();
+        }
+        validator = _defaultValidator;
+      }
+      if (_defaultSanitizer == null) {
+        _defaultSanitizer = new _ValidatingTreeSanitizer(validator);
+      } else {
+        _defaultSanitizer.validator = validator;
+      }
+      treeSanitizer = _defaultSanitizer;
+    } else if (validator != null) {
+      throw new ArgumentError(
+          'validator can only be passed if treeSanitizer is null');
+    }
+
+    if (_parseDocument == null) {
+      _parseDocument = document.implementation.createHtmlDocument('');
+    }
+    var contextElement;
+    if (this is BodyElement) {
+      contextElement = _parseDocument.body;
+    } else {
+      contextElement = _parseDocument.$dom_createElement(tagName);
+      _parseDocument.body.append(contextElement);
+    }
+    var fragment;
+    if (Range.supportsCreateContextualFragment) {
+      var range = _parseDocument.$dom_createRange();
+      range.selectNodeContents(contextElement);
+      fragment = range.createContextualFragment(html);
+    } else {
+      contextElement._innerHtml = html;
+
+      fragment = _parseDocument.createDocumentFragment();
+      while (contextElement.firstChild != null) {
+        fragment.append(contextElement.firstChild);
+      }
+    }
+    if (contextElement != _parseDocument.body) {
+      contextElement.remove();
+    }
+
+    treeSanitizer.sanitizeTree(fragment);
+    return fragment;
+  }
+
+  /**
+   * Parses the HTML fragment and sets it as the contents of this element.
+   *
+   * This uses the default sanitization behavior to sanitize the HTML fragment,
+   * use [setInnerHtml] to override the default behavior.
+   */
+  void set innerHtml(String html) {
+    this.setInnerHtml(html);
+  }
+
+  /**
+   * Parses the HTML fragment and sets it as the contents of this element.
+   * This ensures that the generated content follows the sanitization rules
+   * specified by the validator or treeSanitizer.
+   *
+   * If the default validation behavior is too restrictive then a new
+   * NodeValidator should be created, either extending or wrapping a default
+   * validator and overriding the validation APIs.
+   *
+   * The treeSanitizer is used to walk the generated node tree and sanitize it.
+   * A custom treeSanitizer can also be provided to perform special validation
+   * rules but since the API is more complex to implement this is discouraged.
+   *
+   * The resulting tree is guaranteed to only contain nodes and attributes which
+   * are allowed by the provided validator.
+   *
+   * See also:
+   *
+   * * [NodeValidator]
+   * * [NodeTreeSanitizer]
+   */
+  void setInnerHtml(String html,
+    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    text = null;
+    append(createFragment(
+        html, validator: validator, treeSanitizer: treeSanitizer));
+  }
+  String get innerHtml => _innerHtml;
+
+  /**
+   * For use while transitioning to the safe [innerHtml] or [setInnerHtml].
+   * Unsafe because it opens the app to cross-site scripting vulnerabilities.
+   */
+  @deprecated
+  void set unsafeInnerHtml(String html) {
+    _innerHtml = html;
+  }
 
   // To suppress missing implicit constructor warnings.
   factory Element._() { throw new UnsupportedError("Not supported"); }
@@ -10280,7 +10390,7 @@
 
   bool hidden;
 
-  String innerHtml;
+  String _innerHtml;
 
   InputMethodContext get inputMethodContext;
 
@@ -10316,7 +10426,7 @@
 
   @DomName('Element.attributes')
   @DocsEditable()
-  _NamedNodeMap get $dom_attributes native "Element_attributes_Getter";
+  _NamedNodeMap get _attributes native "Element_attributes_Getter";
 
   @DomName('Element.className')
   @DocsEditable()
@@ -10468,15 +10578,15 @@
 
   @DomName('Element.getElementsByTagName')
   @DocsEditable()
-  List<Node> $dom_getElementsByTagName(String name) native "Element_getElementsByTagName_Callback";
+  List<Node> _getElementsByTagName(String name) native "Element_getElementsByTagName_Callback";
 
   @DomName('Element.hasAttribute')
   @DocsEditable()
-  bool $dom_hasAttribute(String name) native "Element_hasAttribute_Callback";
+  bool _hasAttribute(String name) native "Element_hasAttribute_Callback";
 
   @DomName('Element.hasAttributeNS')
   @DocsEditable()
-  bool $dom_hasAttributeNS(String namespaceURI, String localName) native "Element_hasAttributeNS_Callback";
+  bool _hasAttributeNS(String namespaceURI, String localName) native "Element_hasAttributeNS_Callback";
 
   /**
  * Finds the first descendant element of this element that matches the
@@ -10501,15 +10611,15 @@
 
   @DomName('Element.querySelectorAll')
   @DocsEditable()
-  List<Node> $dom_querySelectorAll(String selectors) native "Element_querySelectorAll_Callback";
+  List<Node> _querySelectorAll(String selectors) native "Element_querySelectorAll_Callback";
 
   @DomName('Element.removeAttribute')
   @DocsEditable()
-  void $dom_removeAttribute(String name) native "Element_removeAttribute_Callback";
+  void _removeAttribute(String name) native "Element_removeAttribute_Callback";
 
   @DomName('Element.removeAttributeNS')
   @DocsEditable()
-  void $dom_removeAttributeNS(String namespaceURI, String localName) native "Element_removeAttributeNS_Callback";
+  void _removeAttributeNS(String namespaceURI, String localName) native "Element_removeAttributeNS_Callback";
 
   @DomName('Element.scrollByLines')
   @DocsEditable()
@@ -10519,7 +10629,7 @@
   @DocsEditable()
   void scrollByPages(int pages) native "Element_scrollByPages_Callback";
 
-  void $dom_scrollIntoView([bool alignWithTop]) {
+  void _scrollIntoView([bool alignWithTop]) {
     if (alignWithTop != null) {
       _scrollIntoView_1(alignWithTop);
       return;
@@ -10532,7 +10642,7 @@
 
   void _scrollIntoView_2() native "Element__scrollIntoView_2_Callback";
 
-  void $dom_scrollIntoViewIfNeeded([bool centerIfNeeded]) {
+  void _scrollIntoViewIfNeeded([bool centerIfNeeded]) {
     if (centerIfNeeded != null) {
       _scrollIntoViewIfNeeded_1(centerIfNeeded);
       return;
@@ -10606,19 +10716,19 @@
 
   @DomName('Element.childElementCount')
   @DocsEditable()
-  int get $dom_childElementCount native "Element_childElementCount_Getter";
+  int get _childElementCount native "Element_childElementCount_Getter";
 
   @DomName('Element.children')
   @DocsEditable()
-  HtmlCollection get $dom_children native "Element_children_Getter";
+  HtmlCollection get _children native "Element_children_Getter";
 
   @DomName('Element.firstElementChild')
   @DocsEditable()
-  Element get $dom_firstElementChild native "Element_firstElementChild_Getter";
+  Element get _firstElementChild native "Element_firstElementChild_Getter";
 
   @DomName('Element.lastElementChild')
   @DocsEditable()
-  Element get $dom_lastElementChild native "Element_lastElementChild_Getter";
+  Element get _lastElementChild native "Element_lastElementChild_Getter";
 
   @DomName('Element.onabort')
   @DocsEditable()
@@ -10849,119 +10959,8 @@
 
 }
 
-final _START_TAG_REGEXP = new RegExp('<(\\w+)');
+
 class _ElementFactoryProvider {
-  static const _CUSTOM_PARENT_TAG_MAP = const {
-    'body' : 'html',
-    'head' : 'html',
-    'caption' : 'table',
-    'td': 'tr',
-    'th': 'tr',
-    'colgroup': 'table',
-    'col' : 'colgroup',
-    'tr' : 'tbody',
-    'tbody' : 'table',
-    'tfoot' : 'table',
-    'thead' : 'table',
-    'track' : 'audio',
-  };
-
-  @DomName('Document.createElement')
-  static Element createElement_html(String html) {
-    // TODO(jacobr): this method can be made more robust and performant.
-    // 1) Cache the dummy parent elements required to use innerHTML rather than
-    //    creating them every call.
-    // 2) Verify that the html does not contain leading or trailing text nodes.
-    // 3) Verify that the html does not contain both <head> and <body> tags.
-    // 4) Detatch the created element from its dummy parent.
-    String parentTag = 'div';
-    String tag;
-    final match = _START_TAG_REGEXP.firstMatch(html);
-    if (match != null) {
-      tag = match.group(1).toLowerCase();
-      if (Device.isIE && Element._TABLE_TAGS.containsKey(tag)) {
-        return _createTableForIE(html, tag);
-      }
-      parentTag = _CUSTOM_PARENT_TAG_MAP[tag];
-      if (parentTag == null) parentTag = 'div';
-    }
-
-    final temp = new Element.tag(parentTag);
-    temp.innerHtml = html;
-
-    Element element;
-    if (temp.children.length == 1) {
-      element = temp.children[0];
-    } else if (parentTag == 'html' && temp.children.length == 2) {
-      // In html5 the root <html> tag will always have a <body> and a <head>,
-      // even though the inner html only contains one of them.
-      element = temp.children[tag == 'head' ? 0 : 1];
-    } else {
-      _singleNode(temp.children);
-    }
-    element.remove();
-    return element;
-  }
-
-  /**
-   * IE table elements don't support innerHTML (even in standards mode).
-   * Instead we use a div and inject the table element in the innerHtml string.
-   * This technique works on other browsers too, but it's probably slower,
-   * so we only use it when running on IE.
-   *
-   * See also innerHTML:
-   * <http://msdn.microsoft.com/en-us/library/ie/ms533897(v=vs.85).aspx>
-   * and Building Tables Dynamically:
-   * <http://msdn.microsoft.com/en-us/library/ie/ms532998(v=vs.85).aspx>.
-   */
-  static Element _createTableForIE(String html, String tag) {
-    var div = new Element.tag('div');
-    div.innerHtml = '<table>$html</table>';
-    var table = _singleNode(div.children);
-    Element element;
-    switch (tag) {
-      case 'td':
-      case 'th':
-        TableRowElement row = _singleNode(table.rows);
-        element = _singleNode(row.cells);
-        break;
-      case 'tr':
-        element = _singleNode(table.rows);
-        break;
-      case 'tbody':
-        element = _singleNode(table.tBodies);
-        break;
-      case 'thead':
-        element = table.tHead;
-        break;
-      case 'tfoot':
-        element = table.tFoot;
-        break;
-      case 'caption':
-        element = table.caption;
-        break;
-      case 'colgroup':
-        element = _getColgroup(table);
-        break;
-      case 'col':
-        element = _singleNode(_getColgroup(table).children);
-        break;
-    }
-    element.remove();
-    return element;
-  }
-
-  static TableColElement _getColgroup(TableElement table) {
-    // TODO(jmesserly): is there a better way to do this?
-    return _singleNode(table.children.where((n) => n.tagName == 'COLGROUP')
-        .toList());
-  }
-
-  static Node _singleNode(List<Node> list) {
-    if (list.length == 1) return list[0];
-    throw new ArgumentError('HTML had ${list.length} '
-        'top level elements but 1 expected');
-  }
 
   @DomName('Document.createElement')
   static Element createElement_tag(String tag) =>
@@ -11286,8 +11285,8 @@
    */
   factory Event.eventType(String type, String name, {bool canBubble: true,
       bool cancelable: true}) {
-    final Event e = document.$dom_createEvent(type);
-    e.$dom_initEvent(name, canBubble, cancelable);
+    final Event e = document._createEvent(type);
+    e._initEvent(name, canBubble, cancelable);
     return e;
   }
 
@@ -11466,7 +11465,7 @@
 
   @DomName('Event.initEvent')
   @DocsEditable()
-  void $dom_initEvent(String eventTypeArg, bool canBubbleArg, bool cancelableArg) native "Event_initEvent_Callback";
+  void _initEvent(String eventTypeArg, bool canBubbleArg, bool cancelableArg) native "Event_initEvent_Callback";
 
   @DomName('Event.preventDefault')
   @DocsEditable()
@@ -11643,6 +11642,7 @@
 
   @DomName('EventTarget.addEventListener')
   @DocsEditable()
+  @deprecated
   void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "EventTarget_addEventListener_Callback";
 
   @DomName('EventTarget.dispatchEvent')
@@ -11651,6 +11651,7 @@
 
   @DomName('EventTarget.removeEventListener')
   @DocsEditable()
+  @deprecated
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "EventTarget_removeEventListener_Callback";
 
 }
@@ -12596,7 +12597,7 @@
     }
     var completer = new Completer<Geoposition>();
     try {
-      $dom_getCurrentPosition(
+      _getCurrentPosition(
           (position) {
             completer.complete(_ensurePosition(position));
           },
@@ -12630,7 +12631,7 @@
     controller = new StreamController<Geoposition>(sync: true,
       onListen: () {
         assert(watchId == null);
-        watchId = $dom_watchPosition(
+        watchId = _watchPosition(
             (position) {
               controller.add(_ensurePosition(position));
             },
@@ -12641,7 +12642,7 @@
       },
       onCancel: () {
         assert(watchId != null);
-        $dom_clearWatch(watchId);
+        _clearWatch(watchId);
       });
 
     return controller.stream;
@@ -12654,15 +12655,15 @@
 
   @DomName('Geolocation.clearWatch')
   @DocsEditable()
-  void $dom_clearWatch(int watchID) native "Geolocation_clearWatch_Callback";
+  void _clearWatch(int watchID) native "Geolocation_clearWatch_Callback";
 
   @DomName('Geolocation.getCurrentPosition')
   @DocsEditable()
-  void $dom_getCurrentPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Object options]) native "Geolocation_getCurrentPosition_Callback";
+  void _getCurrentPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Object options]) native "Geolocation_getCurrentPosition_Callback";
 
   @DomName('Geolocation.watchPosition')
   @DocsEditable()
-  int $dom_watchPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Object options]) native "Geolocation_watchPosition_Callback";
+  int _watchPosition(_PositionCallback successCallback, [_PositionErrorCallback errorCallback, Object options]) native "Geolocation_watchPosition_Callback";
 }
 
 
@@ -12724,8 +12725,8 @@
   factory HashChangeEvent(String type,
       {bool canBubble: true, bool cancelable: true, String oldUrl,
       String newUrl}) {
-    var event = document.$dom_createEvent("HashChangeEvent");
-    event.$dom_initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
+    var event = document._createEvent("HashChangeEvent");
+    event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
     return event;
   }
   // To suppress missing implicit constructor warnings.
@@ -12744,7 +12745,7 @@
 
   @DomName('HashChangeEvent.initHashChangeEvent')
   @DocsEditable()
-  void $dom_initHashChangeEvent(String type, bool canBubble, bool cancelable, String oldURL, String newURL) native "HashChangeEvent_initHashChangeEvent_Callback";
+  void _initHashChangeEvent(String type, bool canBubble, bool cancelable, String oldURL, String newURL) native "HashChangeEvent_initHashChangeEvent_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -13060,21 +13061,21 @@
 
 
   @DomName('Document.body')
-  BodyElement get body => $dom_body;
+  BodyElement get body => _body;
 
   @DomName('Document.body')
   void set body(BodyElement value) {
-    $dom_body = value;
+    _body = value;
   }
 
   @DomName('Document.caretRangeFromPoint')
   Range caretRangeFromPoint(int x, int y) {
-    return $dom_caretRangeFromPoint(x, y);
+    return _caretRangeFromPoint(x, y);
   }
 
   @DomName('Document.elementFromPoint')
   Element elementFromPoint(int x, int y) {
-    return $dom_elementFromPoint(x, y);
+    return _elementFromPoint(x, y);
   }
 
   /**
@@ -13113,36 +13114,36 @@
   @DomName('Document.getCSSCanvasContext')
   CanvasRenderingContext getCssCanvasContext(String contextId, String name,
       int width, int height) {
-    return $dom_getCssCanvasContext(contextId, name, width, height);
+    return _getCssCanvasContext(contextId, name, width, height);
   }
 
   @DomName('Document.head')
-  HeadElement get head => $dom_head;
+  HeadElement get head => _head;
 
   @DomName('Document.lastModified')
-  String get lastModified => $dom_lastModified;
+  String get lastModified => _lastModified;
 
   @DomName('Document.preferredStylesheetSet')
-  String get preferredStylesheetSet => $dom_preferredStylesheetSet;
+  String get preferredStylesheetSet => _preferredStylesheetSet;
 
   @DomName('Document.referrer')
-  String get referrer => $dom_referrer;
+  String get referrer => _referrer;
 
   @DomName('Document.selectedStylesheetSet')
-  String get selectedStylesheetSet => $dom_selectedStylesheetSet;
+  String get selectedStylesheetSet => _selectedStylesheetSet;
   void set selectedStylesheetSet(String value) {
-    $dom_selectedStylesheetSet = value;
+    _selectedStylesheetSet = value;
   }
 
   @DomName('Document.styleSheets')
-  List<StyleSheet> get styleSheets => $dom_styleSheets;
+  List<StyleSheet> get styleSheets => _styleSheets;
 
   @DomName('Document.title')
-  String get title => $dom_title;
+  String get title => _title;
 
   @DomName('Document.title')
   void set title(String value) {
-    $dom_title = value;
+    _title = value;
   }
 
   @DomName('Document.webkitCancelFullScreen')
@@ -13150,7 +13151,7 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   void cancelFullScreen() {
-    $dom_webkitCancelFullScreen();
+    _webkitCancelFullScreen();
   }
 
   @DomName('Document.webkitExitFullscreen')
@@ -13158,7 +13159,7 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   void exitFullscreen() {
-    $dom_webkitExitFullscreen();
+    _webkitExitFullscreen();
   }
 
   @DomName('Document.webkitExitPointerLock')
@@ -13166,45 +13167,45 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   void exitPointerLock() {
-    $dom_webkitExitPointerLock();
+    _webkitExitPointerLock();
   }
 
   @DomName('Document.webkitFullscreenElement')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  Element get fullscreenElement => $dom_webkitFullscreenElement;
+  Element get fullscreenElement => _webkitFullscreenElement;
 
   @DomName('Document.webkitFullscreenEnabled')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  bool get fullscreenEnabled => $dom_webkitFullscreenEnabled;
+  bool get fullscreenEnabled => _webkitFullscreenEnabled;
 
   @DomName('Document.webkitHidden')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  bool get hidden => $dom_webkitHidden;
+  bool get hidden => _webkitHidden;
 
   @DomName('Document.webkitIsFullScreen')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  bool get isFullScreen => $dom_webkitIsFullScreen;
+  bool get isFullScreen => _webkitIsFullScreen;
 
   @DomName('Document.webkitPointerLockElement')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   Element get pointerLockElement =>
-      $dom_webkitPointerLockElement;
+      _webkitPointerLockElement;
 
   @DomName('Document.webkitVisibilityState')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  String get visibilityState => $dom_webkitVisibilityState;
+  String get visibilityState => _webkitVisibilityState;
 
   @Experimental
   void register(String tag, Type custom) {
@@ -13261,11 +13262,11 @@
 
   @DomName('HTMLElement.innerHTML')
   @DocsEditable()
-  String get innerHtml native "HTMLElement_innerHTML_Getter";
+  String get _innerHtml native "HTMLElement_innerHTML_Getter";
 
   @DomName('HTMLElement.innerHTML')
   @DocsEditable()
-  void set innerHtml(String value) native "HTMLElement_innerHTML_Setter";
+  void set _innerHtml(String value) native "HTMLElement_innerHTML_Setter";
 
   @DomName('HTMLElement.inputMethodContext')
   @DocsEditable()
@@ -13616,6 +13617,22 @@
     return true;
   }
 
+  /**
+   * Makes a cross-origin request to the specified URL.
+   *
+   * This API provides a subset of [request] which works on IE9. If IE9
+   * cross-origin support is not required then [request] should be used instead.
+   */
+  @Experimental()
+  static Future<String> requestCrossOrigin(String url,
+      {String method, String sendData}) {
+    if (supportsCrossOrigin) {
+      return request(url, method: method, sendData: sendData).then((xhr) {
+        return xhr.responseText;
+      });
+    }
+  }
+
   // To suppress missing implicit constructor warnings.
   factory HttpRequest._() { throw new UnsupportedError("Not supported"); }
 
@@ -15498,23 +15515,23 @@
 
   factory KeyboardEvent(String type,
       {Window view, bool canBubble: true, bool cancelable: true,
-      String keyIdentifier: "", int keyLocation: 1, bool ctrlKey: false,
+      int keyLocation: 1, bool ctrlKey: false,
       bool altKey: false, bool shiftKey: false, bool metaKey: false,
       bool altGraphKey: false}) {
     if (view == null) {
       view = window;
     }
-    final e = document.$dom_createEvent("KeyboardEvent");
-    e.$dom_initKeyboardEvent(type, canBubble, cancelable, view, keyIdentifier,
+    final e = document._createEvent("KeyboardEvent");
+    e._initKeyboardEvent(type, canBubble, cancelable, view, "",
         keyLocation, ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
     return e;
   }
 
   @DomName('KeyboardEvent.keyCode')
-  int get keyCode => $dom_keyCode;
+  int get keyCode => _keyCode;
 
   @DomName('KeyboardEvent.charCode')
-  int get charCode => $dom_charCode;
+  int get charCode => _charCode;
   // To suppress missing implicit constructor warnings.
   factory KeyboardEvent._() { throw new UnsupportedError("Not supported"); }
 
@@ -15554,7 +15571,7 @@
   @DomName('KeyboardEvent.keyIdentifier')
   @DocsEditable()
   @Experimental() // nonstandard
-  String get $dom_keyIdentifier native "KeyboardEvent_keyIdentifier_Getter";
+  String get _keyIdentifier native "KeyboardEvent_keyIdentifier_Getter";
 
   @DomName('KeyboardEvent.keyLocation')
   @DocsEditable()
@@ -15581,7 +15598,7 @@
 
   @DomName('KeyboardEvent.initKeyboardEvent')
   @DocsEditable()
-  void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable, Window view, String keyIdentifier, int location, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) native "KeyboardEvent_initKeyboardEvent_Callback";
+  void _initKeyboardEvent(String type, bool canBubble, bool cancelable, Window view, String keyIdentifier, int location, 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
@@ -17504,8 +17521,8 @@
     if (source == null) {
       source = window;
     }
-    var event = document.$dom_createEvent("MessageEvent");
-    event.$dom_initMessageEvent(type, canBubble, cancelable, data, origin,
+    var event = document._createEvent("MessageEvent");
+    event._initMessageEvent(type, canBubble, cancelable, data, origin,
         lastEventId, source, messagePorts);
     return event;
   }
@@ -17536,7 +17553,7 @@
 
   @DomName('MessageEvent.initMessageEvent')
   @DocsEditable()
-  void $dom_initMessageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Object dataArg, String originArg, String lastEventIdArg, Window 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";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -18114,8 +18131,8 @@
     if (view == null) {
       view = window;
     }
-    var event = document.$dom_createEvent('MouseEvent');
-    event.$dom_initMouseEvent(type, canBubble, cancelable, view, detail,
+    var event = document._createEvent('MouseEvent');
+    event._initMouseEvent(type, canBubble, cancelable, view, detail,
         screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
         button, relatedTarget);
     return event;
@@ -18133,11 +18150,11 @@
 
   @DomName('MouseEvent.clientX')
   @DocsEditable()
-  int get $dom_clientX native "MouseEvent_clientX_Getter";
+  int get _clientX native "MouseEvent_clientX_Getter";
 
   @DomName('MouseEvent.clientY')
   @DocsEditable()
-  int get $dom_clientY native "MouseEvent_clientY_Getter";
+  int get _clientY native "MouseEvent_clientY_Getter";
 
   @DomName('MouseEvent.ctrlKey')
   @DocsEditable()
@@ -18160,12 +18177,12 @@
   @DomName('MouseEvent.offsetX')
   @DocsEditable()
   @Unstable()
-  int get $dom_offsetX native "MouseEvent_offsetX_Getter";
+  int get _offsetX native "MouseEvent_offsetX_Getter";
 
   @DomName('MouseEvent.offsetY')
   @DocsEditable()
   @Unstable()
-  int get $dom_offsetY native "MouseEvent_offsetY_Getter";
+  int get _offsetY native "MouseEvent_offsetY_Getter";
 
   @DomName('MouseEvent.relatedTarget')
   @DocsEditable()
@@ -18173,11 +18190,11 @@
 
   @DomName('MouseEvent.screenX')
   @DocsEditable()
-  int get $dom_screenX native "MouseEvent_screenX_Getter";
+  int get _screenX native "MouseEvent_screenX_Getter";
 
   @DomName('MouseEvent.screenY')
   @DocsEditable()
-  int get $dom_screenY native "MouseEvent_screenY_Getter";
+  int get _screenY native "MouseEvent_screenY_Getter";
 
   @DomName('MouseEvent.shiftKey')
   @DocsEditable()
@@ -18193,18 +18210,18 @@
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  int get $dom_webkitMovementX native "MouseEvent_webkitMovementX_Getter";
+  int get _webkitMovementX native "MouseEvent_webkitMovementX_Getter";
 
   @DomName('MouseEvent.webkitMovementY')
   @DocsEditable()
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  int get $dom_webkitMovementY native "MouseEvent_webkitMovementY_Getter";
+  int get _webkitMovementY native "MouseEvent_webkitMovementY_Getter";
 
   @DomName('MouseEvent.initMouseEvent')
   @DocsEditable()
-  void $dom_initMouseEvent(String type, bool canBubble, bool cancelable, Window view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, int button, EventTarget relatedTarget) native "MouseEvent_initMouseEvent_Callback";
+  void _initMouseEvent(String type, bool canBubble, bool cancelable, Window view, int detail, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, int button, EventTarget relatedTarget) native "MouseEvent_initMouseEvent_Callback";
 
 
   @deprecated
@@ -18226,14 +18243,14 @@
 
   @DomName('MouseEvent.clientX')
   @DomName('MouseEvent.clientY')
-  Point get client => new Point($dom_clientX, $dom_clientY);
+  Point get client => new Point(_clientX, _clientY);
 
   @DomName('MouseEvent.movementX')
   @DomName('MouseEvent.movementY')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  Point get movement => new Point($dom_webkitMovementX, $dom_webkitMovementY);
+  Point get movement => new Point(_webkitMovementX, _webkitMovementY);
 
   /**
    * The coordinates of the mouse pointer in target node coordinates.
@@ -18242,11 +18259,11 @@
    * after the event has fired or if the element has CSS transforms affecting
    * it.
    */
-  Point get offset => new Point($dom_offsetX, $dom_offsetY);
+  Point get offset => new Point(_offsetX, _offsetY);
 
   @DomName('MouseEvent.screenX')
   @DomName('MouseEvent.screenY')
-  Point get screen => new Point($dom_screenX, $dom_screenY);
+  Point get screen => new Point(_screenX, _screenY);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -18270,8 +18287,8 @@
       {bool canBubble: false, bool cancelable: false, Node relatedNode,
       String prevValue, String newValue, String attrName, int attrChange: 0}) {
 
-    var event = document.$dom_createEvent('MutationEvent');
-    event.$dom_initMutationEvent(type, canBubble, cancelable, relatedNode,
+    var event = document._createEvent('MutationEvent');
+    event._initMutationEvent(type, canBubble, cancelable, relatedNode,
         prevValue, newValue, attrName, attrChange);
     return event;
   }
@@ -18312,7 +18329,7 @@
 
   @DomName('MutationEvent.initMutationEvent')
   @DocsEditable()
-  void $dom_initMutationEvent(String type, bool canBubble, bool cancelable, Node relatedNode, String prevValue, String newValue, String attrName, int attrChange) native "MutationEvent_initMutationEvent_Callback";
+  void _initMutationEvent(String type, bool canBubble, bool cancelable, Node relatedNode, String prevValue, String newValue, String attrName, int attrChange) native "MutationEvent_initMutationEvent_Callback";
 
 }
 
@@ -18856,7 +18873,7 @@
   Node removeLast() {
     final result = last;
     if (result != null) {
-      _this.$dom_removeChild(result);
+      _this._removeChild(result);
     }
     return result;
   }
@@ -18864,7 +18881,7 @@
   Node removeAt(int index) {
     var result = this[index];
     if (result != null) {
-      _this.$dom_removeChild(result);
+      _this._removeChild(result);
     }
     return result;
   }
@@ -18873,7 +18890,7 @@
     if (object is! Node) return false;
     Node node = object;
     if (!identical(_this, node.parentNode)) return false;
-    _this.$dom_removeChild(node);
+    _this._removeChild(node);
     return true;
   }
 
@@ -18885,7 +18902,7 @@
     while (child != null) {
       Node nextChild = child.nextNode;
       if (test(child) == removeMatching) {
-        _this.$dom_removeChild(child);
+        _this._removeChild(child);
       }
       child = nextChild;
     }
@@ -18904,7 +18921,7 @@
   }
 
   void operator []=(int index, Node value) {
-    _this.$dom_replaceChild(value, this[index]);
+    _this._replaceChild(value, this[index]);
   }
 
   Iterator<Node> get iterator => _this.$dom_childNodes.iterator;
@@ -18987,7 +19004,7 @@
     // TODO(vsm): Use the native remove when available.
     if (this.parentNode != null) {
       final Node parent = this.parentNode;
-      parentNode.$dom_removeChild(this);
+      parentNode._removeChild(this);
     }
   }
 
@@ -18998,7 +19015,7 @@
   Node replaceWith(Node otherNode) {
     try {
       final Node parent = this.parentNode;
-      parent.$dom_replaceChild(otherNode, this);
+      parent._replaceChild(otherNode, this);
     } catch (e) {
 
     };
@@ -19147,13 +19164,13 @@
   @DocsEditable()
   // http://dom.spec.whatwg.org/#dom-node-localname
   @deprecated // deprecated
-  String get $dom_localName native "Node_localName_Getter";
+  String get _localName native "Node_localName_Getter";
 
   @DomName('Node.namespaceURI')
   @DocsEditable()
   // http://dom.spec.whatwg.org/#dom-node-namespaceuri
   @deprecated // deprecated
-  String get $dom_namespaceUri native "Node_namespaceURI_Getter";
+  String get _namespaceUri native "Node_namespaceURI_Getter";
 
   @DomName('Node.nextSibling')
   @DocsEditable()
@@ -19226,11 +19243,11 @@
 
   @DomName('Node.removeChild')
   @DocsEditable()
-  Node $dom_removeChild(Node oldChild) native "Node_removeChild_Callback";
+  Node _removeChild(Node oldChild) native "Node_removeChild_Callback";
 
   @DomName('Node.replaceChild')
   @DocsEditable()
-  Node $dom_replaceChild(Node newChild, Node oldChild) native "Node_replaceChild_Callback";
+  Node _replaceChild(Node newChild, Node oldChild) native "Node_replaceChild_Callback";
 
   @DomName('Node.addEventListener')
   @DocsEditable()
@@ -19336,7 +19353,7 @@
 @Unstable()
 class NodeIterator extends NativeFieldWrapperClass1 {
   factory NodeIterator(Node root, int whatToShow) {
-    return document.$dom_createNodeIterator(root, whatToShow, null, false);
+    return document._createNodeIterator(root, whatToShow, null, false);
   }
 
   @DomName('NodeIterator.pointerBeforeReferenceNode')
@@ -20131,22 +20148,22 @@
   @DomName('ParentNode.childElementCount')
   @DocsEditable()
   @Experimental() // untriaged
-  int get $dom_childElementCount native "ParentNode_childElementCount_Getter";
+  int get _childElementCount native "ParentNode_childElementCount_Getter";
 
   @DomName('ParentNode.children')
   @DocsEditable()
   @Experimental() // untriaged
-  HtmlCollection get $dom_children native "ParentNode_children_Getter";
+  HtmlCollection get _children native "ParentNode_children_Getter";
 
   @DomName('ParentNode.firstElementChild')
   @DocsEditable()
   @Experimental() // untriaged
-  Element get $dom_firstElementChild native "ParentNode_firstElementChild_Getter";
+  Element get _firstElementChild native "ParentNode_firstElementChild_Getter";
 
   @DomName('ParentNode.lastElementChild')
   @DocsEditable()
   @Experimental() // untriaged
-  Element get $dom_lastElementChild native "ParentNode_lastElementChild_Getter";
+  Element get _lastElementChild native "ParentNode_lastElementChild_Getter";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -21067,7 +21084,7 @@
   factory Range() => document.$dom_createRange();
 
   factory Range.fromPoint(Point point) =>
-      document.$dom_caretRangeFromPoint(point.x, point.y);
+      document._caretRangeFromPoint(point.x, point.y);
 
   @DomName('Range.END_TO_END')
   @DocsEditable()
@@ -21978,26 +21995,26 @@
   @DomName('Screen.availLeft')
   @DomName('Screen.availTop')
   @DomName('Screen.availWidth')
-  Rect get available => new Rect($dom_availLeft, $dom_availTop, $dom_availWidth,
-      $dom_availHeight);
+  Rect get available => new Rect(_availLeft, _availTop, _availWidth,
+      _availHeight);
 
   @DomName('Screen.availHeight')
   @DocsEditable()
-  int get $dom_availHeight native "Screen_availHeight_Getter";
+  int get _availHeight native "Screen_availHeight_Getter";
 
   @DomName('Screen.availLeft')
   @DocsEditable()
   @Experimental() // nonstandard
-  int get $dom_availLeft native "Screen_availLeft_Getter";
+  int get _availLeft native "Screen_availLeft_Getter";
 
   @DomName('Screen.availTop')
   @DocsEditable()
   @Experimental() // nonstandard
-  int get $dom_availTop native "Screen_availTop_Getter";
+  int get _availTop native "Screen_availTop_Getter";
 
   @DomName('Screen.availWidth')
   @DocsEditable()
-  int get $dom_availWidth native "Screen_availWidth_Getter";
+  int get _availWidth native "Screen_availWidth_Getter";
 
   @DomName('Screen.colorDepth')
   @DocsEditable()
@@ -23681,11 +23698,11 @@
   // TODO(nweiz): update this when maps support lazy iteration
   bool containsValue(String value) => values.any((e) => e == value);
 
-  bool containsKey(String key) => $dom_getItem(key) != null;
+  bool containsKey(String key) => _getItem(key) != null;
 
-  String operator [](String key) => $dom_getItem(key);
+  String operator [](String key) => _getItem(key);
 
-  void operator []=(String key, String value) { $dom_setItem(key, value); }
+  void operator []=(String key, String value) { _setItem(key, value); }
 
   String putIfAbsent(String key, String ifAbsent()) {
     if (!containsKey(key)) this[key] = ifAbsent();
@@ -23694,15 +23711,15 @@
 
   String remove(String key) {
     final value = this[key];
-    $dom_removeItem(key);
+    _removeItem(key);
     return value;
   }
 
-  void clear() => $dom_clear();
+  void clear() => _clear();
 
   void forEach(void f(String key, String value)) {
     for (var i = 0; true; i++) {
-      final key = $dom_key(i);
+      final key = _key(i);
       if (key == null) return;
 
       f(key, this[key]);
@@ -23721,15 +23738,15 @@
     return values;
   }
 
-  int get length => $dom_length;
+  int get length => _length;
 
-  bool get isEmpty => $dom_key(0) == null;
+  bool get isEmpty => _key(0) == null;
 
   bool get isNotEmpty => !isEmpty;
 
   @DomName('Storage.length')
   @DocsEditable()
-  int get $dom_length native "Storage_length_Getter";
+  int get _length native "Storage_length_Getter";
 
   bool __delete__(index_OR_name) {
     if ((index_OR_name is int || index_OR_name == null)) {
@@ -23777,23 +23794,23 @@
 
   @DomName('Storage.clear')
   @DocsEditable()
-  void $dom_clear() native "Storage_clear_Callback";
+  void _clear() native "Storage_clear_Callback";
 
   @DomName('Storage.getItem')
   @DocsEditable()
-  String $dom_getItem(String key) native "Storage_getItem_Callback";
+  String _getItem(String key) native "Storage_getItem_Callback";
 
   @DomName('Storage.key')
   @DocsEditable()
-  String $dom_key(int index) native "Storage_key_Callback";
+  String _key(int index) native "Storage_key_Callback";
 
   @DomName('Storage.removeItem')
   @DocsEditable()
-  void $dom_removeItem(String key) native "Storage_removeItem_Callback";
+  void _removeItem(String key) native "Storage_removeItem_Callback";
 
   @DomName('Storage.setItem')
   @DocsEditable()
-  void $dom_setItem(String key, String data) native "Storage_setItem_Callback";
+  void _setItem(String key, String data) native "Storage_setItem_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -23821,8 +23838,8 @@
     {bool canBubble: false, bool cancelable: false, String key, String oldValue,
     String newValue, String url, Storage storageArea}) {
 
-    var e = document.$dom_createEvent("StorageEvent");
-    e.$dom_initStorageEvent(type, canBubble, cancelable, key, oldValue,
+    var e = document._createEvent("StorageEvent");
+    e._initStorageEvent(type, canBubble, cancelable, key, oldValue,
         newValue, url, storageArea);
     return e;
   }
@@ -23851,7 +23868,7 @@
 
   @DomName('StorageEvent.initStorageEvent')
   @DocsEditable()
-  void $dom_initStorageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, String keyArg, String oldValueArg, String newValueArg, String urlArg, Storage storageAreaArg) native "StorageEvent_initStorageEvent_Callback";
+  void _initStorageEvent(String typeArg, bool canBubbleArg, bool cancelableArg, String keyArg, String oldValueArg, String newValueArg, String urlArg, Storage storageAreaArg) native "StorageEvent_initStorageEvent_Callback";
 
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
@@ -24233,21 +24250,21 @@
 
   @DomName('HTMLTableElement.tBodies')
   List<TableSectionElement> get tBodies =>
-  new _WrappedList<TableSectionElement>($dom_tBodies);
+  new _WrappedList<TableSectionElement>(_tBodies);
 
   @DomName('HTMLTableElement.rows')
   List<TableRowElement> get rows =>
-      new _WrappedList<TableRowElement>($dom_rows);
+      new _WrappedList<TableRowElement>(_rows);
 
   TableRowElement addRow() {
     return insertRow(-1);
   }
 
-  TableCaptionElement createCaption() => $dom_createCaption();
-  TableSectionElement createTBody() => $dom_createTBody();
-  TableSectionElement createTFoot() => $dom_createTFoot();
-  TableSectionElement createTHead() => $dom_createTHead();
-  TableRowElement insertRow(int index) => $dom_insertRow(index);
+  TableCaptionElement createCaption() => _createCaption();
+  TableSectionElement createTBody() => _createTBody();
+  TableSectionElement createTFoot() => _createTFoot();
+  TableSectionElement createTHead() => _createTHead();
+  TableRowElement insertRow(int index) => _insertRow(index);
 
 
   // To suppress missing implicit constructor warnings.
@@ -24279,11 +24296,11 @@
 
   @DomName('HTMLTableElement.rows')
   @DocsEditable()
-  HtmlCollection get $dom_rows native "HTMLTableElement_rows_Getter";
+  HtmlCollection get _rows native "HTMLTableElement_rows_Getter";
 
   @DomName('HTMLTableElement.tBodies')
   @DocsEditable()
-  HtmlCollection get $dom_tBodies native "HTMLTableElement_tBodies_Getter";
+  HtmlCollection get _tBodies native "HTMLTableElement_tBodies_Getter";
 
   @DomName('HTMLTableElement.tFoot')
   @DocsEditable()
@@ -24303,19 +24320,19 @@
 
   @DomName('HTMLTableElement.createCaption')
   @DocsEditable()
-  HtmlElement $dom_createCaption() native "HTMLTableElement_createCaption_Callback";
+  HtmlElement _createCaption() native "HTMLTableElement_createCaption_Callback";
 
   @DomName('HTMLTableElement.createTBody')
   @DocsEditable()
-  HtmlElement $dom_createTBody() native "HTMLTableElement_createTBody_Callback";
+  HtmlElement _createTBody() native "HTMLTableElement_createTBody_Callback";
 
   @DomName('HTMLTableElement.createTFoot')
   @DocsEditable()
-  HtmlElement $dom_createTFoot() native "HTMLTableElement_createTFoot_Callback";
+  HtmlElement _createTFoot() native "HTMLTableElement_createTFoot_Callback";
 
   @DomName('HTMLTableElement.createTHead')
   @DocsEditable()
-  HtmlElement $dom_createTHead() native "HTMLTableElement_createTHead_Callback";
+  HtmlElement _createTHead() native "HTMLTableElement_createTHead_Callback";
 
   @DomName('HTMLTableElement.deleteCaption')
   @DocsEditable()
@@ -24335,7 +24352,7 @@
 
   @DomName('HTMLTableElement.insertRow')
   @DocsEditable()
-  HtmlElement $dom_insertRow(int index) native "HTMLTableElement_insertRow_Callback";
+  HtmlElement _insertRow(int index) native "HTMLTableElement_insertRow_Callback";
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -24348,13 +24365,13 @@
 
   @DomName('HTMLTableRowElement.cells')
   List<TableCellElement> get cells =>
-      new _WrappedList<TableCellElement>($dom_cells);
+      new _WrappedList<TableCellElement>(_cells);
 
   TableCellElement addCell() {
     return insertCell(-1);
   }
 
-  TableCellElement insertCell(int index) => $dom_insertCell(index);
+  TableCellElement insertCell(int index) => _insertCell(index);
 
   // To suppress missing implicit constructor warnings.
   factory TableRowElement._() { throw new UnsupportedError("Not supported"); }
@@ -24365,7 +24382,7 @@
 
   @DomName('HTMLTableRowElement.cells')
   @DocsEditable()
-  HtmlCollection get $dom_cells native "HTMLTableRowElement_cells_Getter";
+  HtmlCollection get _cells native "HTMLTableRowElement_cells_Getter";
 
   @DomName('HTMLTableRowElement.rowIndex')
   @DocsEditable()
@@ -24381,7 +24398,7 @@
 
   @DomName('HTMLTableRowElement.insertCell')
   @DocsEditable()
-  HtmlElement $dom_insertCell(int index) native "HTMLTableRowElement_insertCell_Callback";
+  HtmlElement _insertCell(int index) native "HTMLTableRowElement_insertCell_Callback";
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -24394,20 +24411,20 @@
 
   @DomName('HTMLTableSectionElement.rows')
   List<TableRowElement> get rows =>
-    new _WrappedList<TableRowElement>($dom_rows);
+    new _WrappedList<TableRowElement>(_rows);
 
   TableRowElement addRow() {
     return insertRow(-1);
   }
 
-  TableRowElement insertRow(int index) => $dom_insertRow(index);
+  TableRowElement insertRow(int index) => _insertRow(index);
 
   // To suppress missing implicit constructor warnings.
   factory TableSectionElement._() { throw new UnsupportedError("Not supported"); }
 
   @DomName('HTMLTableSectionElement.rows')
   @DocsEditable()
-  HtmlCollection get $dom_rows native "HTMLTableSectionElement_rows_Getter";
+  HtmlCollection get _rows native "HTMLTableSectionElement_rows_Getter";
 
   @DomName('HTMLTableSectionElement.deleteRow')
   @DocsEditable()
@@ -24415,7 +24432,7 @@
 
   @DomName('HTMLTableSectionElement.insertRow')
   @DocsEditable()
-  HtmlElement $dom_insertRow(int index) native "HTMLTableSectionElement_insertRow_Callback";
+  HtmlElement _insertRow(int index) native "HTMLTableSectionElement_insertRow_Callback";
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -24524,13 +24541,13 @@
 
   @DomName('HTMLTemplateElement.content')
   @DocsEditable()
-  DocumentFragment get $dom_content native "HTMLTemplateElement_content_Getter";
+  DocumentFragment get _content native "HTMLTemplateElement_content_Getter";
 
 
   // For real TemplateElement use the actual DOM .content field instead of
   // our polyfilled expando.
   @Experimental()
-  DocumentFragment get content => $dom_content;
+  DocumentFragment get content => _content;
 
 
   /**
@@ -24724,6 +24741,22 @@
 }''';
     document.head.append(style);
   }
+
+  /**
+   * An override to place the contents into content rather than as child nodes.
+   *
+   * See also:
+   *
+   * * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#innerhtml-on-templates>
+   */
+  void setInnerHtml(String html,
+    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    text = null;
+    var fragment = createFragment(
+        html, validator: validator, treeSanitizer: treeSanitizer);
+
+    content.append(fragment);
+  }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -24734,7 +24767,7 @@
 
 @DomName('Text')
 class Text extends CharacterData {
-  factory Text(String data) => document.$dom_createTextNode(data);
+  factory Text(String data) => document._createTextNode(data);
   // To suppress missing implicit constructor warnings.
   factory Text._() { throw new UnsupportedError("Not supported"); }
 
@@ -25003,8 +25036,8 @@
     if (view == null) {
       view = window;
     }
-    var e = document.$dom_createEvent("TextEvent");
-    e.$dom_initTextEvent(type, canBubble, cancelable, view, data);
+    var e = document._createEvent("TextEvent");
+    e._initTextEvent(type, canBubble, cancelable, view, data);
     return e;
   }
   // To suppress missing implicit constructor warnings.
@@ -25016,7 +25049,7 @@
 
   @DomName('TextEvent.initTextEvent')
   @DocsEditable()
-  void $dom_initTextEvent(String typeArg, bool canBubbleArg, bool cancelableArg, Window 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
@@ -25496,11 +25529,11 @@
 
   @DomName('Touch.clientX')
   @DocsEditable()
-  int get $dom_clientX native "Touch_clientX_Getter";
+  int get _clientX native "Touch_clientX_Getter";
 
   @DomName('Touch.clientY')
   @DocsEditable()
-  int get $dom_clientY native "Touch_clientY_Getter";
+  int get _clientY native "Touch_clientY_Getter";
 
   @DomName('Touch.identifier')
   @DocsEditable()
@@ -25508,19 +25541,19 @@
 
   @DomName('Touch.pageX')
   @DocsEditable()
-  int get $dom_pageX native "Touch_pageX_Getter";
+  int get _pageX native "Touch_pageX_Getter";
 
   @DomName('Touch.pageY')
   @DocsEditable()
-  int get $dom_pageY native "Touch_pageY_Getter";
+  int get _pageY native "Touch_pageY_Getter";
 
   @DomName('Touch.screenX')
   @DocsEditable()
-  int get $dom_screenX native "Touch_screenX_Getter";
+  int get _screenX native "Touch_screenX_Getter";
 
   @DomName('Touch.screenY')
   @DocsEditable()
-  int get $dom_screenY native "Touch_screenY_Getter";
+  int get _screenY native "Touch_screenY_Getter";
 
   @DomName('Touch.target')
   @DocsEditable()
@@ -25557,15 +25590,15 @@
 
   @DomName('Touch.clientX')
   @DomName('Touch.clientY')
-  Point get client => new Point($dom_clientX, $dom_clientY);
+  Point get client => new Point(_clientX, _clientY);
 
   @DomName('Touch.pageX')
   @DomName('Touch.pageY')
-  Point get page => new Point($dom_pageX, $dom_pageY);
+  Point get page => new Point(_pageX, _pageY);
 
   @DomName('Touch.screenX')
   @DomName('Touch.screenY')
-  Point get screen => new Point($dom_screenX, $dom_screenY);
+  Point get screen => new Point(_screenX, _screenY);
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -25586,8 +25619,8 @@
     if (view == null) {
       view = window;
     }
-    var e = document.$dom_createEvent("TouchEvent");
-    e.$dom_initTouchEvent(touches, targetTouches, changedTouches, type, view,
+    var e = document._createEvent("TouchEvent");
+    e._initTouchEvent(touches, targetTouches, changedTouches, type, view,
         screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey);
     return e;
   }
@@ -25624,7 +25657,7 @@
 
   @DomName('TouchEvent.initTouchEvent')
   @DocsEditable()
-  void $dom_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";
+  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";
 
 
   /**
@@ -25654,7 +25687,7 @@
   /// NB: This constructor likely does not work as you might expect it to! This
   /// constructor will simply fail (returning null) if you are not on a device
   /// with touch enabled. See dartbug.com/8314.
-  factory TouchList() => document.$dom_createTouchList();
+  factory TouchList() => document._createTouchList();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -25857,7 +25890,7 @@
 @Unstable()
 class TreeWalker extends NativeFieldWrapperClass1 {
   factory TreeWalker(Node root, int whatToShow) {
-    return document.$dom_createTreeWalker(root, whatToShow, null, false);
+    return document._createTreeWalker(root, whatToShow, null, false);
   }
 
   @DomName('TreeWalker.currentNode')
@@ -25936,8 +25969,8 @@
     if (view == null) {
       view = window;
     }
-    final e = document.$dom_createEvent("UIEvent");
-    e.$dom_initUIEvent(type, canBubble, cancelable, view, detail);
+    final e = document._createEvent("UIEvent");
+    e._initUIEvent(type, canBubble, cancelable, view, detail);
     return e;
   }
   // To suppress missing implicit constructor warnings.
@@ -25946,7 +25979,7 @@
   @DomName('UIEvent.charCode')
   @DocsEditable()
   @Unstable()
-  int get $dom_charCode native "UIEvent_charCode_Getter";
+  int get _charCode native "UIEvent_charCode_Getter";
 
   @DomName('UIEvent.detail')
   @DocsEditable()
@@ -25955,31 +25988,31 @@
   @DomName('UIEvent.keyCode')
   @DocsEditable()
   @Unstable()
-  int get $dom_keyCode native "UIEvent_keyCode_Getter";
+  int get _keyCode native "UIEvent_keyCode_Getter";
 
   @DomName('UIEvent.layerX')
   @DocsEditable()
   // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
   @Experimental() // nonstandard
-  int get $dom_layerX native "UIEvent_layerX_Getter";
+  int get _layerX native "UIEvent_layerX_Getter";
 
   @DomName('UIEvent.layerY')
   @DocsEditable()
   // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
   @Experimental() // nonstandard
-  int get $dom_layerY native "UIEvent_layerY_Getter";
+  int get _layerY native "UIEvent_layerY_Getter";
 
   @DomName('UIEvent.pageX')
   @DocsEditable()
   // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
   @Experimental() // nonstandard
-  int get $dom_pageX native "UIEvent_pageX_Getter";
+  int get _pageX native "UIEvent_pageX_Getter";
 
   @DomName('UIEvent.pageY')
   @DocsEditable()
   // http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#events-mouseevents
   @Experimental() // nonstandard
-  int get $dom_pageY native "UIEvent_pageY_Getter";
+  int get _pageY native "UIEvent_pageY_Getter";
 
   @DomName('UIEvent.view')
   @DocsEditable()
@@ -25992,7 +26025,7 @@
 
   @DomName('UIEvent.initUIEvent')
   @DocsEditable()
-  void $dom_initUIEvent(String type, bool canBubble, bool cancelable, Window view, int detail) native "UIEvent_initUIEvent_Callback";
+  void _initUIEvent(String type, bool canBubble, bool cancelable, Window view, int detail) native "UIEvent_initUIEvent_Callback";
 
 
   @deprecated
@@ -26007,11 +26040,11 @@
 
   @DomName('UIEvent.layerX')
   @DomName('UIEvent.layerY')
-  Point get layer => new Point($dom_layerX, $dom_layerY);
+  Point get layer => new Point(_layerX, _layerY);
 
   @DomName('UIEvent.pageX')
   @DomName('UIEvent.pageY')
-  Point get page => new Point($dom_pageX, $dom_pageY);
+  Point get page => new Point(_pageX, _pageY);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -26065,13 +26098,13 @@
     if ((blob_OR_source_OR_stream is Blob || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_1(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is MediaSource || blob_OR_source_OR_stream == null)) {
+    if ((blob_OR_source_OR_stream is MediaStream || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_2(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is _WebKitMediaSource || blob_OR_source_OR_stream == null)) {
+    if ((blob_OR_source_OR_stream is MediaSource || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_3(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is MediaStream || blob_OR_source_OR_stream == null)) {
+    if ((blob_OR_source_OR_stream is _WebKitMediaSource || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_4(blob_OR_source_OR_stream);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
@@ -26519,16 +26552,16 @@
     if (Device.isFirefox) {
       eventType = 'MouseScrollEvents';
     }
-    final event = document.$dom_createEvent(eventType);
+    final event = document._createEvent(eventType);
     // Dartium always needs these flipped because we're essentially always
     // polyfilling (see similar dart2js code as well)
     deltaX = -deltaX;
     deltaY = -deltaY;
       // Fallthrough for Dartium.
-      event.$dom_initMouseEvent(type, canBubble, cancelable, view, detail,
+      event._initMouseEvent(type, canBubble, cancelable, view, detail,
           screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
           metaKey, button, relatedTarget);
-      event.$dom_initWebKitWheelEvent(deltaX,
+      event._initWebKitWheelEvent(deltaX,
           deltaY ~/ 120, // Chrome does an auto-convert to pixels.
           view, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
           metaKey);
@@ -26575,7 +26608,7 @@
   @DomName('WheelEvent.initWebKitWheelEvent')
   @DocsEditable()
   @Experimental()
-  void $dom_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";
+  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";
 
 
   /**
@@ -26646,6 +26679,15 @@
   }
 
   /**
+   * Deregister 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 deregisterPort(String name) {
+    document.documentElement.attributes.remove('dart-port:$name');
+  }
+
+  /**
    * Returns a Future that completes just before the window is about to
    * repaint so the user can draw an animation frame.
    *
@@ -27087,7 +27129,7 @@
 
   @DomName('Window.getComputedStyle')
   @DocsEditable()
-  CssStyleDeclaration $dom_getComputedStyle(Element element, String pseudoElement) native "Window_getComputedStyle_Callback";
+  CssStyleDeclaration _getComputedStyle(Element element, String pseudoElement) native "Window_getComputedStyle_Callback";
 
   @DomName('Window.getMatchedCSSRules')
   @DocsEditable()
@@ -27108,7 +27150,7 @@
 
   @DomName('Window.moveTo')
   @DocsEditable()
-  void $dom_moveTo(num x, num y) native "Window_moveTo_Callback";
+  void _moveTo(num x, num y) native "Window_moveTo_Callback";
 
   @DomName('Window.open')
   @DocsEditable()
@@ -27505,7 +27547,7 @@
   Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);
 
   void moveTo(Point p) {
-    $dom_moveTo(p.x, p.y);
+    _moveTo(p.x, p.y);
   }
 
 }
@@ -29442,7 +29484,7 @@
 
   Iterable<String> get keys {
     // TODO: generate a lazy collection instead.
-    var attributes = _element.$dom_attributes;
+    var attributes = _element._attributes;
     var keys = new List<String>();
     for (int i = 0, len = attributes.length; i < len; i++) {
       if (_matches(attributes[i])) {
@@ -29454,7 +29496,7 @@
 
   Iterable<String> get values {
     // TODO: generate a lazy collection instead.
-    var attributes = _element.$dom_attributes;
+    var attributes = _element._attributes;
     var values = new List<String>();
     for (int i = 0, len = attributes.length; i < len; i++) {
       if (_matches(attributes[i])) {
@@ -29490,7 +29532,7 @@
   _ElementAttributeMap(Element element): super(element);
 
   bool containsKey(String key) {
-    return _element.$dom_hasAttribute(key);
+    return _element._hasAttribute(key);
   }
 
   String operator [](String key) {
@@ -29503,7 +29545,7 @@
 
   String remove(String key) {
     String value = _element.$dom_getAttribute(key);
-    _element.$dom_removeAttribute(key);
+    _element._removeAttribute(key);
     return value;
   }
 
@@ -29514,7 +29556,7 @@
     return keys.length;
   }
 
-  bool _matches(Node node) => node.$dom_namespaceUri == null;
+  bool _matches(Node node) => node._namespaceUri == null;
 }
 
 /**
@@ -29527,7 +29569,7 @@
   _NamespacedAttributeMap(Element element, this._namespace): super(element);
 
   bool containsKey(String key) {
-    return _element.$dom_hasAttributeNS(_namespace, key);
+    return _element._hasAttributeNS(_namespace, key);
   }
 
   String operator [](String key) {
@@ -29540,7 +29582,7 @@
 
   String remove(String key) {
     String value = this[key];
-    _element.$dom_removeAttributeNS(_namespace, key);
+    _element._removeAttributeNS(_namespace, key);
     return value;
   }
 
@@ -29551,7 +29593,7 @@
     return keys.length;
   }
 
-  bool _matches(Node node) => node.$dom_namespaceUri == _namespace;
+  bool _matches(Node node) => node._namespaceUri == _namespace;
 }
 
 
@@ -29561,27 +29603,27 @@
  */
 class _DataAttributeMap implements Map<String, String> {
 
-  final Map<String, String> $dom_attributes;
+  final Map<String, String> _attributes;
 
-  _DataAttributeMap(this.$dom_attributes);
+  _DataAttributeMap(this._attributes);
 
   // interface Map
 
   // TODO: Use lazy iterator when it is available on Map.
   bool containsValue(String value) => values.any((v) => v == value);
 
-  bool containsKey(String key) => $dom_attributes.containsKey(_attr(key));
+  bool containsKey(String key) => _attributes.containsKey(_attr(key));
 
-  String operator [](String key) => $dom_attributes[_attr(key)];
+  String operator [](String key) => _attributes[_attr(key)];
 
   void operator []=(String key, String value) {
-    $dom_attributes[_attr(key)] = value;
+    _attributes[_attr(key)] = value;
   }
 
   String putIfAbsent(String key, String ifAbsent()) =>
-    $dom_attributes.putIfAbsent(_attr(key), ifAbsent);
+    _attributes.putIfAbsent(_attr(key), ifAbsent);
 
-  String remove(String key) => $dom_attributes.remove(_attr(key));
+  String remove(String key) => _attributes.remove(_attr(key));
 
   void clear() {
     // Needs to operate on a snapshot since we are mutating the collection.
@@ -29591,7 +29633,7 @@
   }
 
   void forEach(void f(String key, String value)) {
-    $dom_attributes.forEach((String key, String value) {
+    _attributes.forEach((String key, String value) {
       if (_matches(key)) {
         f(_strip(key), value);
       }
@@ -29600,7 +29642,7 @@
 
   Iterable<String> get keys {
     final keys = new List<String>();
-    $dom_attributes.forEach((String key, String value) {
+    _attributes.forEach((String key, String value) {
       if (_matches(key)) {
         keys.add(_strip(key));
       }
@@ -29610,7 +29652,7 @@
 
   Iterable<String> get values {
     final values = new List<String>();
-    $dom_attributes.forEach((String key, String value) {
+    _attributes.forEach((String key, String value) {
       if (_matches(key)) {
         values.add(value);
       }
@@ -30629,6 +30671,455 @@
     return _eventTypeGetter(target);
   }
 }
+// DO NOT EDIT- this file is generated from running tool/generator.sh.
+
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+/**
+ * A Dart DOM validator generated from Caja whitelists.
+ *
+ * This contains a whitelist of known HTML tagNames and attributes and will only
+ * accept known good values.
+ *
+ * See also:
+ *
+ * * <https://code.google.com/p/google-caja/wiki/CajaWhitelists>
+ */
+class _Html5NodeValidator implements NodeValidator {
+
+  static final Set<String> _allowedElements = new Set.from([
+    'A',
+    'ABBR',
+    'ACRONYM',
+    'ADDRESS',
+    'AREA',
+    'ARTICLE',
+    'ASIDE',
+    'AUDIO',
+    'B',
+    'BDI',
+    'BDO',
+    'BIG',
+    'BLOCKQUOTE',
+    'BR',
+    'BUTTON',
+    'CANVAS',
+    'CAPTION',
+    'CENTER',
+    'CITE',
+    'CODE',
+    'COL',
+    'COLGROUP',
+    'COMMAND',
+    'DATA',
+    'DATALIST',
+    'DD',
+    'DEL',
+    'DETAILS',
+    'DFN',
+    'DIR',
+    'DIV',
+    'DL',
+    'DT',
+    'EM',
+    'FIELDSET',
+    'FIGCAPTION',
+    'FIGURE',
+    'FONT',
+    'FOOTER',
+    'FORM',
+    'H1',
+    'H2',
+    'H3',
+    'H4',
+    'H5',
+    'H6',
+    'HEADER',
+    'HGROUP',
+    'HR',
+    'I',
+    'IFRAME',
+    'IMG',
+    'INPUT',
+    'INS',
+    'KBD',
+    'LABEL',
+    'LEGEND',
+    'LI',
+    'MAP',
+    'MARK',
+    'MENU',
+    'METER',
+    'NAV',
+    'NOBR',
+    'OL',
+    'OPTGROUP',
+    'OPTION',
+    'OUTPUT',
+    'P',
+    'PRE',
+    'PROGRESS',
+    'Q',
+    'S',
+    'SAMP',
+    'SECTION',
+    'SELECT',
+    'SMALL',
+    'SOURCE',
+    'SPAN',
+    'STRIKE',
+    'STRONG',
+    'SUB',
+    'SUMMARY',
+    'SUP',
+    'TABLE',
+    'TBODY',
+    'TD',
+    'TEXTAREA',
+    'TFOOT',
+    'TH',
+    'THEAD',
+    'TIME',
+    'TR',
+    'TRACK',
+    'TT',
+    'U',
+    'UL',
+    'VAR',
+    'VIDEO',
+    'WBR',
+  ]);
+
+  static const _standardAttributes = const <String>[
+    '*::class',
+    '*::dir',
+    '*::draggable',
+    '*::hidden',
+    '*::id',
+    '*::inert',
+    '*::itemprop',
+    '*::itemref',
+    '*::itemscope',
+    '*::lang',
+    '*::spellcheck',
+    '*::title',
+    '*::translate',
+    'A::accesskey',
+    'A::coords',
+    'A::hreflang',
+    'A::name',
+    'A::shape',
+    'A::tabindex',
+    'A::target',
+    'A::type',
+    'AREA::accesskey',
+    'AREA::alt',
+    'AREA::coords',
+    'AREA::nohref',
+    'AREA::shape',
+    'AREA::tabindex',
+    'AREA::target',
+    'AUDIO::controls',
+    'AUDIO::loop',
+    'AUDIO::mediagroup',
+    'AUDIO::muted',
+    'AUDIO::preload',
+    'BDO::dir',
+    'BODY::alink',
+    'BODY::bgcolor',
+    'BODY::link',
+    'BODY::text',
+    'BODY::vlink',
+    'BR::clear',
+    'BUTTON::accesskey',
+    'BUTTON::disabled',
+    'BUTTON::name',
+    'BUTTON::tabindex',
+    'BUTTON::type',
+    'BUTTON::value',
+    'CANVAS::height',
+    'CANVAS::width',
+    'CAPTION::align',
+    'COL::align',
+    'COL::char',
+    'COL::charoff',
+    'COL::span',
+    'COL::valign',
+    'COL::width',
+    'COLGROUP::align',
+    'COLGROUP::char',
+    'COLGROUP::charoff',
+    'COLGROUP::span',
+    'COLGROUP::valign',
+    'COLGROUP::width',
+    'COMMAND::checked',
+    'COMMAND::command',
+    'COMMAND::disabled',
+    'COMMAND::label',
+    'COMMAND::radiogroup',
+    'COMMAND::type',
+    'DATA::value',
+    'DEL::datetime',
+    'DETAILS::open',
+    'DIR::compact',
+    'DIV::align',
+    'DL::compact',
+    'FIELDSET::disabled',
+    'FONT::color',
+    'FONT::face',
+    'FONT::size',
+    'FORM::accept',
+    'FORM::autocomplete',
+    'FORM::enctype',
+    'FORM::method',
+    'FORM::name',
+    'FORM::novalidate',
+    'FORM::target',
+    'FRAME::name',
+    'H1::align',
+    'H2::align',
+    'H3::align',
+    'H4::align',
+    'H5::align',
+    'H6::align',
+    'HR::align',
+    'HR::noshade',
+    'HR::size',
+    'HR::width',
+    'HTML::version',
+    'IFRAME::align',
+    'IFRAME::frameborder',
+    'IFRAME::height',
+    'IFRAME::marginheight',
+    'IFRAME::marginwidth',
+    'IFRAME::width',
+    'IMG::align',
+    'IMG::alt',
+    'IMG::border',
+    'IMG::height',
+    'IMG::hspace',
+    'IMG::ismap',
+    'IMG::name',
+    'IMG::usemap',
+    'IMG::vspace',
+    'IMG::width',
+    'INPUT::accept',
+    'INPUT::accesskey',
+    'INPUT::align',
+    'INPUT::alt',
+    'INPUT::autocomplete',
+    'INPUT::checked',
+    'INPUT::disabled',
+    'INPUT::inputmode',
+    'INPUT::ismap',
+    'INPUT::list',
+    'INPUT::max',
+    'INPUT::maxlength',
+    'INPUT::min',
+    'INPUT::multiple',
+    'INPUT::name',
+    'INPUT::placeholder',
+    'INPUT::readonly',
+    'INPUT::required',
+    'INPUT::size',
+    'INPUT::step',
+    'INPUT::tabindex',
+    'INPUT::type',
+    'INPUT::usemap',
+    'INPUT::value',
+    'INS::datetime',
+    'KEYGEN::disabled',
+    'KEYGEN::keytype',
+    'KEYGEN::name',
+    'LABEL::accesskey',
+    'LABEL::for',
+    'LEGEND::accesskey',
+    'LEGEND::align',
+    'LI::type',
+    'LI::value',
+    'LINK::sizes',
+    'MAP::name',
+    'MENU::compact',
+    'MENU::label',
+    'MENU::type',
+    'METER::high',
+    'METER::low',
+    'METER::max',
+    'METER::min',
+    'METER::value',
+    'OBJECT::typemustmatch',
+    'OL::compact',
+    'OL::reversed',
+    'OL::start',
+    'OL::type',
+    'OPTGROUP::disabled',
+    'OPTGROUP::label',
+    'OPTION::disabled',
+    'OPTION::label',
+    'OPTION::selected',
+    'OPTION::value',
+    'OUTPUT::for',
+    'OUTPUT::name',
+    'P::align',
+    'PRE::width',
+    'PROGRESS::max',
+    'PROGRESS::min',
+    'PROGRESS::value',
+    'SELECT::autocomplete',
+    'SELECT::disabled',
+    'SELECT::multiple',
+    'SELECT::name',
+    'SELECT::required',
+    'SELECT::size',
+    'SELECT::tabindex',
+    'SOURCE::type',
+    'TABLE::align',
+    'TABLE::bgcolor',
+    'TABLE::border',
+    'TABLE::cellpadding',
+    'TABLE::cellspacing',
+    'TABLE::frame',
+    'TABLE::rules',
+    'TABLE::summary',
+    'TABLE::width',
+    'TBODY::align',
+    'TBODY::char',
+    'TBODY::charoff',
+    'TBODY::valign',
+    'TD::abbr',
+    'TD::align',
+    'TD::axis',
+    'TD::bgcolor',
+    'TD::char',
+    'TD::charoff',
+    'TD::colspan',
+    'TD::headers',
+    'TD::height',
+    'TD::nowrap',
+    'TD::rowspan',
+    'TD::scope',
+    'TD::valign',
+    'TD::width',
+    'TEXTAREA::accesskey',
+    'TEXTAREA::autocomplete',
+    'TEXTAREA::cols',
+    'TEXTAREA::disabled',
+    'TEXTAREA::inputmode',
+    'TEXTAREA::name',
+    'TEXTAREA::placeholder',
+    'TEXTAREA::readonly',
+    'TEXTAREA::required',
+    'TEXTAREA::rows',
+    'TEXTAREA::tabindex',
+    'TEXTAREA::wrap',
+    'TFOOT::align',
+    'TFOOT::char',
+    'TFOOT::charoff',
+    'TFOOT::valign',
+    'TH::abbr',
+    'TH::align',
+    'TH::axis',
+    'TH::bgcolor',
+    'TH::char',
+    'TH::charoff',
+    'TH::colspan',
+    'TH::headers',
+    'TH::height',
+    'TH::nowrap',
+    'TH::rowspan',
+    'TH::scope',
+    'TH::valign',
+    'TH::width',
+    'THEAD::align',
+    'THEAD::char',
+    'THEAD::charoff',
+    'THEAD::valign',
+    'TR::align',
+    'TR::bgcolor',
+    'TR::char',
+    'TR::charoff',
+    'TR::valign',
+    'TRACK::default',
+    'TRACK::kind',
+    'TRACK::label',
+    'TRACK::srclang',
+    'UL::compact',
+    'UL::type',
+    'VIDEO::controls',
+    'VIDEO::height',
+    'VIDEO::loop',
+    'VIDEO::mediagroup',
+    'VIDEO::muted',
+    'VIDEO::preload',
+    'VIDEO::width',
+  ];
+
+  static const _uriAttributes = const <String>[
+    'A::href',
+    'AREA::href',
+    'BLOCKQUOTE::cite',
+    'BODY::background',
+    'COMMAND::icon',
+    'DEL::cite',
+    'FORM::action',
+    'IMG::src',
+    'INPUT::src',
+    'INS::cite',
+    'Q::cite',
+    'VIDEO::poster',
+  ];
+
+  final UriPolicy uriPolicy;
+
+  static final Map<String, Function> _attributeValidators = {};
+
+  /**
+   * All known URI attributes will be validated against the UriPolicy, if
+   * [uriPolicy] is null then a default UriPolicy will be used.
+   */
+  _Html5NodeValidator({UriPolicy uriPolicy})
+      :uriPolicy = uriPolicy != null ? uriPolicy : new UriPolicy() {
+
+    if (_attributeValidators.isEmpty) {
+      for (var attr in _standardAttributes) {
+        _attributeValidators[attr] = _standardAttributeValidator;
+      }
+
+      for (var attr in _uriAttributes) {
+        _attributeValidators[attr] = _uriAttributeValidator;
+      }
+    }
+  }
+
+  bool allowsElement(Element element) {
+    return _allowedElements.contains(element.tagName);
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    var tagName = element.tagName;
+    var validator = _attributeValidators['$tagName::$attributeName'];
+    if (validator == null) {
+      validator = _attributeValidators['*::$attributeName'];
+    }
+    if (validator == null) {
+      return false;
+    }
+    return validator(element, attributeName, value, this);
+  }
+
+  static bool _standardAttributeValidator(Element element, String attributeName,
+      String value, _Html5NodeValidator context) {
+    return true;
+  }
+
+  static bool _uriAttributeValidator(Element element, String attributeName,
+      String value, _Html5NodeValidator context) {
+    return context.uriPolicy.allowsUri(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.
@@ -30710,404 +31201,222 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-/**
- * Internal class that does the actual calculations to determine keyCode and
- * charCode for keydown, keypress, and keyup events for all browsers.
- */
-class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
-  // This code inspired by Closure's KeyHandling library.
-  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html
+_serialize(var message) {
+  return new _JsSerializer().traverse(message);
+}
 
-  /**
-   * The set of keys that have been pressed down without seeing their
-   * corresponding keyup event.
-   */
-  final List<KeyboardEvent> _keyDownList = <KeyboardEvent>[];
+class _JsSerializer extends _Serializer {
 
-  /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
-  final String _type;
-
-  /** The element we are watching for events to happen on. */
-  final EventTarget _target;
-
-  // The distance to shift from upper case alphabet Roman letters to lower case.
-  static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];
-
-  /** Controller to produce KeyEvents for the stream. */
-  final StreamController _controller = new StreamController(sync: true);
-
-  static const _EVENT_TYPE = 'KeyEvent';
-
-  /**
-   * An enumeration of key identifiers currently part of the W3C draft for DOM3
-   * and their mappings to keyCodes.
-   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
-   */
-  static const Map<String, int> _keyIdentifier = const {
-    'Up': KeyCode.UP,
-    'Down': KeyCode.DOWN,
-    'Left': KeyCode.LEFT,
-    'Right': KeyCode.RIGHT,
-    'Enter': KeyCode.ENTER,
-    'F1': KeyCode.F1,
-    'F2': KeyCode.F2,
-    'F3': KeyCode.F3,
-    'F4': KeyCode.F4,
-    'F5': KeyCode.F5,
-    'F6': KeyCode.F6,
-    'F7': KeyCode.F7,
-    'F8': KeyCode.F8,
-    'F9': KeyCode.F9,
-    'F10': KeyCode.F10,
-    'F11': KeyCode.F11,
-    'F12': KeyCode.F12,
-    'U+007F': KeyCode.DELETE,
-    'Home': KeyCode.HOME,
-    'End': KeyCode.END,
-    'PageUp': KeyCode.PAGE_UP,
-    'PageDown': KeyCode.PAGE_DOWN,
-    'Insert': KeyCode.INSERT
-  };
-
-  /** Return a stream for KeyEvents for the specified target. */
-  Stream<KeyEvent> forTarget(EventTarget e, {bool useCapture: false}) {
-    return new _KeyboardEventHandler.initializeAllEventListeners(
-        _type, e).stream;
+  visitSendPortSync(SendPortSync x) {
+    if (x is _JsSendPortSync) return visitJsSendPortSync(x);
+    if (x is _LocalSendPortSync) return visitLocalSendPortSync(x);
+    if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x);
+    throw "Unknown port type $x";
   }
 
-  /**
-   * Accessor to the stream associated with a particular KeyboardEvent
-   * EventTarget.
-   *
-   * [forTarget] must be called to initialize this stream to listen to a
-   * particular EventTarget.
-   */
-  Stream<KeyEvent> get stream {
-    if(_target != null) {
-      return _controller.stream;
+  visitJsSendPortSync(_JsSendPortSync x) {
+    return [ 'sendport', 'nativejs', x._id ];
+  }
+
+  visitLocalSendPortSync(_LocalSendPortSync x) {
+    return [ 'sendport', 'dart',
+             ReceivePortSync._isolateId, x._receivePort._portId ];
+  }
+
+  visitSendPort(SendPort x) {
+    throw new UnimplementedError('Asynchronous send port not yet implemented.');
+  }
+
+  visitRemoteSendPortSync(_RemoteSendPortSync x) {
+    return [ 'sendport', 'dart', x._isolateId, x._portId ];
+  }
+}
+
+_deserialize(var message) {
+  return new _JsDeserializer().deserialize(message);
+}
+
+
+class _JsDeserializer extends _Deserializer {
+
+  static const _UNSPECIFIED = const Object();
+
+  deserializeSendPort(List x) {
+    String tag = x[1];
+    switch (tag) {
+      case 'nativejs':
+        num id = x[2];
+        return new _JsSendPortSync(id);
+      case 'dart':
+        num isolateId = x[2];
+        num portId = x[3];
+        return ReceivePortSync._lookup(isolateId, portId);
+      default:
+        throw 'Illegal SendPortSync type: $tag';
+    }
+  }
+}
+
+// The receiver is JS.
+class _JsSendPortSync implements SendPortSync {
+
+  final num _id;
+  _JsSendPortSync(this._id);
+
+  callSync(var message) {
+    var serialized = _serialize(message);
+    var result = _callPortSync(_id, serialized);
+    return _deserialize(result);
+  }
+
+  bool operator==(var other) {
+    return (other is _JsSendPortSync) && (_id == other._id);
+  }
+
+  int get hashCode => _id;
+}
+
+// TODO(vsm): Differentiate between Dart2Js and Dartium isolates.
+// The receiver is a different Dart isolate, compiled to JS.
+class _RemoteSendPortSync implements SendPortSync {
+
+  int _isolateId;
+  int _portId;
+  _RemoteSendPortSync(this._isolateId, this._portId);
+
+  callSync(var message) {
+    var serialized = _serialize(message);
+    var result = _call(_isolateId, _portId, serialized);
+    return _deserialize(result);
+  }
+
+  static _call(int isolateId, int portId, var message) {
+    var target = 'dart-port-$isolateId-$portId';
+    // TODO(vsm): Make this re-entrant.
+    // TODO(vsm): Set this up set once, on the first call.
+    var source = '$target-result';
+    var result = null;
+    window.on[source].first.then((Event e) {
+      result = json.parse(_getPortSyncEventData(e));
+    });
+    _dispatchEvent(target, [source, message]);
+    return result;
+  }
+
+  bool operator==(var other) {
+    return (other is _RemoteSendPortSync) && (_isolateId == other._isolateId)
+      && (_portId == other._portId);
+  }
+
+  int get hashCode => _isolateId >> 16 + _portId;
+}
+
+// The receiver is in the same Dart isolate, compiled to JS.
+class _LocalSendPortSync implements SendPortSync {
+
+  ReceivePortSync _receivePort;
+
+  _LocalSendPortSync._internal(this._receivePort);
+
+  callSync(var message) {
+    // TODO(vsm): Do a more efficient deep copy.
+    var copy = _deserialize(_serialize(message));
+    var result = _receivePort._callback(copy);
+    return _deserialize(_serialize(result));
+  }
+
+  bool operator==(var other) {
+    return (other is _LocalSendPortSync)
+      && (_receivePort == other._receivePort);
+  }
+
+  int get hashCode => _receivePort.hashCode;
+}
+
+// TODO(vsm): Move this to dart:isolate.  This will take some
+// refactoring as there are dependences here on the DOM.  Users
+// interact with this class (or interface if we change it) directly -
+// new ReceivePortSync.  I think most of the DOM logic could be
+// delayed until the corresponding SendPort is registered on the
+// window.
+
+// A Dart ReceivePortSync (tagged 'dart' when serialized) is
+// identifiable / resolvable by the combination of its isolateid and
+// portid.  When a corresponding SendPort is used within the same
+// isolate, the _portMap below can be used to obtain the
+// ReceivePortSync directly.  Across isolates (or from JS), an
+// EventListener can be used to communicate with the port indirectly.
+class ReceivePortSync {
+
+  static Map<int, ReceivePortSync> _portMap;
+  static int _portIdCount;
+  static int _cachedIsolateId;
+
+  num _portId;
+  Function _callback;
+  StreamSubscription _portSubscription;
+
+  ReceivePortSync() {
+    if (_portIdCount == null) {
+      _portIdCount = 0;
+      _portMap = new Map<int, ReceivePortSync>();
+    }
+    _portId = _portIdCount++;
+    _portMap[_portId] = this;
+  }
+
+  static int get _isolateId {
+    // TODO(vsm): Make this coherent with existing isolate code.
+    if (_cachedIsolateId == null) {
+      _cachedIsolateId = _getNewIsolateId();
+    }
+    return _cachedIsolateId;
+  }
+
+  static String _getListenerName(isolateId, portId) =>
+      'dart-port-$isolateId-$portId';
+  String get _listenerName => _getListenerName(_isolateId, _portId);
+
+  void receive(callback(var message)) {
+    _callback = callback;
+    if (_portSubscription == null) {
+      _portSubscription = window.on[_listenerName].listen((Event e) {
+        var data = json.parse(_getPortSyncEventData(e));
+        var replyTo = data[0];
+        var message = _deserialize(data[1]);
+        var result = _callback(message);
+        _dispatchEvent(replyTo, _serialize(result));
+      });
+    }
+  }
+
+  void close() {
+    _portMap.remove(_portId);
+    if (_portSubscription != null) _portSubscription.cancel();
+  }
+
+  SendPortSync toSendPort() {
+    return new _LocalSendPortSync._internal(this);
+  }
+
+  static SendPortSync _lookup(int isolateId, int portId) {
+    if (isolateId == _isolateId) {
+      return _portMap[portId].toSendPort();
     } else {
-      throw new StateError("Not initialized. Call forTarget to access a stream "
-          "initialized with a particular EventTarget.");
+      return new _RemoteSendPortSync(isolateId, portId);
     }
   }
-
-  /**
-   * General constructor, performs basic initialization for our improved
-   * KeyboardEvent controller.
-   */
-  _KeyboardEventHandler(this._type) :
-    _target = null, super(_EVENT_TYPE) {
-  }
-
-  /**
-   * Hook up all event listeners under the covers so we can estimate keycodes
-   * and charcodes when they are not provided.
-   */
-  _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target) :
-    super(_EVENT_TYPE) {
-    Element.keyDownEvent.forTarget(_target, useCapture: true).listen(
-        processKeyDown);
-    Element.keyPressEvent.forTarget(_target, useCapture: true).listen(
-        processKeyPress);
-    Element.keyUpEvent.forTarget(_target, useCapture: true).listen(
-        processKeyUp);
-  }
-
-  /**
-   * Notify all callback listeners that a KeyEvent of the relevant type has
-   * occurred.
-   */
-  bool _dispatch(KeyEvent event) {
-    if (event.type == _type)
-      _controller.add(event);
-  }
-
-  /** Determine if caps lock is one of the currently depressed keys. */
-  bool get _capsLockOn =>
-      _keyDownList.any((var element) => element.keyCode == KeyCode.CAPS_LOCK);
-
-  /**
-   * Given the previously recorded keydown key codes, see if we can determine
-   * the keycode of this keypress [event]. (Generally browsers only provide
-   * charCode information for keypress events, but with a little
-   * reverse-engineering, we can also determine the keyCode.) Returns
-   * KeyCode.UNKNOWN if the keycode could not be determined.
-   */
-  int _determineKeyCodeForKeypress(KeyboardEvent event) {
-    // Note: This function is a work in progress. We'll expand this function
-    // once we get more information about other keyboards.
-    for (var prevEvent in _keyDownList) {
-      if (prevEvent._shadowCharCode == event.charCode) {
-        return prevEvent.keyCode;
-      }
-      if ((event.shiftKey || _capsLockOn) && event.charCode >= "A".codeUnits[0]
-          && event.charCode <= "Z".codeUnits[0] && event.charCode +
-          _ROMAN_ALPHABET_OFFSET == prevEvent._shadowCharCode) {
-        return prevEvent.keyCode;
-      }
-    }
-    return KeyCode.UNKNOWN;
-  }
-
-  /**
-   * Given the charater code returned from a keyDown [event], try to ascertain
-   * and return the corresponding charCode for the character that was pressed.
-   * This information is not shown to the user, but used to help polyfill
-   * keypress events.
-   */
-  int _findCharCodeKeyDown(KeyboardEvent event) {
-    if (event.keyLocation == 3) { // Numpad keys.
-      switch (event.keyCode) {
-        case KeyCode.NUM_ZERO:
-          // Even though this function returns _charCodes_, for some cases the
-          // KeyCode == the charCode we want, in which case we use the keycode
-          // constant for readability.
-          return KeyCode.ZERO;
-        case KeyCode.NUM_ONE:
-          return KeyCode.ONE;
-        case KeyCode.NUM_TWO:
-          return KeyCode.TWO;
-        case KeyCode.NUM_THREE:
-          return KeyCode.THREE;
-        case KeyCode.NUM_FOUR:
-          return KeyCode.FOUR;
-        case KeyCode.NUM_FIVE:
-          return KeyCode.FIVE;
-        case KeyCode.NUM_SIX:
-          return KeyCode.SIX;
-        case KeyCode.NUM_SEVEN:
-          return KeyCode.SEVEN;
-        case KeyCode.NUM_EIGHT:
-          return KeyCode.EIGHT;
-        case KeyCode.NUM_NINE:
-          return KeyCode.NINE;
-        case KeyCode.NUM_MULTIPLY:
-          return 42; // Char code for *
-        case KeyCode.NUM_PLUS:
-          return 43; // +
-        case KeyCode.NUM_MINUS:
-          return 45; // -
-        case KeyCode.NUM_PERIOD:
-          return 46; // .
-        case KeyCode.NUM_DIVISION:
-          return 47; // /
-      }
-    } else if (event.keyCode >= 65 && event.keyCode <= 90) {
-      // Set the "char code" for key down as the lower case letter. Again, this
-      // will not show up for the user, but will be helpful in estimating
-      // keyCode locations and other information during the keyPress event.
-      return event.keyCode + _ROMAN_ALPHABET_OFFSET;
-    }
-    switch(event.keyCode) {
-      case KeyCode.SEMICOLON:
-        return KeyCode.FF_SEMICOLON;
-      case KeyCode.EQUALS:
-        return KeyCode.FF_EQUALS;
-      case KeyCode.COMMA:
-        return 44; // Ascii value for ,
-      case KeyCode.DASH:
-        return 45; // -
-      case KeyCode.PERIOD:
-        return 46; // .
-      case KeyCode.SLASH:
-        return 47; // /
-      case KeyCode.APOSTROPHE:
-        return 96; // `
-      case KeyCode.OPEN_SQUARE_BRACKET:
-        return 91; // [
-      case KeyCode.BACKSLASH:
-        return 92; // \
-      case KeyCode.CLOSE_SQUARE_BRACKET:
-        return 93; // ]
-      case KeyCode.SINGLE_QUOTE:
-        return 39; // '
-    }
-    return event.keyCode;
-  }
-
-  /**
-   * Returns true if the key fires a keypress event in the current browser.
-   */
-  bool _firesKeyPressEvent(KeyEvent event) {
-    if (!Device.isIE && !Device.isWebKit) {
-      return true;
-    }
-
-    if (Device.userAgent.contains('Mac') && event.altKey) {
-      return KeyCode.isCharacterKey(event.keyCode);
-    }
-
-    // Alt but not AltGr which is represented as Alt+Ctrl.
-    if (event.altKey && !event.ctrlKey) {
-      return false;
-    }
-
-    // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
-    if (!event.shiftKey &&
-        (_keyDownList.last.keyCode == KeyCode.CTRL ||
-         _keyDownList.last.keyCode == KeyCode.ALT ||
-         Device.userAgent.contains('Mac') &&
-         _keyDownList.last.keyCode == KeyCode.META)) {
-      return false;
-    }
-
-    // Some keys with Ctrl/Shift do not issue keypress in WebKit.
-    if (Device.isWebKit && event.ctrlKey && event.shiftKey && (
-        event.keyCode == KeyCode.BACKSLASH ||
-        event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
-        event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
-        event.keyCode == KeyCode.TILDE ||
-        event.keyCode == KeyCode.SEMICOLON || event.keyCode == KeyCode.DASH ||
-        event.keyCode == KeyCode.EQUALS || event.keyCode == KeyCode.COMMA ||
-        event.keyCode == KeyCode.PERIOD || event.keyCode == KeyCode.SLASH ||
-        event.keyCode == KeyCode.APOSTROPHE ||
-        event.keyCode == KeyCode.SINGLE_QUOTE)) {
-      return false;
-    }
-
-    switch (event.keyCode) {
-      case KeyCode.ENTER:
-        // IE9 does not fire keypress on ENTER.
-        return !Device.isIE;
-      case KeyCode.ESC:
-        return !Device.isWebKit;
-    }
-
-    return KeyCode.isCharacterKey(event.keyCode);
-  }
-
-  /**
-   * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
-   * Opera all use).
-   */
-  int _normalizeKeyCodes(KeyboardEvent event) {
-    // Note: This may change once we get input about non-US keyboards.
-    if (Device.isFirefox) {
-      switch(event.keyCode) {
-        case KeyCode.FF_EQUALS:
-          return KeyCode.EQUALS;
-        case KeyCode.FF_SEMICOLON:
-          return KeyCode.SEMICOLON;
-        case KeyCode.MAC_FF_META:
-          return KeyCode.META;
-        case KeyCode.WIN_KEY_FF_LINUX:
-          return KeyCode.WIN_KEY;
-      }
-    }
-    return event.keyCode;
-  }
-
-  /** Handle keydown events. */
-  void processKeyDown(KeyboardEvent e) {
-    // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
-    // before we've caught a key-up event.  If the last-key was one of these
-    // we reset the state.
-    if (_keyDownList.length > 0 &&
-        (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
-         _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
-         Device.userAgent.contains('Mac') &&
-         _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
-      _keyDownList.clear();
-    }
-
-    var event = new KeyEvent(e);
-    event._shadowKeyCode = _normalizeKeyCodes(event);
-    // Technically a "keydown" event doesn't have a charCode. This is
-    // calculated nonetheless to provide us with more information in giving
-    // as much information as possible on keypress about keycode and also
-    // charCode.
-    event._shadowCharCode = _findCharCodeKeyDown(event);
-    if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode &&
-        !_firesKeyPressEvent(event)) {
-      // Some browsers have quirks not firing keypress events where all other
-      // browsers do. This makes them more consistent.
-      processKeyPress(e);
-    }
-    _keyDownList.add(event);
-    _dispatch(event);
-  }
-
-  /** Handle keypress events. */
-  void processKeyPress(KeyboardEvent event) {
-    var e = new KeyEvent(event);
-    // IE reports the character code in the keyCode field for keypress events.
-    // There are two exceptions however, Enter and Escape.
-    if (Device.isIE) {
-      if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
-        e._shadowCharCode = 0;
-      } else {
-        e._shadowCharCode = e.keyCode;
-      }
-    } else if (Device.isOpera) {
-      // Opera reports the character code in the keyCode field.
-      e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
-    }
-    // Now we guestimate about what the keycode is that was actually
-    // pressed, given previous keydown information.
-    e._shadowKeyCode = _determineKeyCodeForKeypress(e);
-
-    // Correct the key value for certain browser-specific quirks.
-    if (e._shadowKeyIdentifier != null &&
-        _keyIdentifier.containsKey(e._shadowKeyIdentifier)) {
-      // This is needed for Safari Windows because it currently doesn't give a
-      // keyCode/which for non printable keys.
-      e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier];
-    }
-    e._shadowAltKey = _keyDownList.any((var element) => element.altKey);
-    _dispatch(e);
-  }
-
-  /** Handle keyup events. */
-  void processKeyUp(KeyboardEvent event) {
-    var e = new KeyEvent(event);
-    KeyboardEvent toRemove = null;
-    for (var key in _keyDownList) {
-      if (key.keyCode == e.keyCode) {
-        toRemove = key;
-      }
-    }
-    if (toRemove != null) {
-      _keyDownList.removeWhere((element) => element == toRemove);
-    } else if (_keyDownList.length > 0) {
-      // This happens when we've reached some international keyboard case we
-      // haven't accounted for or we haven't correctly eliminated all browser
-      // inconsistencies. Filing bugs on when this is reached is welcome!
-      _keyDownList.removeLast();
-    }
-    _dispatch(e);
-  }
 }
 
+get _isolateId => ReceivePortSync._isolateId;
 
-/**
- * Records KeyboardEvents that occur on a particular element, and provides a
- * stream of outgoing KeyEvents with cross-browser consistent keyCode and
- * charCode values despite the fact that a multitude of browsers that have
- * varying keyboard default behavior.
- *
- * Example usage:
- *
- *     KeyboardEventStream.onKeyDown(document.body).listen(
- *         keydownHandlerTest);
- *
- * This class is very much a work in progress, and we'd love to get information
- * on how we can make this class work with as many international keyboards as
- * possible. Bugs welcome!
- */
-class KeyboardEventStream {
-
-  /** Named constructor to produce a stream for onKeyPress events. */
-  static Stream<KeyEvent> onKeyPress(EventTarget target) =>
-      new _KeyboardEventHandler('keypress').forTarget(target);
-
-  /** Named constructor to produce a stream for onKeyUp events. */
-  static Stream<KeyEvent> onKeyUp(EventTarget target) =>
-      new _KeyboardEventHandler('keyup').forTarget(target);
-
-  /** Named constructor to produce a stream for onKeyDown events. */
-  static Stream<KeyEvent> onKeyDown(EventTarget target) =>
-    new _KeyboardEventHandler('keydown').forTarget(target);
+void _dispatchEvent(String receiver, var message) {
+  var event = new CustomEvent(receiver, canBubble: false, cancelable:false,
+    detail: json.stringify(message));
+  window.dispatchEvent(event);
 }
+
+String _getPortSyncEventData(CustomEvent event) => event.detail;
 // Copyright (c) 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.
@@ -31875,6 +32184,1016 @@
    */
   static const String UNIDENTIFIED = "Unidentified";
 }
+// Copyright (c) 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.
+
+
+/**
+ * Internal class that does the actual calculations to determine keyCode and
+ * charCode for keydown, keypress, and keyup events for all browsers.
+ */
+class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
+  // This code inspired by Closure's KeyHandling library.
+  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html
+
+  /**
+   * The set of keys that have been pressed down without seeing their
+   * corresponding keyup event.
+   */
+  final List<KeyboardEvent> _keyDownList = <KeyboardEvent>[];
+
+  /** The type of KeyEvent we are tracking (keyup, keydown, keypress). */
+  final String _type;
+
+  /** The element we are watching for events to happen on. */
+  final EventTarget _target;
+
+  // The distance to shift from upper case alphabet Roman letters to lower case.
+  static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];
+
+  /** Controller to produce KeyEvents for the stream. */
+  final StreamController _controller = new StreamController(sync: true);
+
+  static const _EVENT_TYPE = 'KeyEvent';
+
+  /**
+   * An enumeration of key identifiers currently part of the W3C draft for DOM3
+   * and their mappings to keyCodes.
+   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
+   */
+  static const Map<String, int> _keyIdentifier = const {
+    'Up': KeyCode.UP,
+    'Down': KeyCode.DOWN,
+    'Left': KeyCode.LEFT,
+    'Right': KeyCode.RIGHT,
+    'Enter': KeyCode.ENTER,
+    'F1': KeyCode.F1,
+    'F2': KeyCode.F2,
+    'F3': KeyCode.F3,
+    'F4': KeyCode.F4,
+    'F5': KeyCode.F5,
+    'F6': KeyCode.F6,
+    'F7': KeyCode.F7,
+    'F8': KeyCode.F8,
+    'F9': KeyCode.F9,
+    'F10': KeyCode.F10,
+    'F11': KeyCode.F11,
+    'F12': KeyCode.F12,
+    'U+007F': KeyCode.DELETE,
+    'Home': KeyCode.HOME,
+    'End': KeyCode.END,
+    'PageUp': KeyCode.PAGE_UP,
+    'PageDown': KeyCode.PAGE_DOWN,
+    'Insert': KeyCode.INSERT
+  };
+
+  /** Return a stream for KeyEvents for the specified target. */
+  Stream<KeyEvent> forTarget(EventTarget e, {bool useCapture: false}) {
+    return new _KeyboardEventHandler.initializeAllEventListeners(
+        _type, e).stream;
+  }
+
+  /**
+   * Accessor to the stream associated with a particular KeyboardEvent
+   * EventTarget.
+   *
+   * [forTarget] must be called to initialize this stream to listen to a
+   * particular EventTarget.
+   */
+  Stream<KeyEvent> get stream {
+    if(_target != null) {
+      return _controller.stream;
+    } else {
+      throw new StateError("Not initialized. Call forTarget to access a stream "
+          "initialized with a particular EventTarget.");
+    }
+  }
+
+  /**
+   * General constructor, performs basic initialization for our improved
+   * KeyboardEvent controller.
+   */
+  _KeyboardEventHandler(this._type) :
+    _target = null, super(_EVENT_TYPE) {
+  }
+
+  /**
+   * Hook up all event listeners under the covers so we can estimate keycodes
+   * and charcodes when they are not provided.
+   */
+  _KeyboardEventHandler.initializeAllEventListeners(this._type, this._target) :
+    super(_EVENT_TYPE) {
+    Element.keyDownEvent.forTarget(_target, useCapture: true).listen(
+        processKeyDown);
+    Element.keyPressEvent.forTarget(_target, useCapture: true).listen(
+        processKeyPress);
+    Element.keyUpEvent.forTarget(_target, useCapture: true).listen(
+        processKeyUp);
+  }
+
+  /**
+   * Notify all callback listeners that a KeyEvent of the relevant type has
+   * occurred.
+   */
+  bool _dispatch(KeyEvent event) {
+    if (event.type == _type)
+      _controller.add(event);
+  }
+
+  /** Determine if caps lock is one of the currently depressed keys. */
+  bool get _capsLockOn =>
+      _keyDownList.any((var element) => element.keyCode == KeyCode.CAPS_LOCK);
+
+  /**
+   * Given the previously recorded keydown key codes, see if we can determine
+   * the keycode of this keypress [event]. (Generally browsers only provide
+   * charCode information for keypress events, but with a little
+   * reverse-engineering, we can also determine the keyCode.) Returns
+   * KeyCode.UNKNOWN if the keycode could not be determined.
+   */
+  int _determineKeyCodeForKeypress(KeyboardEvent event) {
+    // Note: This function is a work in progress. We'll expand this function
+    // once we get more information about other keyboards.
+    for (var prevEvent in _keyDownList) {
+      if (prevEvent._shadowCharCode == event.charCode) {
+        return prevEvent.keyCode;
+      }
+      if ((event.shiftKey || _capsLockOn) && event.charCode >= "A".codeUnits[0]
+          && event.charCode <= "Z".codeUnits[0] && event.charCode +
+          _ROMAN_ALPHABET_OFFSET == prevEvent._shadowCharCode) {
+        return prevEvent.keyCode;
+      }
+    }
+    return KeyCode.UNKNOWN;
+  }
+
+  /**
+   * Given the charater code returned from a keyDown [event], try to ascertain
+   * and return the corresponding charCode for the character that was pressed.
+   * This information is not shown to the user, but used to help polyfill
+   * keypress events.
+   */
+  int _findCharCodeKeyDown(KeyboardEvent event) {
+    if (event.keyLocation == 3) { // Numpad keys.
+      switch (event.keyCode) {
+        case KeyCode.NUM_ZERO:
+          // Even though this function returns _charCodes_, for some cases the
+          // KeyCode == the charCode we want, in which case we use the keycode
+          // constant for readability.
+          return KeyCode.ZERO;
+        case KeyCode.NUM_ONE:
+          return KeyCode.ONE;
+        case KeyCode.NUM_TWO:
+          return KeyCode.TWO;
+        case KeyCode.NUM_THREE:
+          return KeyCode.THREE;
+        case KeyCode.NUM_FOUR:
+          return KeyCode.FOUR;
+        case KeyCode.NUM_FIVE:
+          return KeyCode.FIVE;
+        case KeyCode.NUM_SIX:
+          return KeyCode.SIX;
+        case KeyCode.NUM_SEVEN:
+          return KeyCode.SEVEN;
+        case KeyCode.NUM_EIGHT:
+          return KeyCode.EIGHT;
+        case KeyCode.NUM_NINE:
+          return KeyCode.NINE;
+        case KeyCode.NUM_MULTIPLY:
+          return 42; // Char code for *
+        case KeyCode.NUM_PLUS:
+          return 43; // +
+        case KeyCode.NUM_MINUS:
+          return 45; // -
+        case KeyCode.NUM_PERIOD:
+          return 46; // .
+        case KeyCode.NUM_DIVISION:
+          return 47; // /
+      }
+    } else if (event.keyCode >= 65 && event.keyCode <= 90) {
+      // Set the "char code" for key down as the lower case letter. Again, this
+      // will not show up for the user, but will be helpful in estimating
+      // keyCode locations and other information during the keyPress event.
+      return event.keyCode + _ROMAN_ALPHABET_OFFSET;
+    }
+    switch(event.keyCode) {
+      case KeyCode.SEMICOLON:
+        return KeyCode.FF_SEMICOLON;
+      case KeyCode.EQUALS:
+        return KeyCode.FF_EQUALS;
+      case KeyCode.COMMA:
+        return 44; // Ascii value for ,
+      case KeyCode.DASH:
+        return 45; // -
+      case KeyCode.PERIOD:
+        return 46; // .
+      case KeyCode.SLASH:
+        return 47; // /
+      case KeyCode.APOSTROPHE:
+        return 96; // `
+      case KeyCode.OPEN_SQUARE_BRACKET:
+        return 91; // [
+      case KeyCode.BACKSLASH:
+        return 92; // \
+      case KeyCode.CLOSE_SQUARE_BRACKET:
+        return 93; // ]
+      case KeyCode.SINGLE_QUOTE:
+        return 39; // '
+    }
+    return event.keyCode;
+  }
+
+  /**
+   * Returns true if the key fires a keypress event in the current browser.
+   */
+  bool _firesKeyPressEvent(KeyEvent event) {
+    if (!Device.isIE && !Device.isWebKit) {
+      return true;
+    }
+
+    if (Device.userAgent.contains('Mac') && event.altKey) {
+      return KeyCode.isCharacterKey(event.keyCode);
+    }
+
+    // Alt but not AltGr which is represented as Alt+Ctrl.
+    if (event.altKey && !event.ctrlKey) {
+      return false;
+    }
+
+    // Saves Ctrl or Alt + key for IE and WebKit, which won't fire keypress.
+    if (!event.shiftKey &&
+        (_keyDownList.last.keyCode == KeyCode.CTRL ||
+         _keyDownList.last.keyCode == KeyCode.ALT ||
+         Device.userAgent.contains('Mac') &&
+         _keyDownList.last.keyCode == KeyCode.META)) {
+      return false;
+    }
+
+    // Some keys with Ctrl/Shift do not issue keypress in WebKit.
+    if (Device.isWebKit && event.ctrlKey && event.shiftKey && (
+        event.keyCode == KeyCode.BACKSLASH ||
+        event.keyCode == KeyCode.OPEN_SQUARE_BRACKET ||
+        event.keyCode == KeyCode.CLOSE_SQUARE_BRACKET ||
+        event.keyCode == KeyCode.TILDE ||
+        event.keyCode == KeyCode.SEMICOLON || event.keyCode == KeyCode.DASH ||
+        event.keyCode == KeyCode.EQUALS || event.keyCode == KeyCode.COMMA ||
+        event.keyCode == KeyCode.PERIOD || event.keyCode == KeyCode.SLASH ||
+        event.keyCode == KeyCode.APOSTROPHE ||
+        event.keyCode == KeyCode.SINGLE_QUOTE)) {
+      return false;
+    }
+
+    switch (event.keyCode) {
+      case KeyCode.ENTER:
+        // IE9 does not fire keypress on ENTER.
+        return !Device.isIE;
+      case KeyCode.ESC:
+        return !Device.isWebKit;
+    }
+
+    return KeyCode.isCharacterKey(event.keyCode);
+  }
+
+  /**
+   * Normalize the keycodes to the IE KeyCodes (this is what Chrome, IE, and
+   * Opera all use).
+   */
+  int _normalizeKeyCodes(KeyboardEvent event) {
+    // Note: This may change once we get input about non-US keyboards.
+    if (Device.isFirefox) {
+      switch(event.keyCode) {
+        case KeyCode.FF_EQUALS:
+          return KeyCode.EQUALS;
+        case KeyCode.FF_SEMICOLON:
+          return KeyCode.SEMICOLON;
+        case KeyCode.MAC_FF_META:
+          return KeyCode.META;
+        case KeyCode.WIN_KEY_FF_LINUX:
+          return KeyCode.WIN_KEY;
+      }
+    }
+    return event.keyCode;
+  }
+
+  /** Handle keydown events. */
+  void processKeyDown(KeyboardEvent e) {
+    // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
+    // before we've caught a key-up event.  If the last-key was one of these
+    // we reset the state.
+    if (_keyDownList.length > 0 &&
+        (_keyDownList.last.keyCode == KeyCode.CTRL && !e.ctrlKey ||
+         _keyDownList.last.keyCode == KeyCode.ALT && !e.altKey ||
+         Device.userAgent.contains('Mac') &&
+         _keyDownList.last.keyCode == KeyCode.META && !e.metaKey)) {
+      _keyDownList.clear();
+    }
+
+    var event = new KeyEvent(e);
+    event._shadowKeyCode = _normalizeKeyCodes(event);
+    // Technically a "keydown" event doesn't have a charCode. This is
+    // calculated nonetheless to provide us with more information in giving
+    // as much information as possible on keypress about keycode and also
+    // charCode.
+    event._shadowCharCode = _findCharCodeKeyDown(event);
+    if (_keyDownList.length > 0 && event.keyCode != _keyDownList.last.keyCode &&
+        !_firesKeyPressEvent(event)) {
+      // Some browsers have quirks not firing keypress events where all other
+      // browsers do. This makes them more consistent.
+      processKeyPress(e);
+    }
+    _keyDownList.add(event);
+    _dispatch(event);
+  }
+
+  /** Handle keypress events. */
+  void processKeyPress(KeyboardEvent event) {
+    var e = new KeyEvent(event);
+    // IE reports the character code in the keyCode field for keypress events.
+    // There are two exceptions however, Enter and Escape.
+    if (Device.isIE) {
+      if (e.keyCode == KeyCode.ENTER || e.keyCode == KeyCode.ESC) {
+        e._shadowCharCode = 0;
+      } else {
+        e._shadowCharCode = e.keyCode;
+      }
+    } else if (Device.isOpera) {
+      // Opera reports the character code in the keyCode field.
+      e._shadowCharCode = KeyCode.isCharacterKey(e.keyCode) ? e.keyCode : 0;
+    }
+    // Now we guestimate about what the keycode is that was actually
+    // pressed, given previous keydown information.
+    e._shadowKeyCode = _determineKeyCodeForKeypress(e);
+
+    // Correct the key value for certain browser-specific quirks.
+    if (e._shadowKeyIdentifier != null &&
+        _keyIdentifier.containsKey(e._shadowKeyIdentifier)) {
+      // This is needed for Safari Windows because it currently doesn't give a
+      // keyCode/which for non printable keys.
+      e._shadowKeyCode = _keyIdentifier[e._shadowKeyIdentifier];
+    }
+    e._shadowAltKey = _keyDownList.any((var element) => element.altKey);
+    _dispatch(e);
+  }
+
+  /** Handle keyup events. */
+  void processKeyUp(KeyboardEvent event) {
+    var e = new KeyEvent(event);
+    KeyboardEvent toRemove = null;
+    for (var key in _keyDownList) {
+      if (key.keyCode == e.keyCode) {
+        toRemove = key;
+      }
+    }
+    if (toRemove != null) {
+      _keyDownList.removeWhere((element) => element == toRemove);
+    } else if (_keyDownList.length > 0) {
+      // This happens when we've reached some international keyboard case we
+      // haven't accounted for or we haven't correctly eliminated all browser
+      // inconsistencies. Filing bugs on when this is reached is welcome!
+      _keyDownList.removeLast();
+    }
+    _dispatch(e);
+  }
+}
+
+
+/**
+ * Records KeyboardEvents that occur on a particular element, and provides a
+ * stream of outgoing KeyEvents with cross-browser consistent keyCode and
+ * charCode values despite the fact that a multitude of browsers that have
+ * varying keyboard default behavior.
+ *
+ * Example usage:
+ *
+ *     KeyboardEventStream.onKeyDown(document.body).listen(
+ *         keydownHandlerTest);
+ *
+ * This class is very much a work in progress, and we'd love to get information
+ * on how we can make this class work with as many international keyboards as
+ * possible. Bugs welcome!
+ */
+class KeyboardEventStream {
+
+  /** Named constructor to produce a stream for onKeyPress events. */
+  static Stream<KeyEvent> onKeyPress(EventTarget target) =>
+      new _KeyboardEventHandler('keypress').forTarget(target);
+
+  /** Named constructor to produce a stream for onKeyUp events. */
+  static Stream<KeyEvent> onKeyUp(EventTarget target) =>
+      new _KeyboardEventHandler('keyup').forTarget(target);
+
+  /** Named constructor to produce a stream for onKeyDown events. */
+  static Stream<KeyEvent> onKeyDown(EventTarget target) =>
+    new _KeyboardEventHandler('keydown').forTarget(target);
+}
+// Copyright (c) 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 _MicrotaskCallback();
+
+/**
+ * This class attempts to invoke a callback as soon as the current event stack
+ * unwinds, but before the browser repaints.
+ */
+abstract class _MicrotaskScheduler {
+  bool _nextMicrotaskFrameScheduled = false;
+  final _MicrotaskCallback _callback;
+
+  _MicrotaskScheduler(this._callback);
+
+  /**
+   * Creates the best possible microtask scheduler for the current platform.
+   */
+  factory _MicrotaskScheduler.best(_MicrotaskCallback callback) {
+    if (Window._supportsSetImmediate) {
+      return new _SetImmediateScheduler(callback);
+    } else if (MutationObserver.supported) {
+      return new _MutationObserverScheduler(callback);
+    }
+    return new _PostMessageScheduler(callback);
+  }
+
+  /**
+   * Schedules a microtask callback if one has not been scheduled already.
+   */
+  void maybeSchedule() {
+    if (this._nextMicrotaskFrameScheduled) {
+      return;
+    }
+    this._nextMicrotaskFrameScheduled = true;
+    this._schedule();
+  }
+
+  /**
+   * Does the actual scheduling of the callback.
+   */
+  void _schedule();
+
+  /**
+   * Handles the microtask callback and forwards it if necessary.
+   */
+  void _onCallback() {
+    // Ignore spurious messages.
+    if (!_nextMicrotaskFrameScheduled) {
+      return;
+    }
+    _nextMicrotaskFrameScheduled = false;
+    this._callback();
+  }
+}
+
+/**
+ * Scheduler which uses window.postMessage to schedule events.
+ */
+class _PostMessageScheduler extends _MicrotaskScheduler {
+  const _MICROTASK_MESSAGE = "DART-MICROTASK";
+
+  _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
+      // Messages from other windows do not cause a security risk as
+      // all we care about is that _handleMessage is called
+      // after the current event loop is unwound and calling the function is
+      // a noop when zero requests are pending.
+      window.onMessage.listen(this._handleMessage);
+  }
+
+  void _schedule() {
+    window.postMessage(_MICROTASK_MESSAGE, "*");
+  }
+
+  void _handleMessage(e) {
+    this._onCallback();
+  }
+}
+
+/**
+ * Scheduler which uses a MutationObserver to schedule events.
+ */
+class _MutationObserverScheduler extends _MicrotaskScheduler {
+  MutationObserver _observer;
+  Element _dummy;
+
+  _MutationObserverScheduler(_MicrotaskCallback callback): super(callback) {
+    // Mutation events get fired as soon as the current event stack is unwound
+    // so we just make a dummy event and listen for that.
+    _observer = new MutationObserver(this._handleMutation);
+    _dummy = new DivElement();
+    _observer.observe(_dummy, attributes: true);
+  }
+
+  void _schedule() {
+    // Toggle it to trigger the mutation event.
+    _dummy.hidden = !_dummy.hidden;
+  }
+
+  _handleMutation(List<MutationRecord> mutations, MutationObserver observer) {
+    this._onCallback();
+  }
+}
+
+/**
+ * Scheduler which uses window.setImmediate to schedule events.
+ */
+class _SetImmediateScheduler extends _MicrotaskScheduler {
+  _SetImmediateScheduler(_MicrotaskCallback callback): super(callback);
+
+  void _schedule() {
+    window._setImmediate(_handleImmediate);
+  }
+
+  void _handleImmediate() {
+    this._onCallback();
+  }
+}
+
+List<TimeoutHandler> _pendingMicrotasks;
+_MicrotaskScheduler _microtaskScheduler = null;
+
+void _maybeScheduleMicrotaskFrame() {
+  if (_microtaskScheduler == null) {
+    _microtaskScheduler =
+      new _MicrotaskScheduler.best(_completeMicrotasks);
+  }
+  _microtaskScheduler.maybeSchedule();
+}
+
+/**
+ * Registers a [callback] which is called after the current execution stack
+ * unwinds.
+ */
+void _addMicrotaskCallback(TimeoutHandler callback) {
+  if (_pendingMicrotasks == null) {
+    _pendingMicrotasks = <TimeoutHandler>[];
+    _maybeScheduleMicrotaskFrame();
+  }
+  _pendingMicrotasks.add(callback);
+}
+
+
+/**
+ * Complete all pending microtasks.
+ */
+void _completeMicrotasks() {
+  var callbacks = _pendingMicrotasks;
+  _pendingMicrotasks = null;
+  for (var callback in callbacks) {
+    callback();
+  }
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+
+/**
+ * Class which helps construct standard node validation policies.
+ *
+ * By default this will not accept anything, but the 'allow*' functions can be
+ * used to expand what types of elements or attributes are allowed.
+ *
+ * All allow functions are additive- elements will be accepted if they are
+ * accepted by any specific rule.
+ *
+ * It is important to remember that sanitization is not just intended to prevent
+ * cross-site scripting attacks, but also to prevent information from being
+ * displayed in unexpected ways. For example something displaying basic
+ * formatted text may not expect `<video>` tags to appear. In this case an
+ * empty NodeValidatorBuilder with just [allowTextElements] might be
+ * appropriate.
+ */
+class NodeValidatorBuilder implements NodeValidator {
+
+  final List<NodeValidator> _validators = <NodeValidator>[];
+
+  NodeValidatorBuilder() {
+  }
+
+  /**
+   * Creates a new NodeValidatorBuilder which accepts common constructs.
+   *
+   * By default this will accept HTML5 elements and attributes with the default
+   * [UriPolicy] and templating elements.
+   *
+   * Notable syntax which is filtered:
+   *
+   * * Only known-good HTML5 elements and attributes are allowed.
+   * * All URLs must be same-origin, use [allowNavigation] and [allowImages] to
+   * specify additional URI policies.
+   * * Inline-styles are not allowed.
+   * * Custom element tags are disallowed, use [allowCustomElement].
+   * * Custom tags extensions are disallowed, use [allowTagExtension].
+   * * SVG Elements are not allowed, use [allowSvg].
+   *
+   * For scenarios where the HTML should only contain formatted text
+   * [allowTextElements] is more appropriate.
+   *
+   * Use [allowSvg] to allow SVG elements.
+   */
+  NodeValidatorBuilder.common() {
+    allowHtml5();
+    allowTemplating();
+  }
+
+  /**
+   * Allows navigation elements- Form and Anchor tags, along with common
+   * attributes.
+   *
+   * The UriPolicy can be used to restrict the locations the navigation elements
+   * are allowed to direct to. By default this will use the default [UriPolicy].
+   */
+  void allowNavigation([UriPolicy uriPolicy]) {
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+    add(new _SimpleNodeValidator.allowNavigation(uriPolicy));
+  }
+
+  /**
+   * Allows image elements.
+   *
+   * The UriPolicy can be used to restrict the locations the images may be
+   * loaded from. By default this will use the default [UriPolicy].
+   */
+  void allowImages([UriPolicy uriPolicy]) {
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+    add(new _SimpleNodeValidator.allowImages(uriPolicy));
+  }
+
+  /**
+   * Allow basic text elements.
+   *
+   * This allows a subset of HTML5 elements, specifically just these tags and
+   * no attributes.
+   *
+   * * B
+   * * BLOCKQUOTE
+   * * BR
+   * * EM
+   * * H1
+   * * H2
+   * * H3
+   * * H4
+   * * H5
+   * * H6
+   * * HR
+   * * I
+   * * LI
+   * * OL
+   * * P
+   * * SPAN
+   * * UL
+   */
+  void allowTextElements() {
+    add(new _SimpleNodeValidator.allowTextElements());
+  }
+
+  /**
+   * Allow common safe HTML5 elements and attributes.
+   *
+   * This list is based off of the Caja whitelists at:
+   * https://code.google.com/p/google-caja/wiki/CajaWhitelists.
+   *
+   * Common things which are not allowed are script elements, style attributes
+   * and any script handlers.
+   */
+  void allowHtml5({UriPolicy uriPolicy}) {
+    add(new _Html5NodeValidator(uriPolicy: uriPolicy));
+  }
+
+  /**
+   * Allow SVG elements and attributes except for known bad ones.
+   */
+  void allowSvg() {
+    add(new _SvgNodeValidator());
+  }
+
+  /**
+   * Allow custom elements with the specified tag name and specified attributes.
+   *
+   * This will allow the elements as custom tags (such as <x-foo></x-foo>),
+   * but will not allow tag extensions. Use [allowTagExtension] to allow
+   * tag extensions.
+   */
+  void allowCustomElement(String tagName,
+      {UriPolicy uriPolicy,
+      Iterable<String> attributes,
+      Iterable<String> uriAttributes}) {
+
+    var tagNameUpper = tagName.toUpperCase();
+    var attrs;
+    if (attributes != null) {
+      attrs =
+          attributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
+    }
+    var uriAttrs;
+    if (uriAttributes != null) {
+      uriAttrs =
+          uriAttributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
+    }
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+
+    add(new _CustomElementNodeValidator(
+        uriPolicy,
+        [tagNameUpper],
+        attrs,
+        uriAttrs,
+        false,
+        true));
+  }
+
+  /**
+   * Allow custom tag extensions with the specified type name and specified
+   * attributes.
+   *
+   * This will allow tag extensions (such as <div is="x-foo"></div>),
+   * but will not allow custom tags. Use [allowCustomElement] to allow
+   * custom tags.
+   */
+  void allowTagExtension(String tagName, String baseName,
+      {UriPolicy uriPolicy,
+      Iterable<String> attributes,
+      Iterable<String> uriAttributes}) {
+
+    var baseNameUpper = baseName.toUpperCase();
+    var tagNameUpper = tagName.toUpperCase();
+    var attrs;
+    if (attributes != null) {
+      attrs =
+          attributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
+    }
+    var uriAttrs;
+    if (uriAttributes != null) {
+      uriAttrs =
+          uriAttributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
+    }
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+
+    add(new _CustomElementNodeValidator(
+        uriPolicy,
+        [tagNameUpper, baseNameUpper],
+        attrs,
+        uriAttrs,
+        true,
+        false));
+  }
+
+  void allowElement(String tagName, {UriPolicy uriPolicy,
+    Iterable<String> attributes,
+    Iterable<String> uriAttributes}) {
+
+    allowCustomElement(tagName, uriPolicy: uriPolicy,
+        attributes: attributes,
+        uriAttributes: uriAttributes);
+  }
+
+  /**
+   * Allow templating elements (such as <template> and template-related
+   * attributes.
+   *
+   * This still requires other validators to allow regular attributes to be
+   * bound (such as [allowHtml5]).
+   */
+  void allowTemplating() {
+    add(new _TemplatingNodeValidator());
+  }
+
+  /**
+   * Add an additional validator to the current list of validators.
+   *
+   * Elements and attributes will be accepted if they are accepted by any
+   * validators.
+   */
+  void add(NodeValidator validator) {
+    _validators.add(validator);
+  }
+
+  bool allowsElement(Element element) {
+    return _validators.any((v) => v.allowsElement(element));
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    return _validators.any(
+        (v) => v.allowsAttribute(element, attributeName, value));
+  }
+}
+
+class _SimpleNodeValidator implements NodeValidator {
+  final Set<String> allowedElements;
+  final Set<String> allowedAttributes;
+  final Set<String> allowedUriAttributes;
+  final UriPolicy uriPolicy;
+
+  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
+    return new _SimpleNodeValidator(uriPolicy,
+      allowedElements: [
+        'A',
+        'FORM'],
+      allowedAttributes: [
+        'A::accesskey',
+        'A::coords',
+        'A::hreflang',
+        'A::name',
+        'A::shape',
+        'A::tabindex',
+        'A::target',
+        'A::type',
+        'FORM::accept',
+        'FORM::autocomplete',
+        'FORM::enctype',
+        'FORM::method',
+        'FORM::name',
+        'FORM::novalidate',
+        'FORM::target',
+      ],
+      allowedUriAttributes: [
+        'A::href',
+        'FORM::action',
+      ]);
+  }
+
+  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
+    return new _SimpleNodeValidator(uriPolicy,
+      allowedElements: [
+        'IMG'
+      ],
+      allowedAttributes: [
+        'IMG::align',
+        'IMG::alt',
+        'IMG::border',
+        'IMG::height',
+        'IMG::hspace',
+        'IMG::ismap',
+        'IMG::name',
+        'IMG::usemap',
+        'IMG::vspace',
+        'IMG::width',
+      ],
+      allowedUriAttributes: [
+        'IMG::src',
+      ]);
+  }
+
+  factory _SimpleNodeValidator.allowTextElements() {
+    return new _SimpleNodeValidator(null,
+      allowedElements: [
+        'B',
+        'BLOCKQUOTE',
+        'BR',
+        'EM',
+        'H1',
+        'H2',
+        'H3',
+        'H4',
+        'H5',
+        'H6',
+        'HR',
+        'I',
+        'LI',
+        'OL',
+        'P',
+        'SPAN',
+        'UL',
+      ]);
+  }
+
+  /**
+   * Elements must be uppercased tag names. For example `'IMG'`.
+   * Attributes must be uppercased tag name followed by :: followed by
+   * lowercase attribute name. For example `'IMG:src'`.
+   */
+  _SimpleNodeValidator(this.uriPolicy,
+      {Iterable<String> allowedElements, Iterable<String> allowedAttributes,
+      Iterable<String> allowedUriAttributes}):
+      this.allowedElements = allowedElements != null ?
+          new Set.from(allowedElements) : new Set(),
+      this.allowedAttributes = allowedAttributes != null ?
+          new Set.from(allowedAttributes) : new Set(),
+      this.allowedUriAttributes = allowedUriAttributes != null ?
+          new Set.from(allowedUriAttributes) : new Set();
+
+  bool allowsElement(Element element) {
+    return allowedElements.contains(element.tagName);
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    var tagName = element.tagName;
+    if (allowedUriAttributes.contains('$tagName::$attributeName')) {
+      return uriPolicy.allowsUri(value);
+    } else if (allowedUriAttributes.contains('*::$attributeName')) {
+      return uriPolicy.allowsUri(value);
+    } else if (allowedAttributes.contains('$tagName::$attributeName')) {
+      return true;
+    } else if (allowedAttributes.contains('*::$attributeName')) {
+      return true;
+    } else if (allowedAttributes.contains('$tagName::*')) {
+      return true;
+    } else if (allowedAttributes.contains('*::*')) {
+      return true;
+    }
+    return false;
+  }
+}
+
+class _CustomElementNodeValidator extends _SimpleNodeValidator {
+  final bool allowTypeExtension;
+  final bool allowCustomTag;
+
+  _CustomElementNodeValidator(UriPolicy uriPolicy,
+      Iterable<String> allowedElements,
+      Iterable<String> allowedAttributes,
+      Iterable<String> allowedUriAttributes,
+      bool allowTypeExtension,
+      bool allowCustomTag):
+
+      super(uriPolicy,
+          allowedElements: allowedElements,
+          allowedAttributes: allowedAttributes,
+          allowedUriAttributes: allowedUriAttributes),
+      this.allowTypeExtension = allowTypeExtension == true,
+      this.allowCustomTag = allowCustomTag == true;
+
+  bool allowsElement(Element element) {
+    if (allowTypeExtension) {
+      var isAttr = element.attributes['is'];
+      if (isAttr != null) {
+        return allowedElements.contains(isAttr.toUpperCase()) &&
+          allowedElements.contains(element.tagName);
+      }
+    }
+    return allowCustomTag && allowedElements.contains(element.tagName);
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+   if (allowsElement(element)) {
+      if (allowTypeExtension && attributeName == 'is' &&
+          allowedElements.contains(value.toUpperCase())) {
+        return true;
+      }
+      return super.allowsAttribute(element, attributeName, value);
+    }
+    return false;
+  }
+}
+
+class _TemplatingNodeValidator extends _SimpleNodeValidator {
+  static const _TEMPLATE_ATTRS =
+      const <String>['bind', 'if', 'ref', 'repeat', 'syntax'];
+
+  final Set<String> _templateAttrs;
+
+  _TemplatingNodeValidator():
+      super(null,
+          allowedElements: [
+            'TEMPLATE'
+          ],
+          allowedAttributes: _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')),
+      _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS) {
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (super.allowsAttribute(element, attributeName, value)) {
+      return true;
+    }
+
+    if (attributeName == 'template' && value == "") {
+      return true;
+    }
+
+    if (element.attributes['template'] == "" ) {
+      return _templateAttrs.contains(attributeName);
+    }
+    return false;
+  }
+}
+
+
+class _SvgNodeValidator implements NodeValidator {
+  bool allowsElement(Element element) {
+    if (element is svg.ScriptElement) {
+      return false;
+    }
+    if (element is svg.SvgElement) {
+      return true;
+    }
+    return false;
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (attributeName == 'is' || attributeName.startsWith('on')) {
+      return false;
+    }
+    return allowsElement(element);
+  }
+}
 // 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.
@@ -32128,671 +33447,6 @@
     return new Rect(left, top, width, height);
   }
 }
-// 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.
-
-
-/**
- * Helper class to implement custom events which wrap DOM events.
- */
-class _WrappedEvent implements Event {
-  final Event wrapped;
-  _WrappedEvent(this.wrapped);
-
-  bool get bubbles => wrapped.bubbles;
-
-  bool get cancelBubble => wrapped.bubbles;
-  void set cancelBubble(bool value) {
-    wrapped.cancelBubble = value;
-  }
-
-  bool get cancelable => wrapped.cancelable;
-
-  DataTransfer get clipboardData => wrapped.clipboardData;
-
-  EventTarget get currentTarget => wrapped.currentTarget;
-
-  bool get defaultPrevented => wrapped.defaultPrevented;
-
-  int get eventPhase => wrapped.eventPhase;
-
-  EventTarget get target => wrapped.target;
-
-  int get timeStamp => wrapped.timeStamp;
-
-  String get type => wrapped.type;
-
-  void $dom_initEvent(String eventTypeArg, bool canBubbleArg,
-      bool cancelableArg) {
-    throw new UnsupportedError(
-        'Cannot initialize this Event.');
-  }
-
-  void preventDefault() {
-    wrapped.preventDefault();
-  }
-
-  void stopImmediatePropagation() {
-    wrapped.stopImmediatePropagation();
-  }
-
-  void stopPropagation() {
-    wrapped.stopPropagation();
-  }
-}
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-/**
- * A list which just wraps another list, for either intercepting list calls or
- * retyping the list (for example, from List<A> to List<B> where B extends A).
- */
-class _WrappedList<E> extends ListBase<E> {
-  final List _list;
-
-  _WrappedList(this._list);
-
-  // Iterable APIs
-
-  Iterator<E> get iterator => new _WrappedIterator(_list.iterator);
-
-  int get length => _list.length;
-
-  // Collection APIs
-
-  void add(E element) { _list.add(element); }
-
-  bool remove(Object element) => _list.remove(element);
-
-  void clear() { _list.clear(); }
-
-  // List APIs
-
-  E operator [](int index) => _list[index];
-
-  void operator []=(int index, E value) { _list[index] = value; }
-
-  void set length(int newLength) { _list.length = newLength; }
-
-  void sort([int compare(E a, E b)]) { _list.sort(compare); }
-
-  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);
-
-  int lastIndexOf(Object element, [int start]) => _list.lastIndexOf(element, start);
-
-  void insert(int index, E element) => _list.insert(index, element);
-
-  E removeAt(int index) => _list.removeAt(index);
-
-  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
-    _list.setRange(start, end, iterable, skipCount);
-  }
-
-  void removeRange(int start, int end) { _list.removeRange(start, end); }
-
-  void replaceRange(int start, int end, Iterable<E> iterable) {
-    _list.replaceRange(start, end, iterable);
-  }
-
-  void fillRange(int start, int end, [E fillValue]) {
-    _list.fillRange(start, end, fillValue);
-  }
-}
-
-/**
- * Iterator wrapper for _WrappedList.
- */
-class _WrappedIterator<E> implements Iterator<E> {
-  Iterator _iterator;
-
-  _WrappedIterator(this._iterator);
-
-  bool moveNext() {
-    return _iterator.moveNext();
-  }
-
-  E get current => _iterator.current;
-}
-// Copyright (c) 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 _HttpRequestUtils {
-
-  // Helper for factory HttpRequest.get
-  static HttpRequest get(String url,
-                            onComplete(HttpRequest request),
-                            bool withCredentials) {
-    final request = new HttpRequest();
-    request.open('GET', url, async: true);
-
-    request.withCredentials = withCredentials;
-
-    request.onReadyStateChange.listen((e) {
-      if (request.readyState == HttpRequest.DONE) {
-        onComplete(request);
-      }
-    });
-
-    request.send();
-
-    return request;
-  }
-}
-/**
- * A custom KeyboardEvent that attempts to eliminate cross-browser
- * inconsistencies, and also provide both keyCode and charCode information
- * for all key events (when such information can be determined).
- *
- * KeyEvent tries to provide a higher level, more polished keyboard event
- * information on top of the "raw" [KeyboardEvent].
- *
- * This class is very much a work in progress, and we'd love to get information
- * on how we can make this class work with as many international keyboards as
- * possible. Bugs welcome!
- */
-
-class KeyEvent extends _WrappedEvent implements KeyboardEvent {
-  /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
-  KeyboardEvent _parent;
-
-  /** The "fixed" value of whether the alt key is being pressed. */
-  bool _shadowAltKey;
-
-  /** Caculated value of what the estimated charCode is for this event. */
-  int _shadowCharCode;
-
-  /** Caculated value of what the estimated keyCode is for this event. */
-  int _shadowKeyCode;
-
-  /** Caculated value of what the estimated keyCode is for this event. */
-  int get keyCode => _shadowKeyCode;
-
-  /** Caculated value of what the estimated charCode is for this event. */
-  int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;
-
-  /** Caculated value of whether the alt key is pressed is for this event. */
-  bool get altKey => _shadowAltKey;
-
-  /** Caculated value of what the estimated keyCode is for this event. */
-  int get which => keyCode;
-
-  /** Accessor to the underlying keyCode value is the parent event. */
-  int get _realKeyCode => _parent.keyCode;
-
-  /** Accessor to the underlying charCode value is the parent event. */
-  int get _realCharCode => _parent.charCode;
-
-  /** Accessor to the underlying altKey value is the parent event. */
-  bool get _realAltKey => _parent.altKey;
-
-  /** Construct a KeyEvent with [parent] as the event we're emulating. */
-  KeyEvent(KeyboardEvent parent): super(parent) {
-    _parent = parent;
-    _shadowAltKey = _realAltKey;
-    _shadowCharCode = _realCharCode;
-    _shadowKeyCode = _realKeyCode;
-  }
-
-  /** Accessor to provide a stream of KeyEvents on the desired target. */
-  static EventStreamProvider<KeyEvent> keyDownEvent =
-    new _KeyboardEventHandler('keydown');
-  /** Accessor to provide a stream of KeyEvents on the desired target. */
-  static EventStreamProvider<KeyEvent> keyUpEvent =
-    new _KeyboardEventHandler('keyup');
-  /** Accessor to provide a stream of KeyEvents on the desired target. */
-  static EventStreamProvider<KeyEvent> keyPressEvent =
-    new _KeyboardEventHandler('keypress');
-
-  /** True if the altGraphKey is pressed during this event. */
-  bool get altGraphKey => _parent.altGraphKey;
-  /** Accessor to the clipboardData available for this event. */
-  DataTransfer get clipboardData => _parent.clipboardData;
-  /** True if the ctrl key is pressed during this event. */
-  bool get ctrlKey => _parent.ctrlKey;
-  int get detail => _parent.detail;
-  /**
-   * Accessor to the part of the keyboard that the key was pressed from (one of
-   * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
-   * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
-   */
-  int get keyLocation => _parent.keyLocation;
-  Point get layer => _parent.layer;
-  /** True if the Meta (or Mac command) key is pressed during this event. */
-  bool get metaKey => _parent.metaKey;
-  Point get page => _parent.page;
-  /** True if the shift key was pressed during this event. */
-  bool get shiftKey => _parent.shiftKey;
-  Window get view => _parent.view;
-  void $dom_initUIEvent(String type, bool canBubble, bool cancelable,
-      Window view, int detail) {
-    throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
-  }
-  String get _shadowKeyIdentifier => _parent.$dom_keyIdentifier;
-
-  int get $dom_charCode => charCode;
-  int get $dom_keyCode => keyCode;
-  String get $dom_keyIdentifier {
-    throw new UnsupportedError("keyIdentifier is unsupported.");
-  }
-  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) {
-    throw new UnsupportedError(
-        "Cannot initialize a KeyboardEvent from a KeyEvent.");
-  }
-}
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-class Platform {
-  /**
-   * Returns true if dart:typed_data types are supported on this
-   * browser.  If false, using these types will generate a runtime
-   * error.
-   */
-  static final supportsTypedData = true;
-
-  /**
-   * Returns true if SIMD types in dart:typed_data types are supported
-   * on this browser.  If false, using these types will generate a runtime
-   * error.
-   */
-  static final supportsSimd = true;
-
-  /**
-   * Upgrade all custom elements in the subtree which have not been upgraded.
-   *
-   * This is needed to cover timing scenarios which the custom element polyfill
-   * does not cover.
-   */
-  void upgradeCustomElements(Node node) {
-    // no-op, provided for dart2js polyfill.
-  }
-}
-// Copyright (c) 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.
-
-
-_serialize(var message) {
-  return new _JsSerializer().traverse(message);
-}
-
-class _JsSerializer extends _Serializer {
-
-  visitSendPortSync(SendPortSync x) {
-    if (x is _JsSendPortSync) return visitJsSendPortSync(x);
-    if (x is _LocalSendPortSync) return visitLocalSendPortSync(x);
-    if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x);
-    throw "Unknown port type $x";
-  }
-
-  visitJsSendPortSync(_JsSendPortSync x) {
-    return [ 'sendport', 'nativejs', x._id ];
-  }
-
-  visitLocalSendPortSync(_LocalSendPortSync x) {
-    return [ 'sendport', 'dart',
-             ReceivePortSync._isolateId, x._receivePort._portId ];
-  }
-
-  visitSendPort(SendPort x) {
-    throw new UnimplementedError('Asynchronous send port not yet implemented.');
-  }
-
-  visitRemoteSendPortSync(_RemoteSendPortSync x) {
-    return [ 'sendport', 'dart', x._isolateId, x._portId ];
-  }
-}
-
-_deserialize(var message) {
-  return new _JsDeserializer().deserialize(message);
-}
-
-
-class _JsDeserializer extends _Deserializer {
-
-  static const _UNSPECIFIED = const Object();
-
-  deserializeSendPort(List x) {
-    String tag = x[1];
-    switch (tag) {
-      case 'nativejs':
-        num id = x[2];
-        return new _JsSendPortSync(id);
-      case 'dart':
-        num isolateId = x[2];
-        num portId = x[3];
-        return ReceivePortSync._lookup(isolateId, portId);
-      default:
-        throw 'Illegal SendPortSync type: $tag';
-    }
-  }
-}
-
-// The receiver is JS.
-class _JsSendPortSync implements SendPortSync {
-
-  final num _id;
-  _JsSendPortSync(this._id);
-
-  callSync(var message) {
-    var serialized = _serialize(message);
-    var result = _callPortSync(_id, serialized);
-    return _deserialize(result);
-  }
-
-  bool operator==(var other) {
-    return (other is _JsSendPortSync) && (_id == other._id);
-  }
-
-  int get hashCode => _id;
-}
-
-// TODO(vsm): Differentiate between Dart2Js and Dartium isolates.
-// The receiver is a different Dart isolate, compiled to JS.
-class _RemoteSendPortSync implements SendPortSync {
-
-  int _isolateId;
-  int _portId;
-  _RemoteSendPortSync(this._isolateId, this._portId);
-
-  callSync(var message) {
-    var serialized = _serialize(message);
-    var result = _call(_isolateId, _portId, serialized);
-    return _deserialize(result);
-  }
-
-  static _call(int isolateId, int portId, var message) {
-    var target = 'dart-port-$isolateId-$portId';
-    // TODO(vsm): Make this re-entrant.
-    // TODO(vsm): Set this up set once, on the first call.
-    var source = '$target-result';
-    var result = null;
-    window.on[source].first.then((Event e) {
-      result = json.parse(_getPortSyncEventData(e));
-    });
-    _dispatchEvent(target, [source, message]);
-    return result;
-  }
-
-  bool operator==(var other) {
-    return (other is _RemoteSendPortSync) && (_isolateId == other._isolateId)
-      && (_portId == other._portId);
-  }
-
-  int get hashCode => _isolateId >> 16 + _portId;
-}
-
-// The receiver is in the same Dart isolate, compiled to JS.
-class _LocalSendPortSync implements SendPortSync {
-
-  ReceivePortSync _receivePort;
-
-  _LocalSendPortSync._internal(this._receivePort);
-
-  callSync(var message) {
-    // TODO(vsm): Do a more efficient deep copy.
-    var copy = _deserialize(_serialize(message));
-    var result = _receivePort._callback(copy);
-    return _deserialize(_serialize(result));
-  }
-
-  bool operator==(var other) {
-    return (other is _LocalSendPortSync)
-      && (_receivePort == other._receivePort);
-  }
-
-  int get hashCode => _receivePort.hashCode;
-}
-
-// TODO(vsm): Move this to dart:isolate.  This will take some
-// refactoring as there are dependences here on the DOM.  Users
-// interact with this class (or interface if we change it) directly -
-// new ReceivePortSync.  I think most of the DOM logic could be
-// delayed until the corresponding SendPort is registered on the
-// window.
-
-// A Dart ReceivePortSync (tagged 'dart' when serialized) is
-// identifiable / resolvable by the combination of its isolateid and
-// portid.  When a corresponding SendPort is used within the same
-// isolate, the _portMap below can be used to obtain the
-// ReceivePortSync directly.  Across isolates (or from JS), an
-// EventListener can be used to communicate with the port indirectly.
-class ReceivePortSync {
-
-  static Map<int, ReceivePortSync> _portMap;
-  static int _portIdCount;
-  static int _cachedIsolateId;
-
-  num _portId;
-  Function _callback;
-  StreamSubscription _portSubscription;
-
-  ReceivePortSync() {
-    if (_portIdCount == null) {
-      _portIdCount = 0;
-      _portMap = new Map<int, ReceivePortSync>();
-    }
-    _portId = _portIdCount++;
-    _portMap[_portId] = this;
-  }
-
-  static int get _isolateId {
-    // TODO(vsm): Make this coherent with existing isolate code.
-    if (_cachedIsolateId == null) {
-      _cachedIsolateId = _getNewIsolateId();
-    }
-    return _cachedIsolateId;
-  }
-
-  static String _getListenerName(isolateId, portId) =>
-      'dart-port-$isolateId-$portId';
-  String get _listenerName => _getListenerName(_isolateId, _portId);
-
-  void receive(callback(var message)) {
-    _callback = callback;
-    if (_portSubscription == null) {
-      _portSubscription = window.on[_listenerName].listen((Event e) {
-        var data = json.parse(_getPortSyncEventData(e));
-        var replyTo = data[0];
-        var message = _deserialize(data[1]);
-        var result = _callback(message);
-        _dispatchEvent(replyTo, _serialize(result));
-      });
-    }
-  }
-
-  void close() {
-    _portMap.remove(_portId);
-    if (_portSubscription != null) _portSubscription.cancel();
-  }
-
-  SendPortSync toSendPort() {
-    return new _LocalSendPortSync._internal(this);
-  }
-
-  static SendPortSync _lookup(int isolateId, int portId) {
-    if (isolateId == _isolateId) {
-      return _portMap[portId].toSendPort();
-    } else {
-      return new _RemoteSendPortSync(isolateId, portId);
-    }
-  }
-}
-
-get _isolateId => ReceivePortSync._isolateId;
-
-void _dispatchEvent(String receiver, var message) {
-  var event = new CustomEvent(receiver, canBubble: false, cancelable:false,
-    detail: json.stringify(message));
-  window.dispatchEvent(event);
-}
-
-String _getPortSyncEventData(CustomEvent event) => event.detail;
-// Copyright (c) 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 _MicrotaskCallback();
-
-/**
- * This class attempts to invoke a callback as soon as the current event stack
- * unwinds, but before the browser repaints.
- */
-abstract class _MicrotaskScheduler {
-  bool _nextMicrotaskFrameScheduled = false;
-  final _MicrotaskCallback _callback;
-
-  _MicrotaskScheduler(this._callback);
-
-  /**
-   * Creates the best possible microtask scheduler for the current platform.
-   */
-  factory _MicrotaskScheduler.best(_MicrotaskCallback callback) {
-    if (Window._supportsSetImmediate) {
-      return new _SetImmediateScheduler(callback);
-    } else if (MutationObserver.supported) {
-      return new _MutationObserverScheduler(callback);
-    }
-    return new _PostMessageScheduler(callback);
-  }
-
-  /**
-   * Schedules a microtask callback if one has not been scheduled already.
-   */
-  void maybeSchedule() {
-    if (this._nextMicrotaskFrameScheduled) {
-      return;
-    }
-    this._nextMicrotaskFrameScheduled = true;
-    this._schedule();
-  }
-
-  /**
-   * Does the actual scheduling of the callback.
-   */
-  void _schedule();
-
-  /**
-   * Handles the microtask callback and forwards it if necessary.
-   */
-  void _onCallback() {
-    // Ignore spurious messages.
-    if (!_nextMicrotaskFrameScheduled) {
-      return;
-    }
-    _nextMicrotaskFrameScheduled = false;
-    this._callback();
-  }
-}
-
-/**
- * Scheduler which uses window.postMessage to schedule events.
- */
-class _PostMessageScheduler extends _MicrotaskScheduler {
-  const _MICROTASK_MESSAGE = "DART-MICROTASK";
-
-  _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
-      // Messages from other windows do not cause a security risk as
-      // all we care about is that _handleMessage is called
-      // after the current event loop is unwound and calling the function is
-      // a noop when zero requests are pending.
-      window.onMessage.listen(this._handleMessage);
-  }
-
-  void _schedule() {
-    window.postMessage(_MICROTASK_MESSAGE, "*");
-  }
-
-  void _handleMessage(e) {
-    this._onCallback();
-  }
-}
-
-/**
- * Scheduler which uses a MutationObserver to schedule events.
- */
-class _MutationObserverScheduler extends _MicrotaskScheduler {
-  MutationObserver _observer;
-  Element _dummy;
-
-  _MutationObserverScheduler(_MicrotaskCallback callback): super(callback) {
-    // Mutation events get fired as soon as the current event stack is unwound
-    // so we just make a dummy event and listen for that.
-    _observer = new MutationObserver(this._handleMutation);
-    _dummy = new DivElement();
-    _observer.observe(_dummy, attributes: true);
-  }
-
-  void _schedule() {
-    // Toggle it to trigger the mutation event.
-    _dummy.hidden = !_dummy.hidden;
-  }
-
-  _handleMutation(List<MutationRecord> mutations, MutationObserver observer) {
-    this._onCallback();
-  }
-}
-
-/**
- * Scheduler which uses window.setImmediate to schedule events.
- */
-class _SetImmediateScheduler extends _MicrotaskScheduler {
-  _SetImmediateScheduler(_MicrotaskCallback callback): super(callback);
-
-  void _schedule() {
-    window._setImmediate(_handleImmediate);
-  }
-
-  void _handleImmediate() {
-    this._onCallback();
-  }
-}
-
-List<TimeoutHandler> _pendingMicrotasks;
-_MicrotaskScheduler _microtaskScheduler = null;
-
-void _maybeScheduleMicrotaskFrame() {
-  if (_microtaskScheduler == null) {
-    _microtaskScheduler =
-      new _MicrotaskScheduler.best(_completeMicrotasks);
-  }
-  _microtaskScheduler.maybeSchedule();
-}
-
-/**
- * Registers a [callback] which is called after the current execution stack
- * unwinds.
- */
-void _addMicrotaskCallback(TimeoutHandler callback) {
-  if (_pendingMicrotasks == null) {
-    _pendingMicrotasks = <TimeoutHandler>[];
-    _maybeScheduleMicrotaskFrame();
-  }
-  _pendingMicrotasks.add(callback);
-}
-
-
-/**
- * Complete all pending microtasks.
- */
-void _completeMicrotasks() {
-  var callbacks = _pendingMicrotasks;
-  _pendingMicrotasks = null;
-  for (var callback in callbacks) {
-    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.
@@ -32972,6 +33626,365 @@
   }
 }
 
+// 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.
+
+
+
+/**
+ * Interface used to validate that only accepted elements and attributes are
+ * allowed while parsing HTML strings into DOM nodes.
+ *
+ * In general, customization of validation behavior should be done via the
+ * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
+ * implementing validation rules.
+ */
+abstract class NodeValidator {
+
+  /**
+   * Construct a default NodeValidator which only accepts whitelisted HTML5
+   * elements and attributes.
+   *
+   * If a uriPolicy is not specified then the default uriPolicy will be used.
+   */
+  factory NodeValidator({UriPolicy uriPolicy}) =>
+      new _Html5NodeValidator(uriPolicy: uriPolicy);
+
+  factory NodeValidator.throws(NodeValidator base) =>
+      new _ThrowsNodeValidator(base);
+
+  /**
+   * Returns true if the tagName is an accepted type.
+   */
+  bool allowsElement(Element element);
+
+  /**
+   * Returns true if the attribute is allowed.
+   *
+   * The attributeName parameter will always be in lowercase.
+   *
+   * See [allowsElement] for format of tagName.
+   */
+  bool allowsAttribute(Element element, String attributeName, String value);
+}
+
+/**
+ * Performs sanitization of a node tree after construction to ensure that it
+ * does not contain any disallowed elements or attributes.
+ *
+ * In general custom implementations of this class should not be necessary and
+ * all validation customization should be done in custom NodeValidators, but
+ * custom implementations of this class can be created to perform more complex
+ * tree sanitization.
+ */
+abstract class NodeTreeSanitizer {
+
+  /**
+   * Constructs a default tree sanitizer which will remove all elements and
+   * attributes which are not allowed by the provided validator.
+   */
+  factory NodeTreeSanitizer(NodeValidator validator) =>
+      new _ValidatingTreeSanitizer(validator);
+
+  /**
+   * Called with the root of the tree which is to be sanitized.
+   *
+   * This method needs to walk the entire tree and either remove elements and
+   * attributes which are not recognized as safe or throw an exception which
+   * will mark the entire tree as unsafe.
+   */
+  void sanitizeTree(Node node);
+}
+
+/**
+ * Defines the policy for what types of uris are allowed for particular
+ * attribute values.
+ *
+ * This can be used to provide custom rules such as allowing all http:// URIs
+ * for image attributes but only same-origin URIs for anchor tags.
+ */
+abstract class UriPolicy {
+  /**
+   * Constructs the default UriPolicy which is to only allow Uris to the same
+   * origin as the application was launched from.
+   *
+   * This will block all ftp: mailto: URIs. It will also block accessing
+   * https://example.com if the app is running from http://example.com.
+   */
+  factory UriPolicy() => new _SameOriginUriPolicy();
+
+  /**
+   * Checks if the uri is allowed on the specified attribute.
+   *
+   * The uri provided may or may not be a relative path.
+   */
+  bool allowsUri(String uri);
+}
+
+/**
+ * Allows URIs to the same origin as the current application was loaded from
+ * (such as https://example.com:80).
+ */
+class _SameOriginUriPolicy implements UriPolicy {
+  final AnchorElement _hiddenAnchor = new AnchorElement();
+  final Location _loc = window.location;
+
+  bool allowsUri(String uri) {
+    _hiddenAnchor.href = uri;
+    // IE leaves an empty hostname for same-origin URIs.
+    return (_hiddenAnchor.hostname == _loc.hostname &&
+        _hiddenAnchor.port == _loc.port &&
+        _hiddenAnchor.protocol == _loc.protocol) ||
+        (_hiddenAnchor.hostname == '' &&
+        _hiddenAnchor.port == '' &&
+        _hiddenAnchor.protocol == ':');
+  }
+}
+
+
+class _ThrowsNodeValidator implements NodeValidator {
+  final NodeValidator validator;
+
+  _ThrowsNodeValidator(this.validator) {}
+
+  bool allowsElement(Element element) {
+    if (!validator.allowsElement(element)) {
+      throw new ArgumentError(element.tagName);
+    }
+    return true;
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (!validator.allowsAttribute(element, attributeName, value)) {
+      throw new ArgumentError('${element.tagName}[$attributeName="$value"]');
+    }
+  }
+}
+
+
+/**
+ * Standard tree sanitizer which validates a node tree against the provided
+ * validator and removes any nodes or attributes which are not allowed.
+ */
+class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
+  NodeValidator validator;
+  _ValidatingTreeSanitizer(this.validator) {}
+
+  void sanitizeTree(Node node) {
+    void walk(Node node) {
+      sanitizeNode(node);
+
+      var child = node.lastChild;
+      while (child != null) {
+        // Child may be removed during the walk.
+        var nextChild = child.previousNode;
+        walk(child);
+        child = nextChild;
+      }
+    }
+    walk(node);
+  }
+
+  void sanitizeNode(Node node) {
+    switch (node.nodeType) {
+      case Node.ELEMENT_NODE:
+        Element element = node;
+        var attrs = element.attributes;
+        if (!validator.allowsElement(element)) {
+          element.remove();
+          break;
+        }
+
+        var isAttr = attrs['is'];
+        if (isAttr != null) {
+          if (!validator.allowsAttribute(element, 'is', isAttr)) {
+            element.remove();
+            break;
+          }
+        }
+
+        // TODO(blois): Need to be able to get all attributes, irrespective of
+        // XMLNS.
+        var keys = attrs.keys.toList();
+        for (var i = attrs.length - 1; i >= 0; --i) {
+          var name = keys[i];
+          if (!validator.allowsAttribute(element, name.toLowerCase(),
+              attrs[name])) {
+            attrs.remove(name);
+          }
+        }
+
+        if (element is TemplateElement) {
+          TemplateElement template = element;
+          sanitizeTree(template.content);
+        }
+        break;
+      case Node.COMMENT_NODE:
+      case Node.DOCUMENT_FRAGMENT_NODE:
+      case Node.TEXT_NODE:
+      case Node.CDATA_SECTION_NODE:
+        break;
+      default:
+        node.remove();
+    }
+  }
+}
+// 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.
+
+
+/**
+ * Helper class to implement custom events which wrap DOM events.
+ */
+class _WrappedEvent implements Event {
+  final Event wrapped;
+  _WrappedEvent(this.wrapped);
+
+  bool get bubbles => wrapped.bubbles;
+
+  bool get cancelBubble => wrapped.bubbles;
+  void set cancelBubble(bool value) {
+    wrapped.cancelBubble = value;
+  }
+
+  bool get cancelable => wrapped.cancelable;
+
+  DataTransfer get clipboardData => wrapped.clipboardData;
+
+  EventTarget get currentTarget => wrapped.currentTarget;
+
+  bool get defaultPrevented => wrapped.defaultPrevented;
+
+  int get eventPhase => wrapped.eventPhase;
+
+  EventTarget get target => wrapped.target;
+
+  int get timeStamp => wrapped.timeStamp;
+
+  String get type => wrapped.type;
+
+  void _initEvent(String eventTypeArg, bool canBubbleArg,
+      bool cancelableArg) {
+    throw new UnsupportedError(
+        'Cannot initialize this Event.');
+  }
+
+  void preventDefault() {
+    wrapped.preventDefault();
+  }
+
+  void stopImmediatePropagation() {
+    wrapped.stopImmediatePropagation();
+  }
+
+  void stopPropagation() {
+    wrapped.stopPropagation();
+  }
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+/**
+ * A list which just wraps another list, for either intercepting list calls or
+ * retyping the list (for example, from List<A> to List<B> where B extends A).
+ */
+class _WrappedList<E> extends ListBase<E> {
+  final List _list;
+
+  _WrappedList(this._list);
+
+  // Iterable APIs
+
+  Iterator<E> get iterator => new _WrappedIterator(_list.iterator);
+
+  int get length => _list.length;
+
+  // Collection APIs
+
+  void add(E element) { _list.add(element); }
+
+  bool remove(Object element) => _list.remove(element);
+
+  void clear() { _list.clear(); }
+
+  // List APIs
+
+  E operator [](int index) => _list[index];
+
+  void operator []=(int index, E value) { _list[index] = value; }
+
+  void set length(int newLength) { _list.length = newLength; }
+
+  void sort([int compare(E a, E b)]) { _list.sort(compare); }
+
+  int indexOf(Object element, [int start = 0]) => _list.indexOf(element, start);
+
+  int lastIndexOf(Object element, [int start]) => _list.lastIndexOf(element, start);
+
+  void insert(int index, E element) => _list.insert(index, element);
+
+  E removeAt(int index) => _list.removeAt(index);
+
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    _list.setRange(start, end, iterable, skipCount);
+  }
+
+  void removeRange(int start, int end) { _list.removeRange(start, end); }
+
+  void replaceRange(int start, int end, Iterable<E> iterable) {
+    _list.replaceRange(start, end, iterable);
+  }
+
+  void fillRange(int start, int end, [E fillValue]) {
+    _list.fillRange(start, end, fillValue);
+  }
+}
+
+/**
+ * Iterator wrapper for _WrappedList.
+ */
+class _WrappedIterator<E> implements Iterator<E> {
+  Iterator _iterator;
+
+  _WrappedIterator(this._iterator);
+
+  bool moveNext() {
+    return _iterator.moveNext();
+  }
+
+  E get current => _iterator.current;
+}
+// Copyright (c) 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 _HttpRequestUtils {
+
+  // Helper for factory HttpRequest.get
+  static HttpRequest get(String url,
+                            onComplete(HttpRequest request),
+                            bool withCredentials) {
+    final request = new HttpRequest();
+    request.open('GET', url, async: true);
+
+    request.withCredentials = withCredentials;
+
+    request.onReadyStateChange.listen((e) {
+      if (request.readyState == HttpRequest.DONE) {
+        onComplete(request);
+      }
+    });
+
+    request.send();
+
+    return request;
+  }
+}
 // 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.
@@ -33028,6 +34041,147 @@
 
   T get current => _current;
 }
+/**
+ * A custom KeyboardEvent that attempts to eliminate cross-browser
+ * inconsistencies, and also provide both keyCode and charCode information
+ * for all key events (when such information can be determined).
+ *
+ * KeyEvent tries to provide a higher level, more polished keyboard event
+ * information on top of the "raw" [KeyboardEvent].
+ *
+ * This class is very much a work in progress, and we'd love to get information
+ * on how we can make this class work with as many international keyboards as
+ * possible. Bugs welcome!
+ */
+
+class KeyEvent extends _WrappedEvent implements KeyboardEvent {
+  /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
+  KeyboardEvent _parent;
+
+  /** The "fixed" value of whether the alt key is being pressed. */
+  bool _shadowAltKey;
+
+  /** Caculated value of what the estimated charCode is for this event. */
+  int _shadowCharCode;
+
+  /** Caculated value of what the estimated keyCode is for this event. */
+  int _shadowKeyCode;
+
+  /** Caculated value of what the estimated keyCode is for this event. */
+  int get keyCode => _shadowKeyCode;
+
+  /** Caculated value of what the estimated charCode is for this event. */
+  int get charCode => this.type == 'keypress' ? _shadowCharCode : 0;
+
+  /** Caculated value of whether the alt key is pressed is for this event. */
+  bool get altKey => _shadowAltKey;
+
+  /** Caculated value of what the estimated keyCode is for this event. */
+  int get which => keyCode;
+
+  /** Accessor to the underlying keyCode value is the parent event. */
+  int get _realKeyCode => _parent.keyCode;
+
+  /** Accessor to the underlying charCode value is the parent event. */
+  int get _realCharCode => _parent.charCode;
+
+  /** Accessor to the underlying altKey value is the parent event. */
+  bool get _realAltKey => _parent.altKey;
+
+  /** Construct a KeyEvent with [parent] as the event we're emulating. */
+  KeyEvent(KeyboardEvent parent): super(parent) {
+    _parent = parent;
+    _shadowAltKey = _realAltKey;
+    _shadowCharCode = _realCharCode;
+    _shadowKeyCode = _realKeyCode;
+  }
+
+  /** Accessor to provide a stream of KeyEvents on the desired target. */
+  static EventStreamProvider<KeyEvent> keyDownEvent =
+    new _KeyboardEventHandler('keydown');
+  /** Accessor to provide a stream of KeyEvents on the desired target. */
+  static EventStreamProvider<KeyEvent> keyUpEvent =
+    new _KeyboardEventHandler('keyup');
+  /** Accessor to provide a stream of KeyEvents on the desired target. */
+  static EventStreamProvider<KeyEvent> keyPressEvent =
+    new _KeyboardEventHandler('keypress');
+
+  /** True if the altGraphKey is pressed during this event. */
+  bool get altGraphKey => _parent.altGraphKey;
+  /** Accessor to the clipboardData available for this event. */
+  DataTransfer get clipboardData => _parent.clipboardData;
+  /** True if the ctrl key is pressed during this event. */
+  bool get ctrlKey => _parent.ctrlKey;
+  int get detail => _parent.detail;
+  /**
+   * Accessor to the part of the keyboard that the key was pressed from (one of
+   * KeyLocation.STANDARD, KeyLocation.RIGHT, KeyLocation.LEFT,
+   * KeyLocation.NUMPAD, KeyLocation.MOBILE, KeyLocation.JOYSTICK).
+   */
+  int get keyLocation => _parent.keyLocation;
+  Point get layer => _parent.layer;
+  /** True if the Meta (or Mac command) key is pressed during this event. */
+  bool get metaKey => _parent.metaKey;
+  Point get page => _parent.page;
+  /** True if the shift key was pressed during this event. */
+  bool get shiftKey => _parent.shiftKey;
+  Window get view => _parent.view;
+  void _initUIEvent(String type, bool canBubble, bool cancelable,
+      Window view, int detail) {
+    throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
+  }
+  String get _shadowKeyIdentifier => _parent._keyIdentifier;
+
+  int get _charCode => charCode;
+  int get _keyCode => keyCode;
+  String get _keyIdentifier {
+    throw new UnsupportedError("keyIdentifier is unsupported.");
+  }
+  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
+      Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
+      bool altKey, bool shiftKey, bool metaKey,
+      bool altGraphKey) {
+    throw new UnsupportedError(
+        "Cannot initialize a KeyboardEvent from a KeyEvent.");
+  }
+}
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+class Platform {
+  /**
+   * Returns true if dart:typed_data types are supported on this
+   * browser.  If false, using these types will generate a runtime
+   * error.
+   */
+  static final supportsTypedData = true;
+
+  /**
+   * Returns true if SIMD types in dart:typed_data types are supported
+   * on this browser.  If false, using these types will generate a runtime
+   * error.
+   */
+  static final supportsSimd = true;
+
+  /**
+   * Upgrade all custom elements in the subtree which have not been upgraded.
+   *
+   * This is needed to cover timing scenarios which the custom element polyfill
+   * does not cover.
+   *
+   * This is also a workaround for dartbug.com/12642 in Dartium.
+   */
+  static void upgradeCustomElements(Node node) {
+    // no-op, provided for dart2js polyfill.
+    if (node is Element) {
+      (node as Element).queryAll('*');
+    } else {
+      node.nodes.forEach(upgradeCustomElements);
+    }
+  }
+}
 // 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.
diff --git a/sdk/lib/html/html_common/device.dart b/sdk/lib/html/html_common/device.dart
index fe9ad35..d7fb730 100644
--- a/sdk/lib/html/html_common/device.dart
+++ b/sdk/lib/html/html_common/device.dart
@@ -104,7 +104,7 @@
   static bool isEventTypeSupported(String eventType) {
     // Browsers throw for unsupported event names.
     try {
-      var e = document.$dom_createEvent(eventType);
+      var e = new Event.eventType(eventType, '');
       return e is Event;
     } catch (_) { }
     return false;
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index 8296329..44b179e 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -144,7 +144,7 @@
   @DomName('IDBCursor.delete')
   Future delete() {
    try {
-      return _completeRequest($dom_delete());
+      return _completeRequest(_delete());
     } catch (e, stacktrace) {
       return new Future.error(e, stacktrace);
     }
@@ -153,7 +153,7 @@
   @DomName('IDBCursor.value')
   Future update(value) {
    try {
-      return _completeRequest($dom_update(value));
+      return _completeRequest(_update(value));
     } catch (e, stacktrace) {
       return new Future.error(e, stacktrace);
     }
@@ -189,7 +189,7 @@
   @JSName('delete')
   @DomName('IDBCursor.delete')
   @DocsEditable()
-  Request $dom_delete() native;
+  Request _delete() native;
 
   @JSName('continue')
   @DomName('IDBCursor.continue')
@@ -198,14 +198,14 @@
 
   @DomName('IDBCursor.update')
   @DocsEditable()
-  Request $dom_update(/*any*/ value) {
+  Request _update(/*any*/ value) {
     var value_1 = convertDartToNative_SerializedScriptValue(value);
-    return _$dom_update_1(value_1);
+    return _update_1(value_1);
   }
   @JSName('update')
   @DomName('IDBCursor.update')
   @DocsEditable()
-  Request _$dom_update_1(value) native;
+  Request _update_1(value) native;
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -253,7 +253,7 @@
       options['autoIncrement'] = autoIncrement;
     }
 
-    return $dom_createObjectStore(name, options);
+    return _createObjectStore(name, options);
   }
 
   Transaction transaction(storeName_OR_storeNames, String mode) {
@@ -341,21 +341,21 @@
 
   @DomName('IDBDatabase.createObjectStore')
   @DocsEditable()
-  ObjectStore $dom_createObjectStore(String name, [Map options]) {
+  ObjectStore _createObjectStore(String name, [Map options]) {
     if (options != null) {
       var options_1 = convertDartToNative_Dictionary(options);
-      return _$dom_createObjectStore_1(name, options_1);
+      return _createObjectStore_1(name, options_1);
     }
-    return _$dom_createObjectStore_2(name);
+    return _createObjectStore_2(name);
   }
   @JSName('createObjectStore')
   @DomName('IDBDatabase.createObjectStore')
   @DocsEditable()
-  ObjectStore _$dom_createObjectStore_1(name, options) native;
+  ObjectStore _createObjectStore_1(name, options) native;
   @JSName('createObjectStore')
   @DomName('IDBDatabase.createObjectStore')
   @DocsEditable()
-  ObjectStore _$dom_createObjectStore_2(name) native;
+  ObjectStore _createObjectStore_2(name) native;
 
   @DomName('IDBDatabase.deleteObjectStore')
   @DocsEditable()
@@ -412,9 +412,9 @@
     try {
       var request;
       if (version != null) {
-        request = $dom_open(name, version);
+        request = _open(name, version);
       } else {
-        request = $dom_open(name);
+        request = _open(name);
       }
 
       if (onUpgradeNeeded != null) {
@@ -433,7 +433,7 @@
   Future<IdbFactory> deleteDatabase(String name,
       {void onBlocked(Event)}) {
     try {
-      var request = $dom_deleteDatabase(name);
+      var request = _deleteDatabase(name);
 
       if (onBlocked != null) {
         request.onBlocked.listen(onBlocked);
@@ -456,7 +456,7 @@
   @Experimental()
   Future<List<String>> getDatabaseNames() {
     try {
-      var request = $dom_webkitGetDatabaseNames();
+      var request = _webkitGetDatabaseNames();
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -480,7 +480,7 @@
   @JSName('deleteDatabase')
   @DomName('IDBFactory.deleteDatabase')
   @DocsEditable()
-  OpenDBRequest $dom_deleteDatabase(String name) native;
+  OpenDBRequest _deleteDatabase(String name) native;
 
   @JSName('open')
   @DomName('IDBFactory.open')
@@ -488,7 +488,7 @@
   @Returns('Request')
   @Creates('Request')
   @Creates('Database')
-  OpenDBRequest $dom_open(String name, [int version]) native;
+  OpenDBRequest _open(String name, [int version]) native;
 
   @JSName('webkitGetDatabaseNames')
   @DomName('IDBFactory.webkitGetDatabaseNames')
@@ -499,7 +499,7 @@
   @Returns('Request')
   @Creates('Request')
   @Creates('DomStringList')
-  Request $dom_webkitGetDatabaseNames() native;
+  Request _webkitGetDatabaseNames() native;
 
 }
 
@@ -533,9 +533,9 @@
    try {
       var request;
       if (key_OR_range != null) {
-        request = $dom_count(key_OR_range);
+        request = _count(key_OR_range);
       } else {
-        request = $dom_count();
+        request = _count();
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -546,7 +546,7 @@
   @DomName('IDBIndex.get')
   Future get(key) {
     try {
-      var request = $dom_get(key);
+      var request = _get(key);
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -557,7 +557,7 @@
   @DomName('IDBIndex.getKey')
   Future getKey(key) {
     try {
-      var request = $dom_getKey(key);
+      var request = _getKey(key);
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -585,9 +585,9 @@
     }
     var request;
     if (direction == null) {
-      request = $dom_openCursor(key_OR_range);
+      request = _openCursor(key_OR_range);
     } else {
-      request = $dom_openCursor(key_OR_range, direction);
+      request = _openCursor(key_OR_range, direction);
     }
     return ObjectStore._cursorStreamFromResult(request, autoAdvance);
   }
@@ -612,9 +612,9 @@
     }
     var request;
     if (direction == null) {
-      request = $dom_openKeyCursor(key_OR_range);
+      request = _openKeyCursor(key_OR_range);
     } else {
-      request = $dom_openKeyCursor(key_OR_range, direction);
+      request = _openKeyCursor(key_OR_range, direction);
     }
     return ObjectStore._cursorStreamFromResult(request, autoAdvance);
   }
@@ -644,7 +644,7 @@
   @JSName('count')
   @DomName('IDBIndex.count')
   @DocsEditable()
-  Request $dom_count([key_OR_range]) native;
+  Request _count([key_OR_range]) native;
 
   @JSName('get')
   @DomName('IDBIndex.get')
@@ -652,7 +652,7 @@
   @Returns('Request')
   @Creates('Request')
   @annotation_Creates_SerializedScriptValue
-  Request $dom_get(key) native;
+  Request _get(key) native;
 
   @JSName('getKey')
   @DomName('IDBIndex.getKey')
@@ -661,7 +661,7 @@
   @Creates('Request')
   @annotation_Creates_SerializedScriptValue
   @Creates('ObjectStore')
-  Request $dom_getKey(key) native;
+  Request _getKey(key) native;
 
   @JSName('openCursor')
   @DomName('IDBIndex.openCursor')
@@ -669,7 +669,7 @@
   @Returns('Request')
   @Creates('Request')
   @Creates('Cursor')
-  Request $dom_openCursor([key_OR_range, String direction]) native;
+  Request _openCursor([key_OR_range, String direction]) native;
 
   @JSName('openKeyCursor')
   @DomName('IDBIndex.openKeyCursor')
@@ -677,7 +677,7 @@
   @Returns('Request')
   @Creates('Request')
   @Creates('Cursor')
-  Request $dom_openKeyCursor([key_OR_range, String direction]) native;
+  Request _openKeyCursor([key_OR_range, String direction]) native;
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -760,9 +760,9 @@
     try {
       var request;
       if (key != null) {
-        request = $dom_add(value, key);
+        request = _add(value, key);
       } else {
-        request = $dom_add(value);
+        request = _add(value);
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -773,7 +773,7 @@
   @DomName('IDBObjectStore.clear')
   Future clear() {
     try {
-      return _completeRequest($dom_clear());
+      return _completeRequest(_clear());
     } catch (e, stacktrace) {
       return new Future.error(e, stacktrace);
     }
@@ -782,7 +782,7 @@
   @DomName('IDBObjectStore.delete')
   Future delete(key_OR_keyRange){
     try {
-      return _completeRequest($dom_delete(key_OR_keyRange));
+      return _completeRequest(_delete(key_OR_keyRange));
     } catch (e, stacktrace) {
       return new Future.error(e, stacktrace);
     }
@@ -793,9 +793,9 @@
    try {
       var request;
       if (key_OR_range != null) {
-        request = $dom_count(key_OR_range);
+        request = _count(key_OR_range);
       } else {
-        request = $dom_count();
+        request = _count();
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -808,9 +808,9 @@
     try {
       var request;
       if (key != null) {
-        request = $dom_put(value, key);
+        request = _put(value, key);
       } else {
-        request = $dom_put(value);
+        request = _put(value);
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -821,7 +821,7 @@
   @DomName('IDBObjectStore.get')
   Future getObject(key) {
     try {
-      var request = $dom_get(key);
+      var request = _get(key);
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -866,9 +866,9 @@
     // TODO: try/catch this and return a stream with an immediate error.
     var request;
     if (direction == null) {
-      request = $dom_openCursor(key_OR_range);
+      request = _openCursor(key_OR_range);
     } else {
-      request = $dom_openCursor(key_OR_range, direction);
+      request = _openCursor(key_OR_range, direction);
     }
     return _cursorStreamFromResult(request, autoAdvance);
   }
@@ -883,7 +883,7 @@
       options['multiEntry'] = multiEntry;
     }
 
-    return $dom_createIndex(name, keyPath, options);
+    return _createIndex(name, keyPath, options);
   }
 
 
@@ -915,14 +915,14 @@
   @Returns('Request')
   @Creates('Request')
   @_annotation_Creates_IDBKey
-  Request $dom_add(/*any*/ value, [/*any*/ key]) {
+  Request _add(/*any*/ value, [/*any*/ key]) {
     if (key != null) {
       var value_1 = convertDartToNative_SerializedScriptValue(value);
       var key_2 = convertDartToNative_SerializedScriptValue(key);
-      return _$dom_add_1(value_1, key_2);
+      return _add_1(value_1, key_2);
     }
     var value_3 = convertDartToNative_SerializedScriptValue(value);
-    return _$dom_add_2(value_3);
+    return _add_2(value_3);
   }
   @JSName('add')
   @DomName('IDBObjectStore.add')
@@ -930,67 +930,67 @@
   @Returns('Request')
   @Creates('Request')
   @_annotation_Creates_IDBKey
-  Request _$dom_add_1(value, key) native;
+  Request _add_1(value, key) native;
   @JSName('add')
   @DomName('IDBObjectStore.add')
   @DocsEditable()
   @Returns('Request')
   @Creates('Request')
   @_annotation_Creates_IDBKey
-  Request _$dom_add_2(value) native;
+  Request _add_2(value) native;
 
   @JSName('clear')
   @DomName('IDBObjectStore.clear')
   @DocsEditable()
-  Request $dom_clear() native;
+  Request _clear() native;
 
   @JSName('count')
   @DomName('IDBObjectStore.count')
   @DocsEditable()
-  Request $dom_count([key_OR_range]) native;
+  Request _count([key_OR_range]) native;
 
   @DomName('IDBObjectStore.createIndex')
   @DocsEditable()
-  Index $dom_createIndex(String name, keyPath, [Map options]) {
+  Index _createIndex(String name, keyPath, [Map options]) {
     if ((keyPath is List<String> || keyPath == null) && options == null) {
       List keyPath_1 = convertDartToNative_StringArray(keyPath);
-      return _$dom_createIndex_1(name, keyPath_1);
+      return _createIndex_1(name, keyPath_1);
     }
     if (options != null && (keyPath is List<String> || keyPath == null)) {
       List keyPath_2 = convertDartToNative_StringArray(keyPath);
       var options_3 = convertDartToNative_Dictionary(options);
-      return _$dom_createIndex_2(name, keyPath_2, options_3);
+      return _createIndex_2(name, keyPath_2, options_3);
     }
     if ((keyPath is String || keyPath == null) && options == null) {
-      return _$dom_createIndex_3(name, keyPath);
+      return _createIndex_3(name, keyPath);
     }
     if (options != null && (keyPath is String || keyPath == null)) {
       var options_4 = convertDartToNative_Dictionary(options);
-      return _$dom_createIndex_4(name, keyPath, options_4);
+      return _createIndex_4(name, keyPath, options_4);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
   }
   @JSName('createIndex')
   @DomName('IDBObjectStore.createIndex')
   @DocsEditable()
-  Index _$dom_createIndex_1(name, List keyPath) native;
+  Index _createIndex_1(name, List keyPath) native;
   @JSName('createIndex')
   @DomName('IDBObjectStore.createIndex')
   @DocsEditable()
-  Index _$dom_createIndex_2(name, List keyPath, options) native;
+  Index _createIndex_2(name, List keyPath, options) native;
   @JSName('createIndex')
   @DomName('IDBObjectStore.createIndex')
   @DocsEditable()
-  Index _$dom_createIndex_3(name, String keyPath) native;
+  Index _createIndex_3(name, String keyPath) native;
   @JSName('createIndex')
   @DomName('IDBObjectStore.createIndex')
   @DocsEditable()
-  Index _$dom_createIndex_4(name, String keyPath, options) native;
+  Index _createIndex_4(name, String keyPath, options) native;
 
   @JSName('delete')
   @DomName('IDBObjectStore.delete')
   @DocsEditable()
-  Request $dom_delete(key_OR_keyRange) native;
+  Request _delete(key_OR_keyRange) native;
 
   @DomName('IDBObjectStore.deleteIndex')
   @DocsEditable()
@@ -1002,7 +1002,7 @@
   @Returns('Request')
   @Creates('Request')
   @annotation_Creates_SerializedScriptValue
-  Request $dom_get(key) native;
+  Request _get(key) native;
 
   @DomName('IDBObjectStore.index')
   @DocsEditable()
@@ -1014,21 +1014,21 @@
   @Returns('Request')
   @Creates('Request')
   @Creates('Cursor')
-  Request $dom_openCursor([key_OR_range, String direction]) native;
+  Request _openCursor([key_OR_range, String direction]) native;
 
   @DomName('IDBObjectStore.put')
   @DocsEditable()
   @Returns('Request')
   @Creates('Request')
   @_annotation_Creates_IDBKey
-  Request $dom_put(/*any*/ value, [/*any*/ key]) {
+  Request _put(/*any*/ value, [/*any*/ key]) {
     if (key != null) {
       var value_1 = convertDartToNative_SerializedScriptValue(value);
       var key_2 = convertDartToNative_SerializedScriptValue(key);
-      return _$dom_put_1(value_1, key_2);
+      return _put_1(value_1, key_2);
     }
     var value_3 = convertDartToNative_SerializedScriptValue(value);
-    return _$dom_put_2(value_3);
+    return _put_2(value_3);
   }
   @JSName('put')
   @DomName('IDBObjectStore.put')
@@ -1036,14 +1036,14 @@
   @Returns('Request')
   @Creates('Request')
   @_annotation_Creates_IDBKey
-  Request _$dom_put_1(value, key) native;
+  Request _put_1(value, key) native;
   @JSName('put')
   @DomName('IDBObjectStore.put')
   @DocsEditable()
   @Returns('Request')
   @Creates('Request')
   @_annotation_Creates_IDBKey
-  Request _$dom_put_2(value) native;
+  Request _put_2(value) native;
 
 
   /**
diff --git a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
index dc31713..4612492 100644
--- a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
+++ b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
@@ -44,7 +44,7 @@
   @DomName('IDBCursor.delete')
   Future delete() {
    try {
-      return _completeRequest($dom_delete());
+      return _completeRequest(_delete());
     } catch (e, stacktrace) {
       return new Future.error(e, stacktrace);
     }
@@ -53,7 +53,7 @@
   @DomName('IDBCursor.value')
   Future update(value) {
    try {
-      return _completeRequest($dom_update(value));
+      return _completeRequest(_update(value));
     } catch (e, stacktrace) {
       return new Future.error(e, stacktrace);
     }
@@ -82,7 +82,7 @@
 
   @DomName('IDBCursor.delete')
   @DocsEditable()
-  Request $dom_delete() native "IDBCursor_delete_Callback";
+  Request _delete() native "IDBCursor_delete_Callback";
 
   @DomName('IDBCursor.next')
   @DocsEditable()
@@ -91,7 +91,7 @@
 
   @DomName('IDBCursor.update')
   @DocsEditable()
-  Request $dom_update(Object value) native "IDBCursor_update_Callback";
+  Request _update(Object value) native "IDBCursor_update_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -138,7 +138,7 @@
       options['autoIncrement'] = autoIncrement;
     }
 
-    return $dom_createObjectStore(name, options);
+    return _createObjectStore(name, options);
   }
 
 
@@ -181,7 +181,7 @@
 
   @DomName('IDBDatabase.createObjectStore')
   @DocsEditable()
-  ObjectStore $dom_createObjectStore(String name, [Map options]) native "IDBDatabase_createObjectStore_Callback";
+  ObjectStore _createObjectStore(String name, [Map options]) native "IDBDatabase_createObjectStore_Callback";
 
   @DomName('IDBDatabase.deleteObjectStore')
   @DocsEditable()
@@ -278,9 +278,9 @@
     try {
       var request;
       if (version != null) {
-        request = $dom_open(name, version);
+        request = _open(name, version);
       } else {
-        request = $dom_open(name);
+        request = _open(name);
       }
 
       if (onUpgradeNeeded != null) {
@@ -299,7 +299,7 @@
   Future<IdbFactory> deleteDatabase(String name,
       {void onBlocked(Event)}) {
     try {
-      var request = $dom_deleteDatabase(name);
+      var request = _deleteDatabase(name);
 
       if (onBlocked != null) {
         request.onBlocked.listen(onBlocked);
@@ -322,7 +322,7 @@
   @Experimental()
   Future<List<String>> getDatabaseNames() {
     try {
-      var request = $dom_webkitGetDatabaseNames();
+      var request = _webkitGetDatabaseNames();
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -344,9 +344,9 @@
 
   @DomName('IDBFactory.deleteDatabase')
   @DocsEditable()
-  OpenDBRequest $dom_deleteDatabase(String name) native "IDBFactory_deleteDatabase_Callback";
+  OpenDBRequest _deleteDatabase(String name) native "IDBFactory_deleteDatabase_Callback";
 
-  OpenDBRequest $dom_open(String name, [int version]) {
+  OpenDBRequest _open(String name, [int version]) {
     if (version != null) {
       return _open_1(name, version);
     }
@@ -362,7 +362,7 @@
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  Request $dom_webkitGetDatabaseNames() native "IDBFactory_webkitGetDatabaseNames_Callback";
+  Request _webkitGetDatabaseNames() native "IDBFactory_webkitGetDatabaseNames_Callback";
 
 }
 
@@ -396,9 +396,9 @@
    try {
       var request;
       if (key_OR_range != null) {
-        request = $dom_count(key_OR_range);
+        request = _count(key_OR_range);
       } else {
-        request = $dom_count();
+        request = _count();
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -409,7 +409,7 @@
   @DomName('IDBIndex.get')
   Future get(key) {
     try {
-      var request = $dom_get(key);
+      var request = _get(key);
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -420,7 +420,7 @@
   @DomName('IDBIndex.getKey')
   Future getKey(key) {
     try {
-      var request = $dom_getKey(key);
+      var request = _getKey(key);
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -448,9 +448,9 @@
     }
     var request;
     if (direction == null) {
-      request = $dom_openCursor(key_OR_range);
+      request = _openCursor(key_OR_range);
     } else {
-      request = $dom_openCursor(key_OR_range, direction);
+      request = _openCursor(key_OR_range, direction);
     }
     return ObjectStore._cursorStreamFromResult(request, autoAdvance);
   }
@@ -475,9 +475,9 @@
     }
     var request;
     if (direction == null) {
-      request = $dom_openKeyCursor(key_OR_range);
+      request = _openKeyCursor(key_OR_range);
     } else {
-      request = $dom_openKeyCursor(key_OR_range, direction);
+      request = _openKeyCursor(key_OR_range, direction);
     }
     return ObjectStore._cursorStreamFromResult(request, autoAdvance);
   }
@@ -503,7 +503,7 @@
   @DocsEditable()
   bool get unique native "IDBIndex_unique_Getter";
 
-  Request $dom_count([key_OR_range]) {
+  Request _count([key_OR_range]) {
     if ((key_OR_range is KeyRange || key_OR_range == null)) {
       return _count_1(key_OR_range);
     }
@@ -517,7 +517,7 @@
 
   Request _count_2(key_OR_range) native "IDBIndex__count_2_Callback";
 
-  Request $dom_get(key) {
+  Request _get(key) {
     if ((key is KeyRange || key == null)) {
       return _get_1(key);
     }
@@ -531,7 +531,7 @@
 
   Request _get_2(key) native "IDBIndex__get_2_Callback";
 
-  Request $dom_getKey(key) {
+  Request _getKey(key) {
     if ((key is KeyRange || key == null)) {
       return _getKey_1(key);
     }
@@ -545,7 +545,7 @@
 
   Request _getKey_2(key) native "IDBIndex__getKey_2_Callback";
 
-  Request $dom_openCursor([key_OR_range, String direction]) {
+  Request _openCursor([key_OR_range, String direction]) {
     if ((direction is String || direction == null) && (key_OR_range is KeyRange || key_OR_range == null)) {
       return _openCursor_1(key_OR_range, direction);
     }
@@ -559,7 +559,7 @@
 
   Request _openCursor_2(key_OR_range, direction) native "IDBIndex__openCursor_2_Callback";
 
-  Request $dom_openKeyCursor([key_OR_range, String direction]) {
+  Request _openKeyCursor([key_OR_range, String direction]) {
     if ((direction is String || direction == null) && (key_OR_range is KeyRange || key_OR_range == null)) {
       return _openKeyCursor_1(key_OR_range, direction);
     }
@@ -652,9 +652,9 @@
     try {
       var request;
       if (key != null) {
-        request = $dom_add(value, key);
+        request = _add(value, key);
       } else {
-        request = $dom_add(value);
+        request = _add(value);
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -665,7 +665,7 @@
   @DomName('IDBObjectStore.clear')
   Future clear() {
     try {
-      return _completeRequest($dom_clear());
+      return _completeRequest(_clear());
     } catch (e, stacktrace) {
       return new Future.error(e, stacktrace);
     }
@@ -674,7 +674,7 @@
   @DomName('IDBObjectStore.delete')
   Future delete(key_OR_keyRange){
     try {
-      return _completeRequest($dom_delete(key_OR_keyRange));
+      return _completeRequest(_delete(key_OR_keyRange));
     } catch (e, stacktrace) {
       return new Future.error(e, stacktrace);
     }
@@ -685,9 +685,9 @@
    try {
       var request;
       if (key_OR_range != null) {
-        request = $dom_count(key_OR_range);
+        request = _count(key_OR_range);
       } else {
-        request = $dom_count();
+        request = _count();
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -700,9 +700,9 @@
     try {
       var request;
       if (key != null) {
-        request = $dom_put(value, key);
+        request = _put(value, key);
       } else {
-        request = $dom_put(value);
+        request = _put(value);
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -713,7 +713,7 @@
   @DomName('IDBObjectStore.get')
   Future getObject(key) {
     try {
-      var request = $dom_get(key);
+      var request = _get(key);
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -758,9 +758,9 @@
     // TODO: try/catch this and return a stream with an immediate error.
     var request;
     if (direction == null) {
-      request = $dom_openCursor(key_OR_range);
+      request = _openCursor(key_OR_range);
     } else {
-      request = $dom_openCursor(key_OR_range, direction);
+      request = _openCursor(key_OR_range, direction);
     }
     return _cursorStreamFromResult(request, autoAdvance);
   }
@@ -775,7 +775,7 @@
       options['multiEntry'] = multiEntry;
     }
 
-    return $dom_createIndex(name, keyPath, options);
+    return _createIndex(name, keyPath, options);
   }
 
 
@@ -801,13 +801,13 @@
 
   @DomName('IDBObjectStore.add')
   @DocsEditable()
-  Request $dom_add(Object value, [Object key]) native "IDBObjectStore_add_Callback";
+  Request _add(Object value, [Object key]) native "IDBObjectStore_add_Callback";
 
   @DomName('IDBObjectStore.clear')
   @DocsEditable()
-  Request $dom_clear() native "IDBObjectStore_clear_Callback";
+  Request _clear() native "IDBObjectStore_clear_Callback";
 
-  Request $dom_count([key_OR_range]) {
+  Request _count([key_OR_range]) {
     if ((key_OR_range is KeyRange || key_OR_range == null)) {
       return _count_1(key_OR_range);
     }
@@ -821,7 +821,7 @@
 
   Request _count_2(key_OR_range) native "IDBObjectStore__count_2_Callback";
 
-  Index $dom_createIndex(String name, keyPath, [Map options]) {
+  Index _createIndex(String name, keyPath, [Map options]) {
     if ((options is Map || options == null) && (keyPath is List<String> || keyPath == null) && (name is String || name == null)) {
       return _createIndex_1(name, keyPath, options);
     }
@@ -835,7 +835,7 @@
 
   Index _createIndex_2(name, keyPath, options) native "IDBObjectStore__createIndex_2_Callback";
 
-  Request $dom_delete(key_OR_keyRange) {
+  Request _delete(key_OR_keyRange) {
     if ((key_OR_keyRange is KeyRange || key_OR_keyRange == null)) {
       return _delete_1(key_OR_keyRange);
     }
@@ -853,7 +853,7 @@
   @DocsEditable()
   void deleteIndex(String name) native "IDBObjectStore_deleteIndex_Callback";
 
-  Request $dom_get(key) {
+  Request _get(key) {
     if ((key is KeyRange || key == null)) {
       return _get_1(key);
     }
@@ -871,7 +871,7 @@
   @DocsEditable()
   Index index(String name) native "IDBObjectStore_index_Callback";
 
-  Request $dom_openCursor([key_OR_range, String direction]) {
+  Request _openCursor([key_OR_range, String direction]) {
     if ((direction is String || direction == null) && (key_OR_range is KeyRange || key_OR_range == null)) {
       return _openCursor_1(key_OR_range, direction);
     }
@@ -887,7 +887,7 @@
 
   @DomName('IDBObjectStore.put')
   @DocsEditable()
-  Request $dom_put(Object value, [Object key]) native "IDBObjectStore_put_Callback";
+  Request _put(Object value, [Object key]) native "IDBObjectStore_put_Callback";
 
 
   /**
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index df228f5..1cf3387 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -696,77 +696,138 @@
 
 
 /**
- * Http request delivered to the HTTP server callback. The [HttpRequest] is a
- * [Stream] of the body content of the request. Listen to the body to handle the
+ * A server-side object
+ * that contains the content of and information about an HTTP request.
+ *
+ * __Note__: Check out the
+ * [http_server](http://pub.dartlang.org/packages/http_server)
+ * package, which makes working with the low-level
+ * dart:io HTTP server subsystem easier.
+ *
+ * HttpRequest objects are generated by an [HttpServer],
+ * which listens for HTTP requests on a specific host and port.
+ * For each request received, the HttpServer, which is a [Stream],
+ * generates an HttpRequest object and adds it to the stream.
+ *
+ * An HttpRequest object delivers the body content of the request
+ * as a stream of bytes.
+ * The object also contains information about the request,
+ * such as the method, URI, and headers.
+ *
+ * In the following code, an HttpServer listens
+ * for HTTP requests and, within the callback function,
+ * uses the HttpRequest object's `method` property to dispatch requests.
+ *
+ *     final HOST = InternetAddress.LOOPBACK_IP_V4;
+ *     final PORT = 4040;
+ *
+ *     HttpServer.bind(HOST, PORT).then((_server) {
+ *       _server.listen((HttpRequest request) {
+ *         switch (request.method) {
+ *           case 'GET': 
+ *             handleGetRequest(request);
+ *             break;
+ *           case 'POST': 
+ *             ...
+ *         }
+ *       },
+ *       onError: handleError);    // listen() failed.
+ *     }).catchError(handleError);
+ *   
+ * Listen to the HttpRequest stream to handle the
  * data and be notified once the entire body is received.
+ * An HttpRequest object contains an [HttpResponse] object,
+ * to which the server can write its response.
+ * For example, here's a skeletal callback function
+ * that responds to a request:
+ *
+ *     void handleGetRequest(HttpRequest req) {
+ *       HttpResponse res = req.response;
+ *       var body = [];
+ *       req.listen((List<int> buffer) => body.add(buffer),
+ *         onDone: () {
+ *           res.write('Received ${body.length} for request ');
+ *           res.write(' ${req.method}: ${req.uri.path}');
+ *           res.close();
+ *         },
+ *         onError: handleError);
+ *     }
  */
 abstract class HttpRequest implements Stream<List<int>> {
   /**
-   * Returns the content length of the request body. If the size of
-   * the request body is not known in advance this -1.
+   * The content length of the request body (read-only).
+   *
+   * If the size of the request body is not known in advance,
+   * this value is -1.
    */
   int get contentLength;
 
   /**
-   * Returns the method for the request.
+   * The method, such as 'GET' or 'POST', for the request (read-only).
    */
   String get method;
 
   /**
-   * Returns the URI for the request. This provides access to the
-   * path, query string and fragment identifier for the request.
+   * The URI for the request (read-only).
+   *
+   * This provides access to the
+   * path, query string, and fragment identifier for the request.
    */
   Uri get uri;
 
   /**
-   * Returns the request headers.
+   * The request headers (read-only).
    */
   HttpHeaders get headers;
 
   /**
-   * Returns the cookies in the request (from the Cookie headers).
+   * The cookies in the request, from the Cookie headers (read-only).
    */
   List<Cookie> get cookies;
 
   /**
-   * Returns the persistent connection state signaled by the client.
+   * The persistent connection state signaled by the client (read-only).
    */
   bool get persistentConnection;
 
   /**
-   * Returns the client certificate of the client making the request.
-   * Returns null if the connection is not a secure TLS or SSL connection,
+   * The client certificate of the client making the request (read-only).
+   *
+   * This value is 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;
 
   /**
-   * Gets the session for the given request. If the session is
-   * being initialized by this call, [:isNew:] will be true for the returned
+   * The session for the given request (read-only).
+   *
+   * If the session is
+   * being initialized by this call, [:isNew:] is true for the returned
    * session.
    * See [HttpServer.sessionTimeout] on how to change default timeout.
    */
   HttpSession get session;
 
   /**
-   * Returns the HTTP protocol version used in the request. This will
-   * be "1.0" or "1.1".
+   * The HTTP protocol version used in the request, 
+   * either "1.0" or "1.1" (read-only).
    */
   String get protocolVersion;
 
   /**
-   * Gets information about the client connection. Returns [null] if the socket
-   * is not available.
+   * Information about the client connection (read-only).
+   *
+   * Returns [null] if the socket is not available.
    */
   HttpConnectionInfo get connectionInfo;
 
   /**
-   * Gets the [HttpResponse] object, used for sending back the response to the
-   * client.
+   * The [HttpResponse] object, used for sending back the response to the
+   * client (read-only).
    *
    * If the [contentLength] of the body isn't 0, and the body isn't being read,
-   * any write calls on the [HttpResponse] will automatically drain the request
+   * any write calls on the [HttpResponse] automatically drain the request
    * body.
    */
   HttpResponse get response;
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index 393320f..5f9788b 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -79,7 +79,13 @@
 /**
  * Returns a proxy to the global JavaScript context for this page.
  */
-JsObject get context => _deserialize(_jsPortSync.callSync([]));
+JsObject get context {
+  var port = _jsPortSync;
+  if (port == null) {
+    return null;
+  }
+  return _deserialize(_jsPortSync.callSync([]));
+}
 
 /**
  * Converts a json-like [data] to a JavaScript map or array and return a
diff --git a/sdk/lib/json/json.dart b/sdk/lib/json/json.dart
index 5fd3a6a..efc2621 100644
--- a/sdk/lib/json/json.dart
+++ b/sdk/lib/json/json.dart
@@ -8,50 +8,12 @@
 
 library dart.json;
 
+import "dart:convert";
+export "dart:convert" show JsonUnsupportedObjectError, JsonCyclicError;
+
 // JSON parsing and serialization.
 
 /**
- * Error thrown by JSON serialization if an object cannot be serialized.
- *
- * The [unsupportedObject] field holds that object that failed to be serialized.
- *
- * If an object isn't directly serializable, the serializer calls the 'toJson'
- * method on the object. If that call fails, the error will be stored in the
- * [cause] field. If the call returns an object that isn't directly
- * serializable, the [cause] will be null.
- */
-class JsonUnsupportedObjectError extends Error {
-  /** The object that could not be serialized. */
-  final unsupportedObject;
-  /** The exception thrown by object's [:toJson:] method, if any. */
-  final cause;
-
-  JsonUnsupportedObjectError(this.unsupportedObject, { this.cause });
-
-  String toString() {
-    if (cause != null) {
-      return "Calling toJson method on object failed.";
-    } else {
-      return "Object toJson method returns non-serializable value.";
-    }
-  }
-}
-
-
-/**
- * Reports that an object could not be stringified due to cyclic references.
- *
- * An object that references itself cannot be serialized by [stringify].
- * When the cycle is detected, a [JsonCyclicError] is thrown.
- */
-class JsonCyclicError extends JsonUnsupportedObjectError {
-  /** The first object that was detected as part of a cycle. */
-  JsonCyclicError(Object object): super(object);
-  String toString() => "Cyclic error in JSON stringify";
-}
-
-
-/**
  * Parses [json] and build the corresponding parsed JSON value.
  *
  * Parsed JSON values are of the types [num], [String], [bool], [Null],
@@ -66,17 +28,12 @@
  *
  * Throws [FormatException] if the input is not valid JSON text.
  */
-external parse(String json, [reviver(var key, var value)]);
-
-_parse(String json, reviver(var key, var value)) {
-  BuildJsonListener listener;
-  if (reviver == null) {
-    listener = new BuildJsonListener();
-  } else {
-    listener = new ReviverJsonListener(reviver);
+parse(String json, [reviver(var key, var value)]) {
+  if (reviver != null) {
+    var original = reviver;
+    reviver = (key, value) => original(key == null ? "" : key, value);
   }
-  new JsonParser(json, listener).parse();
-  return listener.result;
+  return JSON.decode(json, reviver: reviver);
 }
 
 /**
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 66b9abd..4e96d84 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -119,7 +119,7 @@
 
 /**
  * Returns an [InstanceMirror] reflecting [reflectee].
- * If [reflectee] is function or an instance of a class 
+ * If [reflectee] is function or an instance of a class
  * that has a [:call:] method, the returned instance mirror
  * will be a [ClosureMirror].
  *
@@ -131,7 +131,7 @@
 
 /**
  * Let *C* be the original class declaration of the class
- * represented by [key]. 
+ * represented by [key].
  * This function returns a [ClassMirror] reflecting *C*.
  *
  * If [key] is not an instance of [Type] then this function
@@ -161,29 +161,29 @@
  */
 abstract class IsolateMirror implements Mirror {
   /**
-   * Returns a unique name used to refer to an isolate 
+   * Returns a unique name used to refer to an isolate
    * in debugging messages.
    */
   String get debugName;
 
   /**
-   * Returns [:true:] if and only if this mirror reflects 
+   * Returns [:true:] if and only if this mirror reflects
    * the currently running isolate. Otherwise returns
    * [:false:].
    */
   bool get isCurrent;
 
   /**
-   * Returns a [LibraryMirror] on the root library for this 
+   * Returns a [LibraryMirror] on the root library for this
    * isolate.
    */
   LibraryMirror get rootLibrary;
 
   /**
-   * Returns [:true:] if this mirror is equal to [other]. 
+   * Returns [:true:] if this mirror is equal to [other].
    * Otherwise returns [:false:].
-   * The equality holds if and only if 
-   * (1) [other] is a mirror of the same kind 
+   * The equality holds if and only if
+   * (1) [other] is a mirror of the same kind
    * and
    * (2) the isolate being reflected by this mirror is the same
    * isolate being reflected by [other].
@@ -200,7 +200,7 @@
    *
    * 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.
+   * 'mylibrary' for a [:library 'mylibrary';:] declaration.
    */
   Symbol get simpleName;
 
@@ -227,15 +227,15 @@
    * immediately surrounding the reflectee.
    *
    * For a library, the owner is [:null:].
-   * For a class declaration, typedef or top level function 
-   * or variable, the owner is the enclosing library. 
+   * For a class declaration, typedef or top level function
+   * or variable, the owner is the enclosing library.
    * For a mixin application *S with M*, the owner is the owner
    * of *M*.
    * For class Null, the owner is the dart:core library.
    * For a constructor, the owner is the immediately enclosing class.
    * For a method, instance variable or
    * a static variable, the owner is the immediately enclosing class,
-   * unless the class is a mixin application *S with M*, in which case 
+   * unless the class is a mixin application *S with M*, in which case
    * the owner is *M*. Note that *M* may be an invocation of a generic.
    * For a parameter, local variable or local function the owner is the
    * immediately enclosing function.
@@ -270,11 +270,11 @@
    *
    * Let *D* be the declaration this mirror reflects.
    * If *D* is decorated with annotations *A1, ..., An*
-   * where *n > 0*, then for each annotation *Ai* associated 
-   * with *D, 1 <= i <= n*, let *ci* be the constant object 
-   * specified by *Ai*. Then this method returns a list whose 
+   * where *n > 0*, then for each annotation *Ai* associated
+   * with *D, 1 <= i <= n*, let *ci* be the constant object
+   * specified by *Ai*. Then this method returns a list whose
    * members are instance mirrors on *c1, ..., cn*.
-   * If no annotations are associated with *D*, then 
+   * If no annotations are associated with *D*, then
    * an empty list is returned.
    */
   List<InstanceMirror> get metadata;
@@ -496,12 +496,12 @@
 
   /**
    * Returns true if this mirror is equal to [other].
-   * The equality holds if and only if 
+   * The equality holds if and only if
    * (1) [other] is a mirror of the same kind
    * and
-   * (2) either 
+   * (2) either
    * (a) [hasReflectee] is true and so is
-   * [:identical(reflectee, other.reflectee):] 
+   * [:identical(reflectee, other.reflectee):]
    * or
    * (b) the remote objects reflected by this mirror and
    * by [other] are identical.
@@ -532,13 +532,6 @@
   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 and returns a mirror on the result.
    * Let *f* be the closure reflected by this mirror,
    * let *a1, ..., an* be the elements of [positionalArguments]
@@ -660,7 +653,7 @@
    * Returns [:true:] if this mirror is equal to [other].
    * Otherwise returns [:false:].
    *
-   * The equality holds if and only if 
+   * The equality holds if and only if
    * (1) [other] is a mirror of the same kind
    * and
    * (2)  The library being reflected by this mirror
@@ -765,9 +758,9 @@
 
   /**
    * An immutable map from names to mirrors for all type arguments for
-   * this type.  The keys of the map are the names of the 
+   * this type.  The keys of the map are the names of the
    * corresponding type variables.
-   * 
+   *
    * If the the reflectee is an invocation of a generic class,
    * the type arguments are the bindings of its type parameters.
    * If the reflectee is the original declaration of a generic,
@@ -823,7 +816,7 @@
    * the result of calling [reflect](*r*).
    * If evaluating the expression causes a compilation error
    * this method throws a [MirroredCompilationError].
-   * If evaluating the expression throws an exception *e* 
+   * If evaluating the expression throws an exception *e*
    * (that it does not catch)
    * this method throws *e*.
    */
@@ -874,13 +867,13 @@
    * Returns [:true:] if this mirror is equal to [other].
    * Otherwise returns [:false:].
    *
-   * The equality holds if and only if 
+   * The equality holds if and only if
    * (1) [other] is a mirror of the same kind
    * and
    * (2) This mirror and [other] reflect the same class.
-   * 
+   *
    * Note that if the reflected class is an invocation of
-   * a generic class,(2) implies that the reflected class 
+   * a generic class,(2) implies that the reflected class
    * and [other] have equal type arguments.
    */
    bool operator == (other);
@@ -921,7 +914,7 @@
    * Returns [:true:] if this mirror is equal to [other].
    * Otherwise returns [:false:].
    *
-   * The equality holds if and only if 
+   * The equality holds if and only if
    * (1) [other] is a mirror of the same kind
    * and
    * (2)  [:simpleName == other.simpleName:] and
@@ -953,6 +946,11 @@
   TypeMirror get returnType;
 
   /**
+   * The source code for the reflectee, if available. Otherwise null.
+   */
+  String get source;
+
+  /**
    * A list of mirrors on the parameters for the reflectee.
    */
   List<ParameterMirror> get parameters;
@@ -1033,7 +1031,7 @@
   /**
    * Returns true if this mirror is equal to [other].
    *
-   * The equality holds if and only if 
+   * The equality holds if and only if
    * (1) [other] is a mirror of the same kind
    * and
    * (2) [:simpleName == other.simpleName:] and
@@ -1069,7 +1067,7 @@
   /**
    * Returns true if this mirror is equal to [other].
    *
-   * The equality holds if and only if 
+   * The equality holds if and only if
    * (1) [other] is a mirror of the same kind
    * and
    * (2)  [:simpleName == other.simpleName:] and
@@ -1100,16 +1098,18 @@
   bool get isNamed;
 
   /**
-   * Returns [:true:] if the reflectee has a default value.
+   * Returns [:true:] if the reflectee has explicitly declared a default value.
    * Otherwise returns [:false:].
    */
   bool get hasDefaultValue;
 
   /**
-   * A mirror on the default value for this parameter, if it exists.
+   * If this is a required parameter, returns [:null:]. Otherwise returns a
+   * mirror on the default value for this parameter. If no default is declared
+   * for an optional parameter, the default is [:null:] and a mirror on [:null:]
+   * is returned.
    */
-  // TODO(ahe): This should return an InstanceMirror.
-  String get defaultValue;
+  InstanceMirror get defaultValue;
 }
 
 /**
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index f5066ee1..7d4f71b 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -21,40 +21,12 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-final _START_TAG_REGEXP = new RegExp('<(\\w+)');
-
 class _SvgElementFactoryProvider {
   static SvgElement createSvgElement_tag(String tag) {
     final Element temp =
       document.$dom_createElementNS("http://www.w3.org/2000/svg", tag);
     return temp;
   }
-
-  static SvgElement createSvgElement_svg(String svg) {
-    Element parentTag;
-    final match = _START_TAG_REGEXP.firstMatch(svg);
-    if (match != null && match.group(1).toLowerCase() == 'svg') {
-      parentTag = new Element.tag('div');
-    } else {
-      parentTag = new SvgSvgElement();
-    }
-
-    parentTag.innerHtml = svg;
-    if (parentTag.children.length == 1) return parentTag.children.removeLast();
-
-    throw new ArgumentError(
-        'SVG had ${parentTag.children.length} '
-        'top-level children but 1 expected');
-  }
-}
-
-class _SvgSvgElementFactoryProvider {
-  static SvgSvgElement createSvgSvgElement() {
-    final el = new SvgElement.tag("svg");
-    // The SVG spec requires the version attribute to match the spec version
-    el.attributes['version'] = "1.1";
-    return el;
-  }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -4757,10 +4729,28 @@
 @DomName('SVGElement')
 @Unstable()
 class SvgElement extends Element native "SVGElement" {
+  static final _START_TAG_REGEXP = new RegExp('<(\\w+)');
+
   factory SvgElement.tag(String tag) =>
-      _SvgElementFactoryProvider.createSvgElement_tag(tag);
-  factory SvgElement.svg(String svg) =>
-      _SvgElementFactoryProvider.createSvgElement_svg(svg);
+      document.$dom_createElementNS("http://www.w3.org/2000/svg", tag);
+  factory SvgElement.svg(String svg,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+
+    if (validator == null && treeSanitizer == null) {
+      validator = new NodeValidatorBuilder.common()..allowSvg();
+    }
+
+    final match = _START_TAG_REGEXP.firstMatch(svg);
+    var parentElement;
+    if (match != null && match.group(1).toLowerCase() == 'svg') {
+      parentElement = document.body;
+    } else {
+      parentElement = new SvgSvgElement();
+    }
+    var fragment = parentElement.createFragment(svg, validator: validator,
+        treeSanitizer: treeSanitizer);
+    return fragment.nodes.where((e) => e is SvgElement).single;
+  }
 
   _AttributeClassSet _cssClassSet;
   CssClassSet get classes {
@@ -4792,12 +4782,33 @@
     return container.innerHtml;
   }
 
-  void set innerHtml(String svg) {
-    final container = new Element.tag("div");
-    // Wrap the SVG string in <svg> so that SvgElements are created, rather than
-    // HTMLElements.
-    container.innerHtml = '<svg version="1.1">$svg</svg>';
-    this.children = container.children[0].children;
+  void set innerHtml(String value) {
+    this.setInnerHtml(value);
+  }
+
+  DocumentFragment createFragment(String svg,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+
+    if (treeSanitizer == null) {
+      if (validator == null) {
+        validator = new NodeValidatorBuilder.common()
+          ..allowSvg();
+      }
+      treeSanitizer = new NodeTreeSanitizer(validator);
+    }
+
+    // We create a fragment which will parse in the HTML parser
+    var html = '<svg version="1.1">$svg</svg>';
+    var fragment = document.body.createFragment(html,
+        treeSanitizer: treeSanitizer);
+
+    var svgFragment = new DocumentFragment();
+    // The root is the <svg/> element, need to pull out the contents.
+    var root = fragment.nodes.single;
+    while (root.firstChild != null) {
+      svgFragment.append(root.firstChild);
+    }
+    return svgFragment;
   }
 
   // Unsupported methods inherited from Element.
@@ -4817,8 +4828,8 @@
     throw new UnsupportedError("Cannot invoke insertAdjacentElement on SVG.");
   }
 
-  HtmlCollection get $dom_children {
-    throw new UnsupportedError("Cannot get dom_children on SVG.");
+  HtmlCollection get _children {
+    throw new UnsupportedError("Cannot get _children on SVG.");
   }
 
   bool get isContentEditable => false;
@@ -4839,7 +4850,7 @@
   factory SvgElement._() { throw new UnsupportedError("Not supported"); }
 
   // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
+  AnimatedString get _svgClassName => JS("AnimatedString", "#.className", this);
 
   @JSName('ownerSVGElement')
   @DomName('SVGElement.ownerSVGElement')
@@ -4876,7 +4887,12 @@
 @DomName('SVGSVGElement')
 @Unstable()
 class SvgSvgElement extends GraphicsElement implements FitToViewBox, ExternalResourcesRequired, ZoomAndPan native "SVGSVGElement" {
-  factory SvgSvgElement() => _SvgSvgElementFactoryProvider.createSvgSvgElement();
+  factory SvgSvgElement() {
+    final el = new SvgElement.tag("svg");
+    // The SVG spec requires the version attribute to match the spec version
+    el.attributes['version'] = "1.1";
+    return el;
+  }
 
   // To suppress missing implicit constructor warnings.
   factory SvgSvgElement._() { throw new UnsupportedError("Not supported"); }
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index 1095161..e9d3b1e 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -18,40 +18,12 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-final _START_TAG_REGEXP = new RegExp('<(\\w+)');
-
 class _SvgElementFactoryProvider {
   static SvgElement createSvgElement_tag(String tag) {
     final Element temp =
       document.$dom_createElementNS("http://www.w3.org/2000/svg", tag);
     return temp;
   }
-
-  static SvgElement createSvgElement_svg(String svg) {
-    Element parentTag;
-    final match = _START_TAG_REGEXP.firstMatch(svg);
-    if (match != null && match.group(1).toLowerCase() == 'svg') {
-      parentTag = new Element.tag('div');
-    } else {
-      parentTag = new SvgSvgElement();
-    }
-
-    parentTag.innerHtml = svg;
-    if (parentTag.children.length == 1) return parentTag.children.removeLast();
-
-    throw new ArgumentError(
-        'SVG had ${parentTag.children.length} '
-        'top-level children but 1 expected');
-  }
-}
-
-class _SvgSvgElementFactoryProvider {
-  static SvgSvgElement createSvgSvgElement() {
-    final el = new SvgElement.tag("svg");
-    // The SVG spec requires the version attribute to match the spec version
-    el.attributes['version'] = "1.1";
-    return el;
-  }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -5306,7 +5278,7 @@
 
   @DomName('SVGDocument.createEvent')
   @DocsEditable()
-  Event $dom_createEvent(String eventType) native "SVGDocument_createEvent_Callback";
+  Event _createEvent(String eventType) native "SVGDocument_createEvent_Callback";
 
 }
 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
@@ -5343,10 +5315,28 @@
 @DomName('SVGElement')
 @Unstable()
 class SvgElement extends Element {
+  static final _START_TAG_REGEXP = new RegExp('<(\\w+)');
+
   factory SvgElement.tag(String tag) =>
-      _SvgElementFactoryProvider.createSvgElement_tag(tag);
-  factory SvgElement.svg(String svg) =>
-      _SvgElementFactoryProvider.createSvgElement_svg(svg);
+      document.$dom_createElementNS("http://www.w3.org/2000/svg", tag);
+  factory SvgElement.svg(String svg,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+
+    if (validator == null && treeSanitizer == null) {
+      validator = new NodeValidatorBuilder.common()..allowSvg();
+    }
+
+    final match = _START_TAG_REGEXP.firstMatch(svg);
+    var parentElement;
+    if (match != null && match.group(1).toLowerCase() == 'svg') {
+      parentElement = document.body;
+    } else {
+      parentElement = new SvgSvgElement();
+    }
+    var fragment = parentElement.createFragment(svg, validator: validator,
+        treeSanitizer: treeSanitizer);
+    return fragment.nodes.where((e) => e is SvgElement).single;
+  }
 
   _AttributeClassSet _cssClassSet;
   CssClassSet get classes {
@@ -5378,12 +5368,33 @@
     return container.innerHtml;
   }
 
-  void set innerHtml(String svg) {
-    final container = new Element.tag("div");
-    // Wrap the SVG string in <svg> so that SvgElements are created, rather than
-    // HTMLElements.
-    container.innerHtml = '<svg version="1.1">$svg</svg>';
-    this.children = container.children[0].children;
+  void set innerHtml(String value) {
+    this.setInnerHtml(value);
+  }
+
+  DocumentFragment createFragment(String svg,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+
+    if (treeSanitizer == null) {
+      if (validator == null) {
+        validator = new NodeValidatorBuilder.common()
+          ..allowSvg();
+      }
+      treeSanitizer = new NodeTreeSanitizer(validator);
+    }
+
+    // We create a fragment which will parse in the HTML parser
+    var html = '<svg version="1.1">$svg</svg>';
+    var fragment = document.body.createFragment(html,
+        treeSanitizer: treeSanitizer);
+
+    var svgFragment = new DocumentFragment();
+    // The root is the <svg/> element, need to pull out the contents.
+    var root = fragment.nodes.single;
+    while (root.firstChild != null) {
+      svgFragment.append(root.firstChild);
+    }
+    return svgFragment;
   }
 
   // Unsupported methods inherited from Element.
@@ -5403,8 +5414,8 @@
     throw new UnsupportedError("Cannot invoke insertAdjacentElement on SVG.");
   }
 
-  HtmlCollection get $dom_children {
-    throw new UnsupportedError("Cannot get dom_children on SVG.");
+  HtmlCollection get _children {
+    throw new UnsupportedError("Cannot get _children on SVG.");
   }
 
   bool get isContentEditable => false;
@@ -5427,7 +5438,7 @@
   @DomName('SVGElement.className')
   @DocsEditable()
   @Experimental() // untriaged
-  AnimatedString get $dom_svgClassName native "SVGElement_className_Getter";
+  AnimatedString get _svgClassName native "SVGElement_className_Getter";
 
   @DomName('SVGElement.ownerSVGElement')
   @DocsEditable()
@@ -5479,7 +5490,12 @@
 @DomName('SVGSVGElement')
 @Unstable()
 class SvgSvgElement extends GraphicsElement implements FitToViewBox, ExternalResourcesRequired, ZoomAndPan {
-  factory SvgSvgElement() => _SvgSvgElementFactoryProvider.createSvgSvgElement();
+  factory SvgSvgElement() {
+    final el = new SvgElement.tag("svg");
+    // The SVG spec requires the version attribute to match the spec version
+    el.attributes['version'] = "1.1";
+    return el;
+  }
 
   // To suppress missing implicit constructor warnings.
   factory SvgSvgElement._() { throw new UnsupportedError("Not supported"); }
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index 08ddefd..7c85f1d 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -478,7 +478,7 @@
   @JSName('connect')
   @DomName('AudioNode.connect')
   @DocsEditable()
-  void $dom_connect(destination, int output, [int input]) native;
+  void _connect(destination, int output, [int input]) native;
 
   @DomName('AudioNode.disconnect')
   @DocsEditable()
@@ -486,11 +486,11 @@
 
   @DomName('AudioNode.connect')
   void connectNode(AudioNode destination, [int output = 0, int input = 0]) =>
-      $dom_connect(destination, output, input);
+      _connect(destination, output, input);
 
   @DomName('AudioNode.connect')
   void connectParam(AudioParam destination, [int output = 0]) =>
-      $dom_connect(destination, output);
+      _connect(destination, output);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
diff --git a/sdk/lib/web_audio/dartium/web_audio_dartium.dart b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
index 64d95f9..cd8b0b9 100644
--- a/sdk/lib/web_audio/dartium/web_audio_dartium.dart
+++ b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
@@ -587,7 +587,7 @@
   @DocsEditable()
   int get numberOfOutputs native "AudioNode_numberOfOutputs_Getter";
 
-  void $dom_connect(destination, int output, [int input]) {
+  void _connect(destination, int output, [int input]) {
     if ((input is int || input == null) && (output is int || output == null) && (destination is AudioNode || destination == null)) {
       _connect_1(destination, output, input);
       return;
@@ -621,11 +621,11 @@
 
   @DomName('AudioNode.connect')
   void connectNode(AudioNode destination, [int output = 0, int input = 0]) =>
-      $dom_connect(destination, output, input);
+      _connect(destination, output, input);
 
   @DomName('AudioNode.connect')
   void connectParam(AudioParam destination, [int output = 0]) =>
-      $dom_connect(destination, output);
+      _connect(destination, output);
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
index 843ace1..014c34f 100644
--- a/tests/co19/co19-analyzer.status
+++ b/tests/co19/co19-analyzer.status
@@ -231,6 +231,9 @@
 Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t07: fail, OK
 Language/12_Expressions/30_Identifier_Reference_A14_t03: fail, OK
 
+# co19 issue #543: invocation of a non-function
+Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t02: fail, OK
+
 
 # co19-roll r546 (11.08.2013) caused these failures
 Language/13_Statements/11_Return_A07_t01: fail # co19-roll r546: Please triage this failure
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 3d31a9d..de5a6db 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -50,6 +50,8 @@
 LibTest/async/Stream/Stream.periodic_A01_t01: PASS, FAIL, OK # co19 issue 538
 LibTest/async/Stream/Stream.periodic_A03_t01: PASS, FAIL, OK # co19 issue 538
 LibTest/async/Timer/run_A01_t01: PASS, FAIL, OK # co19 issue 538
+LibTest/async/Timer/Timer_A01_t01: PASS, FAIL, OK # co19 issue 538
+LibTest/async/Timer/Timer_A02_t01: PASS, FAIL, OK # co19 issue 538
 LibTest/async/Timer/Timer.periodic_A01_t01: PASS, FAIL, OK # co19 issue 537
 LibTest/async/Timer/Timer.periodic_A02_t01: PASS, FAIL, OK # co19 issue 538
 LibTest/async/Future/Future.delayed_A01_t02: PASS, FAIL, OK # co19 issue 536
@@ -64,12 +66,15 @@
 Utils/tests/Expect/listEquals_A03_t01: FAIL, OK # co19 issue 500
 Utils/tests/Expect/setEquals_A02_t01: FAIL, OK # co19 issue 499
 
-LibTest/isolate_api/streamSpawnFunction_A02_t02: PASS, FAIL, OK # co19 issue 540
-LibTest/isolate_api/streamSpawnFunction_A02_t03: PASS, FAIL, OK # co19 issue 540
+LibTest/isolate/isolate_api/streamSpawnFunction_A02_t02: PASS, FAIL, OK # co19 issue 540
+LibTest/isolate/isolate_api/streamSpawnFunction_A02_t03: PASS, FAIL, OK # co19 issue 540
 LibTest/isolate/IsolateStream/contains_A02_t01: PASS, FAIL, OK # co19 issue 540
 
 LibTest/async/EventTransformStream/listen_A04_t01: Pass, Timeout # co19 issue 542
 
+LibTest/async/EventTransformStream/elementAt_A03_t01: FAIL # co19 issue 545
+LibTest/async/Stream/elementAt_A03_t01: FAIL # co19 issue 545
+
 ### CHECKED MODE FAILURES ###
 
 [ ($runtime == vm || $compiler == dart2js) && $checked]
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 3e06a4b..d9637be 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -11,8 +11,6 @@
 LibTest/core/double/floor_A01_t05: Fail # co19 issue 428
 LibTest/core/double/ceil_A01_t05: Fail # co19 issue 428
 
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t04: Fail # Issue 5743
-
 Language/07_Classes/4_Abstract_Instance_Members_A03_t02: Fail # Dart issue 978
 Language/07_Classes/4_Abstract_Instance_Members_A03_t03: Fail # Dart issue 978
 Language/07_Classes/4_Abstract_Instance_Members_A03_t04: Fail # Dart issue 978
@@ -25,9 +23,6 @@
 Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Fail # Dart issue 5802
 Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t05: Fail # Dart issue 5894
 
-
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # Issue 6085
-
 LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A03_t01: Fail # Issue 12508
 LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail # Issue 12508
 LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # Issue 12508
@@ -179,7 +174,6 @@
 Language/13_Statements/03_Variable_Declaration_A04_t08: fail # co19 issue 535
 Language/13_Statements/06_For_A01_t11: fail # Dart issue 5675
 Language/13_Statements/09_Switch_A01_t02: fail # co19-roll r546: Please triage this failure
-Language/13_Statements/09_Switch_A02_t01: fail # co19-roll r546: Please triage this failure
 Language/13_Statements/09_Switch_A02_t02: fail # co19-roll r546: Please triage this failure
 Language/13_Statements/09_Switch_A03_t01: fail # co19-roll r546: Please triage this failure
 Language/13_Statements/09_Switch_A03_t02: fail # co19-roll r546: Please triage this failure
@@ -216,7 +210,6 @@
 Language/14_Libraries_and_Scripts/5_URIs_A01_t21: fail # Issue 12518
 LibTest/async/StreamSink/close_A01_t01: fail # co19 503
 
-LibTest/async/Timer/Timer_A02_t01: fail, pass # co19 issue 538
 LibTest/core/DateTime/parse_A03_t01: fail # Issue 12514
 LibTest/isolate/isolate_api/spawnFunction_A04_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/isolate_api/streamSpawnFunction_A02_t01: fail # co19-roll r546: Please triage this failure
diff --git a/tests/co19/test_config.dart b/tests/co19/test_config.dart
index 5756107..547ea88 100644
--- a/tests/co19/test_config.dart
+++ b/tests/co19/test_config.dart
@@ -6,6 +6,7 @@
 
 import 'dart:io';
 import '../../tools/testing/dart/test_suite.dart';
+import '../../tools/testing/dart/utils.dart' show Path;
 
 class Co19TestSuite extends StandardTestSuite {
   RegExp _testRegExp = new RegExp(r"t[0-9]{2}.dart$");
diff --git a/tests/compiler/dart2js/dart_backend_test.dart b/tests/compiler/dart2js/dart_backend_test.dart
index aa5a70f..2afbe17 100644
--- a/tests/compiler/dart2js/dart_backend_test.dart
+++ b/tests/compiler/dart2js/dart_backend_test.dart
@@ -454,7 +454,8 @@
   localfoo();
 }
 ''';
-  MockCompiler compiler = new MockCompiler();
+  MockCompiler compiler = new MockCompiler(emitJavaScript: false);
+  assert(compiler.backend is DartBackend);
   compiler.parseScript(src);
   FunctionElement mainElement = compiler.mainApp.find(leg.Compiler.MAIN);
   compiler.processQueue(compiler.enqueuer.resolution, mainElement);
diff --git a/tests/compiler/dart2js/mirror_helper_rename_test.dart b/tests/compiler/dart2js/mirror_helper_rename_test.dart
new file mode 100644
index 0000000..67f1a95
--- /dev/null
+++ b/tests/compiler/dart2js/mirror_helper_rename_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import 'memory_compiler.dart' show compilerFor;
+import '../../../sdk/lib/_internal/compiler/implementation/apiimpl.dart' show
+    Compiler;
+import
+    '../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart'
+show
+    Node;
+import
+    '../../../sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart';
+import
+    '../../../sdk/lib/_internal/compiler/implementation/mirror_renamer/mirror_renamer.dart';
+import
+    '../../../sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart'
+show
+    SourceString;
+
+main() {
+  testWithMirrorHelperLibrary(minify: true);
+  testWithMirrorHelperLibrary(minify: false);
+  testWithoutMirrorHelperLibrary(minify: true);
+  testWithoutMirrorHelperLibrary(minify: false);
+}
+
+Compiler runCompiler({useMirrorHelperLibrary: false, minify: false}) {
+  List<String> options = ['--output-type=dart'];
+  if (minify) {
+    options.add('--minify');
+  }
+  Compiler compiler = compilerFor(MEMORY_SOURCE_FILES, options: options);
+  DartBackend backend = compiler.backend;
+  backend.useMirrorHelperLibrary = useMirrorHelperLibrary;
+  compiler.runCompiler(Uri.parse('memory:main.dart'));
+  return compiler;
+}
+
+void testWithMirrorHelperLibrary({bool minify}) {
+  Compiler compiler = runCompiler(useMirrorHelperLibrary: true, minify: minify);
+
+  DartBackend backend = compiler.backend;
+  MirrorRenamer mirrorRenamer = backend.mirrorRenamer;
+  Map<Node, String> renames = backend.renames;
+  Map<String, SourceString> symbols = mirrorRenamer.symbols;
+
+  Expect.isFalse(null == backend.mirrorHelperLibrary);
+  Expect.isFalse(null == backend.mirrorHelperGetNameFunction);
+
+  for (Node n in renames.keys) {
+    if (symbols.containsKey(renames[n])) {
+      if(n.toString() == 'getName') {
+        Expect.equals(
+            const SourceString(MirrorRenamer.MIRROR_HELPER_GET_NAME_FUNCTION),
+            symbols[renames[n]]);
+      } else {
+        Expect.equals(n.toString(), symbols[renames[n]].stringValue);
+      }
+    }
+  }
+
+  String output = compiler.assembledCode;
+  String getNameMatch = MirrorRenamer.MIRROR_HELPER_GET_NAME_FUNCTION;
+  Iterable i = getNameMatch.allMatches(output);
+
+
+  if (minify) {
+    Expect.equals(0, i.length);
+  } else {
+    // Appears twice in code (defined & called).
+    Expect.equals(2, i.length);
+  }
+
+  String mapMatch = 'const<String,SourceString>';
+  i = mapMatch.allMatches(output);
+  Expect.equals(1, i.length);
+}
+
+void testWithoutMirrorHelperLibrary({bool minify}) {
+  Compiler compiler =
+      runCompiler(useMirrorHelperLibrary: false, minify: minify);
+  DartBackend backend = compiler.backend;
+
+  Expect.equals(null, backend.mirrorHelperLibrary);
+  Expect.equals(null, backend.mirrorHelperGetNameFunction);
+  Expect.equals(null, backend.mirrorRenamer);
+}
+
+const MEMORY_SOURCE_FILES = const <String, String> {
+  'main.dart': """
+import 'dart:mirrors';
+
+class Foo {
+  noSuchMethod(Invocation invocation) {
+    MirrorSystem.getName(invocation.memberName);
+  }
+}
+
+void main() {
+  new Foo().fisk();
+}
+"""};
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mirror_helper_test.dart b/tests/compiler/dart2js/mirror_helper_test.dart
index 01e69ed..ba3b9af 100644
--- a/tests/compiler/dart2js/mirror_helper_test.dart
+++ b/tests/compiler/dart2js/mirror_helper_test.dart
@@ -29,10 +29,10 @@
 
 
 main() {
-  testWithMirrorRenaming();
-  testWithoutMirrorRenaming();
-  testWithMirrorRenamingMinify();
-  testWithoutMirrorRenamingMinify();
+  testWithMirrorRenaming(minify: true);
+  testWithMirrorRenaming(minify: false);
+  testWithoutMirrorRenaming(minify: true);
+  testWithoutMirrorRenaming(minify: false);
 }
 
 Compiler runCompiler({useMirrorHelperLibrary: false, minify: false}) {
@@ -47,63 +47,27 @@
   return compiler;
 }
 
-void testWithMirrorRenaming() {
-  Compiler compiler = runCompiler(useMirrorHelperLibrary: true, minify: false);
+void testWithMirrorRenaming({bool minify}) {
+  Compiler compiler = runCompiler(useMirrorHelperLibrary: true, minify: minify);
 
   DartBackend backend = compiler.backend;
+  MirrorRenamer mirrorRenamer = backend.mirrorRenamer;
   Map<Node, String> renames = backend.renames;
   Map<LibraryElement, String> imports = backend.imports;
 
   Node getNameFunctionNode =
       backend.memberNodes.values.first.first.body.statements.nodes.head;
 
-  Expect.equals(MirrorRenamer.MIRROR_HELPER_GET_NAME_FUNCTION,
+  Expect.equals(renames[mirrorRenamer.mirrorHelperGetNameFunctionNode.name],
                 renames[getNameFunctionNode.expression.selector]);
-  Expect.equals(MirrorRenamer.MIRROR_HELPER_CLASS_FULLY_QUALIFIED_NAME,
+  Expect.equals("",
                 renames[getNameFunctionNode.expression.receiver]);
-  Expect.equals(2, imports.keys.length);
-  Expect.isTrue(imports.keys.any((library) =>
-      library.canonicalUri ==
-          new Uri(path: MirrorRenamer.MIRROR_HELPER_LIBRARY_NAME)));
-}
-
-void testWithMirrorRenamingMinify() {
-  Compiler compiler = runCompiler(useMirrorHelperLibrary: true, minify: true);
-
-  DartBackend backend = compiler.backend;
-  Map<Node, String> renames = backend.renames;
-  Map<LibraryElement, String> imports = backend.imports;
-
-  Node getNameFunctionNode =
-      backend.memberNodes.values.first.first.body.statements.nodes.head;
-
-  Expect.equals(MirrorRenamer.MIRROR_HELPER_GET_NAME_FUNCTION,
-      renames[getNameFunctionNode.expression.selector]);
-  Expect.equals(MirrorRenamer.MIRROR_HELPER_CLASS_FULLY_QUALIFIED_NAME,
-                renames[getNameFunctionNode.expression.receiver]);
-  Expect.equals(2, imports.keys.length);
-  Expect.isTrue(imports.keys.any((library) =>
-      library.canonicalUri ==
-          new Uri(path: MirrorRenamer.MIRROR_HELPER_LIBRARY_NAME)));
-}
-
-void testWithoutMirrorRenaming() {
-  Compiler compiler = runCompiler(useMirrorHelperLibrary: false, minify: false);
-
-  DartBackend backend = compiler.backend;
-  Map<Node, String> renames = backend.renames;
-  Map<LibraryElement, String> imports = backend.imports;
-
-  Node getNameFunctionNode =
-      backend.memberNodes.values.first.first.body.statements.nodes.head;
-
-  Expect.isFalse(renames.containsKey(getNameFunctionNode.expression.selector));
-  Expect.isFalse(renames.containsKey(getNameFunctionNode.expression.receiver));
   Expect.equals(1, imports.keys.length);
 }
 
-void testWithoutMirrorRenamingMinify() {
-  Compiler compiler = runCompiler(useMirrorHelperLibrary: false, minify: true);
+void testWithoutMirrorRenaming({bool minify}) {
+  Compiler compiler =
+      runCompiler(useMirrorHelperLibrary: false, minify: minify);
 
   DartBackend backend = compiler.backend;
   Map<Node, String> renames = backend.renames;
@@ -121,7 +85,6 @@
   'main.dart': """
 import 'dart:mirrors';
 
-
 class Foo {
   noSuchMethod(Invocation invocation) {
     MirrorSystem.getName(invocation.memberName);
diff --git a/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart b/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart
index 35885cd..c1206fc 100644
--- a/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart
+++ b/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart
@@ -10,6 +10,10 @@
     '../../../sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart'
 show
     DartBackend;
+import
+    '../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart'
+show
+    Node;
 
 main() {
   testUniqueMinification();
@@ -31,10 +35,25 @@
 void testUniqueMinification() {
   Compiler compiler = runCompiler(useMirrorHelperLibrary: true, minify: true);
   DartBackend backend = compiler.backend;
+  MirrorRenamer mirrorRenamer = backend.mirrorRenamer;
   Map<Node, String> renames = backend.renames;
+  Map<String, SourceString> symbols = mirrorRenamer.symbols;
 
-  //'Foo' appears twice, so toSet() reduces the length by 1.
-  Expect.equals(renames.values.toSet().length, renames.values.length - 1);
+  // Check that no two different source code names get the same mangled name,
+  // with the exception of MirrorSystem.getName that gets renamed to the same
+  // mangled name as the getNameHelper from _mirror_helper.dart.
+  for (Node node in renames.keys) {
+    Identifier identifier = node.asIdentifier();
+    if (identifier != null) {
+      SourceString source = identifier.source;
+      if (mirrorRenamer.mirrorSystemGetNameNodes.first.selector == node)
+        continue;
+      if (symbols.containsKey(renames[node])) {
+        print(node);
+        Expect.equals(source, symbols[renames[node]]);
+      }
+    }
+  }
 }
 
 void testNoUniqueMinification() {
@@ -42,7 +61,7 @@
   DartBackend backend = compiler.backend;
   Map<Node, String> renames = backend.renames;
 
-  //'Foo' appears twice and now 'invocation' and 'hest' can get the same name.
+  // 'Foo' appears twice and 'invocation' and 'hest' get the same mangled name.
   Expect.equals(renames.values.toSet().length, renames.values.length - 2);
 }
 
@@ -52,7 +71,7 @@
 
 class Foo {
   noSuchMethod(invocation) {
-    MirrorSystem.getName(const Symbol('hest'));
+    MirrorSystem.getName(null);
   }
 }
 
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 688f4bc..c30295e 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -225,6 +225,7 @@
                 bool disableTypeInference: false,
                 bool analyzeAll: false,
                 bool analyzeOnly: false,
+                bool emitJavaScript: true,
                 bool preserveComments: false})
       : warnings = [], errors = [],
         sourceFiles = new Map<String, SourceFile>(),
@@ -235,6 +236,7 @@
               disableTypeInferenceFlag: disableTypeInference,
               analyzeAllFlag: analyzeAll,
               analyzeOnly: analyzeOnly,
+              emitJavaScript: emitJavaScript,
               preserveComments: preserveComments) {
     coreLibrary = createLibrary("core", coreSource);
     // We need to set the assert method to avoid calls with a 'null'
diff --git a/tests/compiler/dart2js/simple_function_subtype_test.dart b/tests/compiler/dart2js/simple_function_subtype_test.dart
new file mode 100644
index 0000000..7329598
--- /dev/null
+++ b/tests/compiler/dart2js/simple_function_subtype_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that simple function subtype checks use predicates.
+
+library simple_function_subtype_test;
+import "package:expect/expect.dart";
+import 'compiler_helper.dart';
+
+const String TEST = r"""
+typedef Args0();
+typedef Args1(a);
+typedef Args2(a, b);
+typedef Args3(a, b, c);
+typedef Args4(a, b, c, d);
+typedef Args5(a, b, c, d, e);
+typedef Args6(a, b, c, d, e, f);
+typedef Args7(a, b, c, d, e, f, g);
+typedef Args8(a, b, c, d, e, f, g, h);
+typedef Args9(a, b, c, d, e, f, g, h, i);
+typedef Args10(a, b, c, d, e, f, g, h, i, j);
+typedef Args11(a, b, c, d, e, f, g, h, i, j, k);
+typedef Args12(a, b, c, d, e, f, g, h, i, j, k, l);
+typedef Args13(a, b, c, d, e, f, g, h, i, j, k, l, m);
+typedef Args14(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
+typedef Args15(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
+
+args5_10(a, b, c, d, e, [f, g, h, i, j]) {}
+
+foo() {
+  print(args5_10 is Args0);
+  print(args5_10 is Args1);
+  print(args5_10 is Args2);
+  print(args5_10 is Args3);
+  print(args5_10 is Args4);
+  print(args5_10 is Args5);
+  print(args5_10 is Args6);
+  print(args5_10 is Args7);
+  print(args5_10 is Args8);
+  print(args5_10 is Args9);
+  print(args5_10 is Args10);
+  print(args5_10 is Args11);
+  print(args5_10 is Args12);
+  print(args5_10 is Args13);
+  print(args5_10 is Args14);
+  print(args5_10 is Args15);
+}
+""";
+
+main() {
+  String generated = compile(TEST, entry: 'foo');
+  for (int i = 0 ; i <= 15  ; i++) {
+    String predicateCheck = '.\$is_args$i';
+    Expect.isTrue(generated.contains(predicateCheck),
+      'Expected predicate check $predicateCheck');
+  }
+  Expect.isFalse(generated.contains('checkFunctionSubtype'),
+    'Unexpected use of checkFunctionSubtype');
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/type_representation_test.dart
index 001a030..8c651f6 100644
--- a/tests/compiler/dart2js/type_representation_test.dart
+++ b/tests/compiler/dart2js/type_representation_test.dart
@@ -124,7 +124,7 @@
       env.getElement('m3').computeType(env.compiler));
 
   // m4() {}
-  expect('{$func: "dynamic_"}',
+  expect('{$func: "args0"}',
       env.getElement('m4').computeType(env.compiler));
 
   // m5(int a, String b) {}
diff --git a/tests/compiler/dart2js_native/mirror_intercepted_field_test.dart b/tests/compiler/dart2js_native/mirror_intercepted_field_test.dart
new file mode 100644
index 0000000..a56cbb0
--- /dev/null
+++ b/tests/compiler/dart2js_native/mirror_intercepted_field_test.dart
@@ -0,0 +1,29 @@
+// 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:mirrors';
+import "package:expect/expect.dart";
+
+class B native "B" {
+  // Having this field in a native class will generate accessors with
+  // the interceptor calling convention.
+  var f;
+}
+
+class A {
+  int f;
+}
+
+const symF = const Symbol('f');
+
+main() {
+  var a = new A();
+
+  InstanceMirror mirror = reflect(a);
+  mirror.setField(symF, 42);
+  Expect.equals(42, a.f);
+
+  mirror = mirror.getField(symF);
+  Expect.equals(42, mirror.reflectee);
+}
diff --git a/tests/corelib/linked_hash_map_from_iterable_test.dart b/tests/corelib/linked_hash_map_from_iterable_test.dart
index d581532..02c9029 100644
--- a/tests/corelib/linked_hash_map_from_iterable_test.dart
+++ b/tests/corelib/linked_hash_map_from_iterable_test.dart
@@ -20,7 +20,6 @@
 
   Expect.isTrue(map is Map);
   Expect.isTrue(map is LinkedHashMap);
-  Expect.isFalse(map is HashMap);
 
   Expect.equals(3, map.length);
   Expect.equals(3, map.keys.length);
@@ -36,7 +35,6 @@
 
   Expect.isTrue(map is Map);
   Expect.isTrue(map is LinkedHashMap);
-  Expect.isFalse(map is HashMap);
 
   Expect.equals(3, map.length);
   Expect.equals(3, map.keys.length);
@@ -52,7 +50,6 @@
 
   Expect.isTrue(map is Map);
   Expect.isTrue(map is LinkedHashMap);
-  Expect.isFalse(map is HashMap);
 
   Expect.equals(3, map.length);
   Expect.equals(3, map.keys.length);
@@ -69,7 +66,6 @@
 
   Expect.isTrue(map is Map);
   Expect.isTrue(map is LinkedHashMap);
-  Expect.isFalse(map is HashMap);
 
   Expect.equals(3, map.length);
   Expect.equals(3, map.keys.length);
@@ -84,7 +80,6 @@
   var map = new LinkedHashMap.fromIterable([]);
   Expect.isTrue(map is Map);
   Expect.isTrue(map is LinkedHashMap);
-  Expect.isFalse(map is HashMap);
 
   Expect.equals(0, map.length);
   Expect.equals(0, map.keys.length);
@@ -96,7 +91,6 @@
 
   Expect.isTrue(map is Map);
   Expect.isTrue(map is LinkedHashMap);
-  Expect.isFalse(map is HashMap);
 
   Expect.equals(2, map.length);
   Expect.equals(2, map.keys.length);
diff --git a/tests/corelib/linked_hash_map_from_iterables_test.dart b/tests/corelib/linked_hash_map_from_iterables_test.dart
index 0212dd4..37a5534 100644
--- a/tests/corelib/linked_hash_map_from_iterables_test.dart
+++ b/tests/corelib/linked_hash_map_from_iterables_test.dart
@@ -18,7 +18,6 @@
   var map = new LinkedHashMap.fromIterables([1, 2, 3], ["one", "two", "three"]);
   Expect.isTrue(map is Map);
   Expect.isTrue(map is LinkedHashMap);
-  Expect.isFalse(map is HashMap);
 
   Expect.equals(3, map.length);
   Expect.equals(3, map.keys.length);
@@ -33,7 +32,6 @@
   var map = new LinkedHashMap.fromIterables([], []);
   Expect.isTrue(map is Map);
   Expect.isTrue(map is LinkedHashMap);
-  Expect.isFalse(map is HashMap);
 
   Expect.equals(0, map.length);
   Expect.equals(0, map.keys.length);
@@ -52,7 +50,6 @@
   var map = new LinkedHashMap.fromIterables([1, 2, 2], ["one", "two", "three"]);
   Expect.isTrue(map is Map);
   Expect.isTrue(map is LinkedHashMap);
-  Expect.isFalse(map is HashMap);
 
   Expect.equals(2, map.length);
   Expect.equals(2, map.keys.length);
diff --git a/tests/corelib/map_from_iterable_test.dart b/tests/corelib/map_from_iterable_test.dart
index 4d0468d..c5aa0c0 100644
--- a/tests/corelib/map_from_iterable_test.dart
+++ b/tests/corelib/map_from_iterable_test.dart
@@ -19,7 +19,7 @@
   var map = new Map.fromIterable([1, 2, 3]);
 
   Expect.isTrue(map is Map);
-  Expect.isTrue(map is HashMap);
+  Expect.isTrue(map is LinkedHashMap);
 
   Expect.equals(3, map.length);
   Expect.equals(3, map.keys.length);
@@ -34,7 +34,7 @@
   var map = new Map.fromIterable([1, 2, 3], value: (x) => x + 1);
 
   Expect.isTrue(map is Map);
-  Expect.isTrue(map is HashMap);
+  Expect.isTrue(map is LinkedHashMap);
 
   Expect.equals(3, map.length);
   Expect.equals(3, map.keys.length);
@@ -49,7 +49,7 @@
   var map = new Map.fromIterable([1, 2, 3], key: (x) => x + 1);
 
   Expect.isTrue(map is Map);
-  Expect.isTrue(map is HashMap);
+  Expect.isTrue(map is LinkedHashMap);
 
   Expect.equals(3, map.length);
   Expect.equals(3, map.keys.length);
@@ -64,9 +64,8 @@
   var map = new Map.fromIterable([1, 2, 3],
       key: (x) => x + 1, value: (x) => x - 1);
 
-
   Expect.isTrue(map is Map);
-  Expect.isTrue(map is HashMap);
+  Expect.isTrue(map is LinkedHashMap);
 
   Expect.equals(3, map.length);
   Expect.equals(3, map.keys.length);
@@ -80,7 +79,7 @@
 void emptyIterableTest() {
   var map = new Map.fromIterable([]);
   Expect.isTrue(map is Map);
-  Expect.isTrue(map is HashMap);
+  Expect.isTrue(map is LinkedHashMap);
 
   Expect.equals(0, map.length);
   Expect.equals(0, map.keys.length);
@@ -91,7 +90,7 @@
   var map = new Map.fromIterable([1, 2, 2], key: (x) => x + 1);
 
   Expect.isTrue(map is Map);
-  Expect.isTrue(map is HashMap);
+  Expect.isTrue(map is LinkedHashMap);
 
   Expect.equals(2, map.length);
   Expect.equals(2, map.keys.length);
diff --git a/tests/corelib/map_from_iterables_test.dart b/tests/corelib/map_from_iterables_test.dart
index 8c21e9f..ca1793c 100644
--- a/tests/corelib/map_from_iterables_test.dart
+++ b/tests/corelib/map_from_iterables_test.dart
@@ -17,7 +17,7 @@
 void positiveTest() {
   var map = new Map.fromIterables([1, 2, 3], ["one", "two", "three"]);
   Expect.isTrue(map is Map);
-  Expect.isTrue(map is HashMap);
+  Expect.isTrue(map is LinkedHashMap);
 
   Expect.equals(3, map.length);
   Expect.equals(3, map.keys.length);
@@ -31,7 +31,7 @@
 void emptyMapTest() {
   var map = new Map.fromIterables([], []);
   Expect.isTrue(map is Map);
-  Expect.isTrue(map is HashMap);
+  Expect.isTrue(map is LinkedHashMap);
 
   Expect.equals(0, map.length);
   Expect.equals(0, map.keys.length);
@@ -49,7 +49,7 @@
 void equalElementsTest() {
   var map = new Map.fromIterables([1, 2, 2], ["one", "two", "three"]);
   Expect.isTrue(map is Map);
-  Expect.isTrue(map is HashMap);
+  Expect.isTrue(map is LinkedHashMap);
 
   Expect.equals(2, map.length);
   Expect.equals(2, map.keys.length);
diff --git a/tests/corelib/map_from_test.dart b/tests/corelib/map_from_test.dart
index 21597fb..736ead0 100644
--- a/tests/corelib/map_from_test.dart
+++ b/tests/corelib/map_from_test.dart
@@ -9,6 +9,7 @@
 main() {
   testWithConstMap();
   testWithNonConstMap();
+  testWithHashMap();
   testWithLinkedMap();
 }
 
@@ -17,7 +18,7 @@
   var otherMap = new Map.from(map);
   Expect.isTrue(otherMap is Map);
   Expect.isTrue(otherMap is HashMap);
-  Expect.isTrue(otherMap is !LinkedHashMap);
+  Expect.isTrue(otherMap is LinkedHashMap);
 
   Expect.equals(2, otherMap.length);
   Expect.equals(2, otherMap.keys.length);
@@ -38,7 +39,7 @@
   var otherMap = new Map.from(map);
   Expect.isTrue(otherMap is Map);
   Expect.isTrue(otherMap is HashMap);
-  Expect.isTrue(otherMap is !LinkedHashMap);
+  Expect.isTrue(otherMap is LinkedHashMap);
 
   Expect.equals(2, otherMap.length);
   Expect.equals(2, otherMap.keys.length);
@@ -68,11 +69,23 @@
   Expect.equals(3, otherMap.values.length);
 }
 
+testWithHashMap() {
+  var map = const { 'b': 1, 'a': 2, 'c': 3 };
+  var otherMap = new HashMap.from(map);
+  Expect.isTrue(otherMap is Map);
+  Expect.isTrue(otherMap is HashMap);
+  Expect.isTrue(otherMap is !LinkedHashMap);
+  var i = 1;
+  for (var val in map.values) {
+    Expect.equals(i++, val);
+  }
+}
+
 testWithLinkedMap() {
   var map = const { 'b': 1, 'a': 2, 'c': 3 };
   var otherMap = new LinkedHashMap.from(map);
   Expect.isTrue(otherMap is Map);
-  Expect.isTrue(otherMap is! HashMap);
+  Expect.isTrue(otherMap is HashMap);
   Expect.isTrue(otherMap is LinkedHashMap);
   var i = 1;
   for (var val in map.values) {
diff --git a/tests/corelib/map_values2_test.dart b/tests/corelib/map_values2_test.dart
index 8efc532..9718949 100644
--- a/tests/corelib/map_values2_test.dart
+++ b/tests/corelib/map_values2_test.dart
@@ -42,9 +42,9 @@
   Expect.isFalse(map5.values is Iterable<bool>);
   Expect.isFalse(map5.values is List);
   Expect.equals(2, map5.values.length);
-  Expect.isTrue(map5.values.first == 43 || map5.values.first == 500);
-  Expect.isTrue(map5.values.last == 43 || map5.values.first == 500);
-  Expect.notEquals(map5.values.first, map5.values.last);
+  // new Map gives a LinkedHashMap, so we know the order.
+  Expect.isTrue(map5.values.first == 43);
+  Expect.isTrue(map5.values.last == 500);
 
   Expect.isTrue(map6.values is Iterable<int>);
   Expect.isFalse(map6.values is Iterable<bool>);
diff --git a/tests/corelib/uri_path_test.dart b/tests/corelib/uri_path_test.dart
index 058d912..d1804f9 100644
--- a/tests/corelib/uri_path_test.dart
+++ b/tests/corelib/uri_path_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.
 
+import "dart:collection";
+
 import "package:expect/expect.dart";
 
 void testInvalidArguments() {
@@ -91,14 +93,36 @@
   test(encoded + "/" + encoded, [unencoded, unencoded]);
 
   Uri uri;
-  uri = new Uri(pathSegments: ["xxx", "yyy", "zzz"]);
+  List pathSegments = ["xxx", "yyy", "zzz"];
+
+  uri = new Uri(pathSegments: pathSegments);
+  Expect.equals(3, uri.pathSegments.length);
+  uri = new Uri(pathSegments: pathSegments.where((_) => true));
+  Expect.equals(3, uri.pathSegments.length);
+  uri = new Uri(pathSegments: new DoubleLinkedQueue.from(pathSegments));
+  Expect.equals(3, uri.pathSegments.length);
+
+  uri = new Uri(scheme: "http",
+                host: "host",
+                pathSegments: pathSegments);
   Expect.equals(3, uri.pathSegments.length);
   uri = new Uri(scheme: "http",
                 host: "host",
-                pathSegments: ["xxx", "yyy", "zzz"]);
+                pathSegments: pathSegments.where((_) => true));
+  Expect.equals(3, uri.pathSegments.length);
+  uri = new Uri(scheme: "http",
+                host: "host",
+                pathSegments: new DoubleLinkedQueue.from(pathSegments));
+  Expect.equals(3, uri.pathSegments.length);
+
+  uri = new Uri(scheme: "file",
+                pathSegments: pathSegments);
   Expect.equals(3, uri.pathSegments.length);
   uri = new Uri(scheme: "file",
-                pathSegments: ["xxx", "yyy", "zzz"]);
+                pathSegments: pathSegments.where((_) => true));
+  Expect.equals(3, uri.pathSegments.length);
+  uri = new Uri(scheme: "file",
+                pathSegments: new DoubleLinkedQueue.from(pathSegments));
   Expect.equals(3, uri.pathSegments.length);
 }
 
diff --git a/tests/corelib/uri_test.dart b/tests/corelib/uri_test.dart
index 0d671b7..351c3b9 100644
--- a/tests/corelib/uri_test.dart
+++ b/tests/corelib/uri_test.dart
@@ -5,7 +5,7 @@
 library uriTest;
 
 import "package:expect/expect.dart";
-import 'dart:utf';
+import 'dart:convert';
 
 testUri(String uri, bool isAbsolute) {
   Expect.equals(isAbsolute, Uri.parse(uri).isAbsolute);
@@ -205,7 +205,7 @@
 
   // URI encode tests
   // Create a string with code point 0x10000 encoded as a surrogate pair.
-  var s = decodeUtf8([0xf0, 0x90, 0x80, 0x80]);
+  var s = UTF8.decode([0xf0, 0x90, 0x80, 0x80]);
 
   Expect.stringEquals("\u{10000}", s);
 
diff --git a/tests/html/cssstyledeclaration_test.dart b/tests/html/cssstyledeclaration_test.dart
index 45df00c..964e9f9 100644
--- a/tests/html/cssstyledeclaration_test.dart
+++ b/tests/html/cssstyledeclaration_test.dart
@@ -7,6 +7,7 @@
 import '../../pkg/unittest/lib/html_config.dart';
 import 'dart:html';
 import 'dart:async';
+import 'utils.dart';
 
 main() {
   useHtmlConfiguration();
@@ -103,7 +104,7 @@
         '<li class="bar" style="background-color: red; border-left: 10px;">'
         '<li class="baz" style="background-color: black;>'
         '<li class="baz classy" style="background-color: blue; ">'
-        '</ul>');
+        '</ul>', treeSanitizer: new NullTreeSanitizer());
     document.documentElement.children.add(listElement);
 
     var elements = document.queryAll('li');
@@ -121,7 +122,7 @@
         '<li class="bar" style="background-color: red; border-left: 10px;">'
         '<li class="baz" style="background-color: black;>'
         '<li class="baz" id="wat" style="background-color: blue; ">'
-        '</ul>');
+        '</ul>', treeSanitizer: new NullTreeSanitizer());
     document.documentElement.children.add(listElement);
 
     var elements = document.queryAll('li');
diff --git a/tests/html/custom/attribute_changed_callback_test.dart b/tests/html/custom/attribute_changed_callback_test.dart
index 3e78587..955399f 100644
--- a/tests/html/custom/attribute_changed_callback_test.dart
+++ b/tests/html/custom/attribute_changed_callback_test.dart
@@ -13,7 +13,7 @@
 
   static var attributeChangedInvocations = 0;
 
-  void onAttributeChanged(name, oldValue, newValue) {
+  void attributeChanged(name, oldValue, newValue) {
     attributeChangedInvocations++;
   }
 }
@@ -24,11 +24,11 @@
 
   static var invocations = [];
 
-  void onCreated() {
+  void created() {
     invocations.add('created');
   }
 
-  void onAttributeChanged(name, oldValue, newValue) {
+  void attributeChanged(name, oldValue, newValue) {
     invocations.add('$name: $oldValue => $newValue');
   }
 }
diff --git a/tests/html/custom/constructor_calls_created_synchronously_test.dart b/tests/html/custom/constructor_calls_created_synchronously_test.dart
index ae11d86..77b5446 100644
--- a/tests/html/custom/constructor_calls_created_synchronously_test.dart
+++ b/tests/html/custom/constructor_calls_created_synchronously_test.dart
@@ -13,7 +13,7 @@
 
   static int ncallbacks = 0;
 
-  void onCreated() {
+  void created() {
     ncallbacks++;
   }
 }
diff --git a/tests/html/custom/created_callback_test.dart b/tests/html/custom/created_callback_test.dart
index 2f3cd51..1265b51 100644
--- a/tests/html/custom/created_callback_test.dart
+++ b/tests/html/custom/created_callback_test.dart
@@ -6,6 +6,7 @@
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
 import 'dart:html';
+import '../utils.dart';
 
 class A extends HtmlElement {
   static final tag = 'x-a';
@@ -13,7 +14,7 @@
 
   static int createdInvocations = 0;
 
-  void onCreated() {
+  void created() {
     createdInvocations++;
   }
 }
@@ -30,7 +31,7 @@
   static int createdInvocations = 0;
   static var div;
 
-  void onCreated() {
+  void created() {
     createdInvocations++;
 
     if (this.id != 'u') {
@@ -71,12 +72,12 @@
 
     var div = new DivElement();
     C.div = div;
-    div.innerHtml = """
+    div.setInnerHtml("""
 <x-c id="t"></x-c>
 <x-b id="u"></x-b>
 <x-c id="v"></x-c>
 <x-b id="w"></x-b>
-""";
+""", treeSanitizer: new NullTreeSanitizer());
 
     expect(C.createdInvocations, 2);
     expect(div.query('#w') is B, isTrue);
diff --git a/tests/html/custom/document_register_basic_test.dart b/tests/html/custom/document_register_basic_test.dart
index 718358a..eb91447 100644
--- a/tests/html/custom/document_register_basic_test.dart
+++ b/tests/html/custom/document_register_basic_test.dart
@@ -6,6 +6,7 @@
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
 import 'dart:html';
+import '../utils.dart';
 
 class Foo extends HtmlElement {
   static final tag = 'x-foo';
@@ -83,7 +84,8 @@
     // Parser initiated instantiation
     var container = new DivElement()..id = "container";
     document.body.append(container);
-    container.innerHtml = "<x-foo></x-foo>";
+    container.setInnerHtml("<x-foo></x-foo>",
+        treeSanitizer: new NullTreeSanitizer());
     var parsedFoo = container.firstChild;
 
     expect(parsedFoo is Foo, isTrue);
@@ -117,7 +119,8 @@
     expect(createdMixedBar is Bar, isTrue);
     expect(createdMixedBar.tagName, "X-BAR");
 
-    container.innerHtml = "<X-BAR></X-BAR><X-Bar></X-Bar>";
+    container.setInnerHtml("<X-BAR></X-BAR><X-Bar></X-Bar>",
+        treeSanitizer: new NullTreeSanitizer());
     expect(container.firstChild is Bar, isTrue);
     expect(container.firstChild.tagName, "X-BAR");
     expect(container.lastChild is Bar, isTrue);
diff --git a/tests/html/custom/document_register_type_extensions_test.dart b/tests/html/custom/document_register_type_extensions_test.dart
index cacb251..ec4bd17 100644
--- a/tests/html/custom/document_register_type_extensions_test.dart
+++ b/tests/html/custom/document_register_type_extensions_test.dart
@@ -6,6 +6,7 @@
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
 import 'dart:html';
+import '../utils.dart';
 
 class Foo extends HtmlElement {
   static final tag = 'x-foo';
@@ -170,8 +171,9 @@
     // Parser
 
     createElementFromHtml(html) {
-	var container = new DivElement()..innerHtml = html;
-	return container.firstChild;
+      var container = new DivElement()..setInnerHtml(html,
+        treeSanitizer: new NullTreeSanitizer());
+      return container.firstChild;
     }
 
     var fooParsed = createElementFromHtml('<x-foo>');
diff --git a/tests/html/custom_elements_test.dart b/tests/html/custom_elements_test.dart
index 8f627e7..3ad83a1 100644
--- a/tests/html/custom_elements_test.dart
+++ b/tests/html/custom_elements_test.dart
@@ -7,6 +7,7 @@
 import 'dart:html';
 import 'package:unittest/html_individual_config.dart';
 import 'package:unittest/unittest.dart';
+import 'utils.dart';
 
 class CustomMixin {
   var mixinMethodCalled;
@@ -18,9 +19,9 @@
 
 class CustomType extends HtmlElement with CustomMixin{
   factory CustomType() => null;
-  bool onCreatedCalled; // = false;
-  void onCreated() {
-    onCreatedCalled = true;
+  bool createdCalled; // = false;
+  void created() {
+    createdCalled = true;
     customCreatedCount++;
   }
 
@@ -61,7 +62,7 @@
       var element = new Element.tag(tag);
       expect(element, isNotNull);
       expect(element is CustomType, isTrue);
-      expect(element.onCreatedCalled, isTrue);
+      expect(element.createdCalled, isTrue);
     });
 
     test('register twice', () {
@@ -121,7 +122,7 @@
       var postElement = dom.children[0];
       expect(postElement, isNotNull);
       expect(postElement is CustomType, isTrue);
-      expect(postElement.onCreatedCalled, isTrue);
+      expect(postElement.createdCalled, isTrue);
 
       // Element from first query remains an UnknownElement.
       expect(preElement is HtmlElement, isTrue);
@@ -144,20 +145,24 @@
       var tag = nextTag;
       document.register(tag, CustomType);
       var element = new DivElement();
-      element.innerHtml = '<$tag></$tag>';
+      element.setInnerHtml('<$tag></$tag>',
+          treeSanitizer: new NullTreeSanitizer());
+	  Platform.upgradeCustomElements(element);
       document.body.nodes.add(element);
       var queried = query(tag);
 
       expect(queried, isNotNull);
       expect(queried is CustomType, isTrue);
-      expect(queried.onCreatedCalled, isTrue);
+      expect(queried.createdCalled, isTrue);
     });
 
     test('query id', () {
       var tag = nextTag;
       document.register(tag, CustomType);
       var element = new DivElement();
-      element.innerHtml = '<$tag id="someid"></$tag>';
+      element.setInnerHtml('<$tag id="someid"></$tag>',
+          treeSanitizer: new NullTreeSanitizer());
+	  Platform.upgradeCustomElements(element);
       document.body.nodes.add(element);
       var queried = query('#someid');
 
@@ -168,12 +173,14 @@
   });
 
   group('lifecycle', () {
-    test('onCreated', () {
+    test('created', () {
       int oldCount = customCreatedCount;
       var tag = nextTag;
       document.register(tag, CustomType);
       var element = new DivElement();
-      element.innerHtml = '<$tag></$tag>';
+      element.setInnerHtml('<$tag></$tag>',
+          treeSanitizer: new NullTreeSanitizer());
+      Platform.upgradeCustomElements(element);
       document.body.nodes.add(element);
       expect(customCreatedCount, oldCount + 1);
     });
diff --git a/tests/html/custom_tags_test.dart b/tests/html/custom_tags_test.dart
index 7ac344c..6295af5 100644
--- a/tests/html/custom_tags_test.dart
+++ b/tests/html/custom_tags_test.dart
@@ -6,6 +6,7 @@
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_config.dart';
 import 'dart:html';
+import 'utils.dart';
 
 main() {
   useHtmlConfiguration();
@@ -24,7 +25,8 @@
 
   test('custom inner html', () {
     var element = new DivElement();
-    element.innerHtml = "<x-basic2 id='basic2'></x-basic2>";
+    element.setInnerHtml("<x-basic2 id='basic2'></x-basic2>",
+        treeSanitizer: new NullTreeSanitizer());
     document.body.nodes.add(element);
 
     var queryById = query('#basic2');
@@ -37,7 +39,8 @@
 
   test('type extension inner html', () {
     var element = new DivElement();
-    element.innerHtml = "<div is='x-basic3' id='basic3'></div>";
+    element.setInnerHtml("<div is='x-basic3' id='basic3'></div>",
+        treeSanitizer: new NullTreeSanitizer());
     document.body.nodes.add(element);
 
     var queryById = query('#basic3');
diff --git a/tests/html/datalistelement_test.dart b/tests/html/datalistelement_test.dart
index b69bbdb..8af53c1 100644
--- a/tests/html/datalistelement_test.dart
+++ b/tests/html/datalistelement_test.dart
@@ -54,8 +54,7 @@
 
   test('options', () {
     expect(() {
-      var options = document.query('#browsers')
-          .queryAll('option');  // Uses DataListElement.
+      var options = document.query('#browsers').options;
       expect(options.length, 5);
     }, expectation);
   });
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index 71dd4ea..199262f 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -8,6 +8,7 @@
 import 'dart:async';
 import 'dart:html';
 import 'dart:svg' as svg;
+import 'utils.dart';
 
 expectLargeRect(Rect rect) {
   expect(rect.top, 0);
@@ -83,7 +84,7 @@
 
   group('constructors', () {
     test('error', () {
-      expect(() => new Element.html('<br/><br/>'), throwsArgumentError);
+      expect(() => new Element.html('<br/><br/>'), throwsStateError);
     });
 
     test('.html has no parent', () =>
@@ -123,7 +124,8 @@
     });
 
     test('.html caption', () {
-      var node = new Element.html('<caption><p>Table 1.');
+      var table = new TableElement();
+      var node = table.createFragment('<caption><p>Table 1.').nodes.single;
       expect(node, predicate((x) => x is TableCaptionElement,
           'is a TableCaptionElement'));
       expect(node.tagName, 'CAPTION');
@@ -132,7 +134,9 @@
     });
 
     test('.html colgroup', () {
-      var node = new Element.html('<colgroup> <col> <col> <col>');
+      var table = new TableElement();
+      var node =
+          table.createFragment('<colgroup> <col> <col> <col>').nodes.single;
       expect(node, predicate((x) => x is TableColElement,
           'is a TableColElement'));
       expect(node.tagName, 'COLGROUP');
@@ -140,18 +144,10 @@
       expect(node.innerHtml, ' <col> <col> <col>');
     });
 
-    test('.html col', () {
-      var node = new Element.html('<col span="2">');
-      expect(node, predicate((x) => x is TableColElement,
-          'is a TableColElement'));
-      expect(node.tagName, 'COL');
-      expect(node.parent, isNull);
-      expect(node.outerHtml, '<col span="2">');
-    });
-
     test('.html tbody', () {
       var innerHtml = '<tr><td headers="n r1">Sad</td><td>Happy</td></tr>';
-      var node = new Element.html('<tbody>$innerHtml');
+      var table = new TableElement();
+      var node = table.createFragment('<tbody>$innerHtml').nodes.single;
       expect(node, predicate((x) => x is TableSectionElement,
           'is a TableSectionElement'));
       expect(node.tagName, 'TBODY');
@@ -163,7 +159,8 @@
 
     test('.html thead', () {
       var innerHtml = '<tr><th id="n">Negative</th><th>Positive</th></tr>';
-      var node = new Element.html('<thead>$innerHtml');
+      var table = new TableElement();
+      var node = table.createFragment('<thead>$innerHtml').nodes.single;
       expect(node, predicate((x) => x is TableSectionElement,
           'is a TableSectionElement'));
       expect(node.tagName, 'THEAD');
@@ -175,7 +172,8 @@
 
     test('.html tfoot', () {
       var innerHtml = '<tr><th>percentage</th><td>34.3%</td></tr>';
-      var node = new Element.html('<tfoot>$innerHtml');
+      var table = new TableElement();
+      var node = table.createFragment('<tfoot>$innerHtml').nodes.single;
       expect(node, predicate((x) => x is TableSectionElement,
           'is a TableSectionElement'));
       expect(node.tagName, 'TFOOT');
@@ -186,7 +184,9 @@
     });
 
     test('.html tr', () {
-      var node = new Element.html('<tr><td>foo<td>bar');
+      var table = new TableElement();
+      var tBody = table.createTBody();
+      var node = tBody.createFragment('<tr><td>foo<td>bar').nodes.single;
       expect(node, predicate((x) => x is TableRowElement,
           'is a TableRowElement'));
       expect(node.tagName, 'TR');
@@ -195,7 +195,10 @@
     });
 
     test('.html td', () {
-      var node = new Element.html('<td>foobar');
+      var table = new TableElement();
+      var tBody = table.createTBody();
+      var tRow = tBody.addRow();
+      var node = tRow.createFragment('<td>foobar').nodes.single;
       expect(node, predicate((x) => x is TableCellElement,
           'is a TableCellElement'));
       expect(node.tagName, 'TD');
@@ -204,7 +207,10 @@
     });
 
     test('.html th', () {
-      var node = new Element.html('<th>foobar');
+      var table = new TableElement();
+      var tBody = table.createTBody();
+      var tRow = tBody.addRow();
+      var node = tRow.createFragment('<th>foobar').nodes.single;
       expect(node, predicate((x) => x is TableCellElement,
           'is a TableCellElement'));
       expect(node.tagName, 'TH');
@@ -304,7 +310,7 @@
         final element = new Element.html(
             '''<div class="foo" style="overflow: hidden" data-foo="bar"
                    data-foo2="bar2" dir="rtl">
-               </div>''');
+               </div>''', treeSanitizer: new NullTreeSanitizer());
         final attributes = element.attributes;
         expect(attributes['class'], 'foo');
         expect(attributes['style'], startsWith('overflow: hidden'));
@@ -820,4 +826,75 @@
       expect(firedEvent5, true);
     });
   });
+
+  group('ElementList', () {
+    // Tests for methods on the DOM class 'NodeList'.
+    //
+    // There are two interesting things that are checked here from the viewpoint
+    // of the dart2js implementation of a 'native' class:
+    //
+    //   1. Some methods are implementated from by 'Object' or 'Interceptor';
+    //      some of these tests simply check that a method can be called.
+    //   2. Some methods are implemented by mixins.
+
+    ElementList makeElementList() =>
+        (new Element.html("<div>Foo<br/><!--baz--><br/><br/></div>"))
+        .queryAll('br');
+
+    test('hashCode', () {
+      var nodes = makeElementList();
+      var hash = nodes.hashCode;
+      final int N = 1000;
+      int matchCount = 0;
+      for (int i = 0; i < N; i++) {
+        if (makeElementList().hashCode == hash) matchCount++;
+      }
+      expect(matchCount, lessThan(N));
+    });
+
+    test('operator==', () {
+      var a = [makeElementList(), makeElementList(), null];
+      for (int i = 0; i < a.length; i++) {
+        for (int j = 0; j < a.length; j++) {
+          expect(i == j,  a[i] == a[j]);
+        }
+      }
+    });
+
+    test('runtimeType', () {
+      var nodes1 = makeElementList();
+      var nodes2 = makeElementList();
+      var type1 = nodes1.runtimeType;
+      var type2 = nodes2.runtimeType;
+      expect(type1 == type2, true);
+      String name = '$type1';
+      if (name.length > 3) {
+        expect(name.contains('ElementList'), true);
+      }
+    });
+
+    test('first', () {
+      var nodes = makeElementList();
+      expect(nodes.first, isBRElement);
+    });
+
+    test('last', () {
+      var nodes = makeElementList();
+      expect(nodes.last, isBRElement);
+    });
+
+    test('where', () {
+      var filtered = makeElementList().where((n) => n is BRElement).toList();
+      expect(filtered.length, 3);
+      expect(filtered[0], isBRElement);
+    });
+
+    test('sublist', () {
+      var range = makeElementList().sublist(1, 3);
+      expect(range.length, 2);
+      expect(range[0], isBRElement);
+      expect(range[1], isBRElement);
+    });
+
+  });
 }
diff --git a/tests/html/html.status b/tests/html/html.status
index b3c80c6..98b47fb 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -20,7 +20,6 @@
 # postMessage in dartium always transfers the typed array buffer, never a view
 postmessage_structured_test/typed_arrays: Fail
 xhr_test: Pass, Fail # Issue 12648
-custom_elements_test/lifecycle: Fail # Issue 12642
 custom/attribute_changed_callback_test: Fail # 12643
 custom/created_callback_test: Fail # Issue 12642
 
@@ -40,6 +39,7 @@
 
 [ $compiler == dart2js && $runtime == safari ]
 url_test: Fail # Issue 10096
+audiobuffersourcenode_test/supported: Pass, Timeout # Issue 12772
 
 [ $compiler == dart2js && $browser && $checked ]
 postmessage_structured_test/typed_arrays: Fail # Issue 10097
@@ -145,6 +145,7 @@
 dom_constructors_test: Fail
 dromaeo_smoke_test: Skip #TODO(efortuna): investigating.
 element_test/click: Fail                # IE does not support firing this event.
+element_test/constructors: Fail         # IE9 does not support innerHTML on table elements
 element_test/matches: Fail # IE9 does not support matches
 form_element_test: Fail # Issue 4793.
 isolates_test: Skip         # BUG(4016)
@@ -223,9 +224,7 @@
 svgelement_test/supported_feMerge: Fail
 svgelement_test/supported_feMergeNode: Fail
 svgelement_test/supported_feOffset: Fail
-svgelement_test/supported_fePointLight: Fail
 svgelement_test/supported_feSpecularLighting: Fail
-svgelement_test/supported_feSpotLight: Fail
 svgelement_test/supported_feTile: Fail
 svgelement_test/supported_feTurbulence: Fail
 svgelement_test/supported_filter: Fail
@@ -246,14 +245,12 @@
 xsltprocessor_test/supported: Fail
 
 [ $runtime == safari ]
-datalistelement_test: Fail # Issue: 7414
-element_test/elements: Crash, Fail # Issue: 7414
 element_types_test/supported_track: Pass, Fail
 input_element_test/supported_month: Fail, Crash
 input_element_test/supported_time: Fail, Crash
 input_element_test/supported_week: Fail, Crash
 webgl_1_test: Pass, Fail # Issue 8219
-wheelevent_test: Fail # Issue: 7414
+wheelevent_test: Fail # Issue: 12798
 xhr_test/xhr_requestBlob: Fail # Issue: 9178 Safari doesn't support Blob responses.
 canvasrenderingcontext2d_test/drawImage_video_element: Fail # Safari does not support drawImage w/ video element
 canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Fail # Safari does not support drawImage w/ video element
@@ -358,11 +355,8 @@
 websql_test/supported: Fail
 xhr_test/supported_HttpRequestProgressEvent: Fail
 
-[ $runtime == ff && $system == windows ]
-rtc_test/supported: Fail # Release build does not enable by default.
-element_types_test/supported_template: Fail
 
-[ $runtime == ff && $system == linux ]
+[ $runtime == ff && ($system == linux || $system == windows) ]
 rtc_test/functionality: Fail # Issue: 12109.
 
 # 'html' tests import the HTML library, so they only make sense in
diff --git a/tests/html/node_test.dart b/tests/html/node_test.dart
index 1070554..d142c60 100644
--- a/tests/html/node_test.dart
+++ b/tests/html/node_test.dart
@@ -335,92 +335,6 @@
     });
   });
 
-  group('NodeList', () {
-    // Tests for methods on the DOM class 'NodeList'.
-    //
-    // There are two interesting things that are checked here from the viewpoint
-    // of the dart2js implementation of a 'native' class:
-    //
-    //   1. Some methods are implementated from by 'Object' or 'Interceptor';
-    //      some of these tests simply check that a method can be called.
-    //   2. Some methods are implemented by mixins.
-
-    List<Node> makeNodeList() =>
-        (new Element.html("<div>Foo<br/><!--baz--><br/><br/></div>"))
-        .$dom_getElementsByTagName('br');
-    // Our WebKit-derived bindings declare getElementsByTagName as returning
-    // NodeList.
-    //
-    // WebKit browsers returns NodeList.
-    // Firefox and IE return HtmlCollection.
-    // This is messed-up since the two types are disjoint.  We could make
-    // HtmlCollection extend NodeList but we would require better optimizations
-    // to recognize when NodeList_methods can be used.
-
-    test('trueNodeList', () {
-      var nodes = makeNodeList();
-      expect(nodes is NodeList || nodes is HtmlCollection, true);
-    });
-
-    test('hashCode', () {
-      var nodes = makeNodeList();
-      var hash = nodes.hashCode;
-      final int N = 1000;
-      int matchCount = 0;
-      for (int i = 0; i < N; i++) {
-        if (makeNodeList().hashCode == hash) matchCount++;
-      }
-      expect(matchCount, lessThan(N));
-    });
-
-    test('operator==', () {
-      var a = [makeNodeList(), makeNodeList(), null];
-      for (int i = 0; i < a.length; i++) {
-        for (int j = 0; j < a.length; j++) {
-          expect(i == j,  a[i] == a[j]);
-        }
-      }
-    });
-
-    test('runtimeType', () {
-      var nodes1 = makeNodeList();
-      var nodes2 = makeNodeList();
-      var type1 = nodes1.runtimeType;
-      var type2 = nodes2.runtimeType;
-      expect(type1 == type2, true);
-      String name = '$type1';
-      if (name.length > 3) {
-        expect(name.contains('NodeList') || name.contains('HtmlCollection'),
-               true);
-      }
-    });
-
-    test('first', () {
-      var nodes = makeNodeList();
-      expect(nodes.first, isBRElement);
-    });
-
-    test('last', () {
-      var nodes = makeNodeList();
-      expect(nodes.last, isBRElement);
-    });
-
-    test('where', () {
-      var filtered = makeNodeList().where((n) => n is BRElement).toList();
-      expect(filtered.length, 3);
-      expect(filtered[0], isBRElement);
-      expect(filtered, isNodeList);
-    });
-
-    test('sublist', () {
-      var range = makeNodeList().sublist(1, 3);
-      expect(range.length, 2);
-      expect(range[0], isBRElement);
-      expect(range[1], isBRElement);
-    });
-
-  });
-
   group('iterating', () {
     test('NodeIterator', () {
       var root = makeNodeWithChildren();
diff --git a/tests/html/node_validator_test.dart b/tests/html/node_validator_test.dart
new file mode 100644
index 0000000..7f76762
--- /dev/null
+++ b/tests/html/node_validator_test.dart
@@ -0,0 +1,424 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library validator_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:svg' as svg;
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'utils.dart';
+
+
+var nullSanitizer = new NullTreeSanitizer();
+
+void validateHtml(String html, String reference, NodeValidator validator) {
+  var a = document.body.createFragment(html, validator: validator);
+  var b = document.body.createFragment(reference,
+      treeSanitizer: nullSanitizer);
+
+  validateNodeTree(a, b);
+}
+
+class RecordingUriValidator implements UriPolicy {
+  final List<String> calls = <String>[];
+
+  bool allowsUri(String uri) {
+    calls.add('$uri');
+    return false;
+  }
+
+  void reset() {
+    calls.clear();
+  }
+}
+
+void testHtml(String name, NodeValidator validator, String html,
+  [String reference]) {
+  test(name, () {
+    if (reference == null) {
+      reference = html;
+    }
+
+    validateHtml(html, reference, validator);
+  });
+}
+
+main() {
+  useHtmlConfiguration();
+
+  group('DOM sanitization', () {
+    var validator = new NodeValidatorBuilder.common();
+
+    testHtml('allows simple constructs',
+        validator,
+        '<div class="baz">something</div>');
+
+    testHtml('blocks unknown attributes',
+        validator,
+        '<div foo="baz">something</div>',
+        '<div>something</div>');
+
+    testHtml('blocks custom element',
+        validator,
+        '<x-my-element>something</x-my-element>',
+        '');
+
+    testHtml('blocks custom is element',
+        validator,
+        '<div is="x-my-element">something</div>',
+        '');
+
+    testHtml('blocks body elements',
+        validator,
+        '<body background="s"></body>',
+        '');
+
+    testHtml('allows select elements',
+        validator,
+        '<select>'
+          '<option>a</option>'
+        '</select>');
+
+    testHtml('blocks sequential script elements',
+        validator,
+        '<div><script></script><script></script></div>',
+        '<div></div>');
+
+    testHtml('blocks namespaced attributes',
+        validator,
+        '<div ns:foo="foo"></div>',
+        '<div></div>');
+
+    testHtml('blocks namespaced common attributes',
+        validator,
+        '<div ns:class="foo"></div>',
+        '<div></div>');
+
+    testHtml('blocks namespaced common elements',
+        validator,
+        '<ns:div></ns:div>',
+        '');
+
+    testHtml('allows CDATA sections',
+        validator,
+        '<span>![CDATA[ some text ]]></span>');
+
+    test('sanitizes template contents', () {
+      var html = '<template>'
+          '<div></div>'
+          '<script></script>'
+          '<img src="http://example.com/foo"/>'
+        '</template>';
+
+      var fragment = document.body.createFragment(html, validator: validator);
+      var template = fragment.nodes.single;
+
+      var expectedContent = document.body.createFragment(
+          '<div></div>'
+          '<img/>');
+
+      validateNodeTree(template.content, expectedContent);
+    });
+  });
+
+  group('URI sanitization', () {
+    var recorder = new RecordingUriValidator();
+    var validator = new NodeValidatorBuilder()..allowHtml5(uriPolicy: recorder);
+
+    checkUriPolicyCalls(String name, String html, String reference,
+        List<String> expectedCalls) {
+
+      test(name, () {
+        recorder.reset();
+
+        validateHtml(html, reference, validator);
+        expect(recorder.calls, expectedCalls);
+      });
+    }
+
+    checkUriPolicyCalls('a::href',
+        '<a href="s"></a>',
+        '<a></a>',
+        ['s']);
+
+    checkUriPolicyCalls('area::href',
+        '<area href="s"></area>',
+        '<area></area>',
+        ['s']);
+
+    checkUriPolicyCalls('blockquote::cite',
+        '<blockquote cite="s"></blockquote>',
+        '<blockquote></blockquote>',
+        ['s']);
+    checkUriPolicyCalls('command::icon',
+        '<command icon="s"/>',
+        '<command/>',
+        ['s']);
+    checkUriPolicyCalls('img::src',
+        '<img src="s"/>',
+        '<img/>',
+        ['s']);
+    checkUriPolicyCalls('input::src',
+        '<input src="s"/>',
+        '<input/>',
+        ['s']);
+    checkUriPolicyCalls('ins::cite',
+        '<ins cite="s"></ins>',
+        '<ins></ins>',
+        ['s']);
+    checkUriPolicyCalls('q::cite',
+        '<q cite="s"></q>',
+        '<q></q>',
+        ['s']);
+    checkUriPolicyCalls('video::poster',
+        '<video poster="s"/>',
+        '<video/>',
+        ['s']);
+  });
+
+  group('NodeValidationPolicy', () {
+
+    group('allowNavigation', () {
+      var validator = new NodeValidatorBuilder()..allowNavigation();
+
+      testHtml('allows anchor tags',
+          validator,
+          '<a href="#foo">foo</a>');
+
+      testHtml('allows form elements',
+          validator,
+          '<form method="post" action="/foo"></form>');
+
+      testHtml('disallows script navigation',
+          validator,
+          '<a href="javascript:foo = 1">foo</a>',
+          '<a>foo</a>');
+
+      testHtml('disallows cross-site navigation',
+          validator,
+          '<a href="http://example.com">example.com</a>',
+          '<a>example.com</a>');
+
+      testHtml('blocks other elements',
+          validator,
+          '<a href="#foo"><b>foo</b></a>',
+          '<a href="#foo"></a>');
+
+      testHtml('blocks tag extension',
+          validator,
+          '<a is="x-foo"></a>',
+          '');
+    });
+
+    group('allowImages', () {
+      var validator = new NodeValidatorBuilder()..allowImages();
+
+      testHtml('allows images',
+          validator,
+          '<img src="/foo.jpg" alt="something" width="100" height="100"/>');
+
+      testHtml('blocks onerror',
+          validator,
+          '<img src="/foo.jpg" onerror="something"/>',
+          '<img src="/foo.jpg"/>');
+
+      testHtml('enforces same-origin',
+          validator,
+          '<img src="http://example.com/foo.jpg"/>',
+          '<img/>');
+    });
+
+    group('allowCustomElement', () {
+      var validator = new NodeValidatorBuilder()
+        ..allowCustomElement(
+            'x-foo',
+            attributes: ['bar'],
+            uriAttributes: ['baz'])
+        ..allowHtml5();
+
+      testHtml('allows custom elements',
+          validator,
+          '<x-foo bar="something" baz="/foo.jpg"></x-foo>');
+
+
+      testHtml('validates custom tag URIs',
+          validator,
+          '<x-foo baz="http://example.com/foo.jpg"></x-foo>',
+          '<x-foo></x-foo>');
+
+      testHtml('blocks type extensions',
+          validator,
+          '<div is="x-foo"></div>',
+          '');
+
+      testHtml('blocks tags on non-matching elements',
+          validator,
+          '<div bar="foo"></div>',
+          '<div></div>');
+    });
+
+    group('allowTagExtension', () {
+       var validator = new NodeValidatorBuilder()
+        ..allowTagExtension(
+            'x-foo',
+            'div',
+            attributes: ['bar'],
+            uriAttributes: ['baz'])
+        ..allowHtml5();
+
+      testHtml('allows tag extensions',
+          validator,
+          '<div is="x-foo" bar="something" baz="/foo.jpg"></div>');
+
+      testHtml('blocks custom elements',
+            validator,
+            '<x-foo></x-foo>',
+            '');
+
+      testHtml('validates tag extension URIs',
+          validator,
+          '<div is="x-foo" baz="http://example.com/foo.jpg"></div>',
+          '<div is="x-foo"></div>');
+
+      testHtml('blocks tags on non-matching elements',
+          validator,
+          '<div bar="foo"></div>',
+          '<div></div>');
+
+      testHtml('blocks non-matching tags',
+          validator,
+          '<span is="x-foo">something</span>',
+          '');
+
+      validator = new NodeValidatorBuilder()
+        ..allowTagExtension(
+            'x-foo',
+            'div',
+            attributes: ['bar'],
+            uriAttributes: ['baz'])
+        ..allowTagExtension(
+            'x-else',
+            'div');
+
+      testHtml('blocks tags on non-matching custom elements',
+          validator,
+          '<div bar="foo" is="x-else"></div>',
+          '<div is="x-else"></div>');
+    });
+
+    group('allowTemplating', () {
+      var validator = new NodeValidatorBuilder()
+        ..allowTemplating()
+        ..allowHtml5();
+
+      testHtml('allows templates',
+          validator,
+          '<template bind="{{a}}"></template>');
+
+      testHtml('allows template attributes',
+          validator,
+          '<template bind="{{a}}" ref="foo" repeat="{{}}" if="{{}}" syntax="foo"></template>');
+
+      testHtml('allows template attribute',
+          validator,
+          '<div template repeat="{{}}"></div>');
+
+      testHtml('blocks illegal template attribute',
+          validator,
+          '<div template="foo" repeat="{{}}"></div>',
+          '<div></div>');
+    });
+
+    group('allowSvg', () {
+      var validator = new NodeValidatorBuilder()..allowSvg();
+
+      testHtml('allows basic SVG',
+        validator,
+        '<svg xmlns="http://www.w3.org/2000/svg'
+            'xmlns:xlink="http://www.w3.org/1999/xlink">'
+          '<image xlink:href="foo" data-foo="bar"/>'
+        '</svg>');
+
+      testHtml('blocks script elements',
+        validator,
+        '<svg xmlns="http://www.w3.org/2000/svg>'
+          '<script></script>'
+        '</svg>',
+        '<svg xmlns="http://www.w3.org/2000/svg></svg>');
+
+      testHtml('blocks script handlers',
+        validator,
+        '<svg xmlns="http://www.w3.org/2000/svg'
+            'xmlns:xlink="http://www.w3.org/1999/xlink">'
+          '<image xlink:href="foo" onerror="something"/>'
+        '</svg>',
+        '<svg xmlns="http://www.w3.org/2000/svg'
+            'xmlns:xlink="http://www.w3.org/1999/xlink">'
+          '<image xlink:href="foo"/>'
+        '</svg>');
+
+      testHtml('blocks foreignObject content',
+        validator,
+        '<svg xmlns="http://www.w3.org/2000/svg>'
+          '<foreignobject width="100" height="150">'
+            '<body xmlns="http://www.w3.org/1999/xhtml">'
+              '<div>Some content</div>'
+            '</body>'
+          '</foreignobject>'
+        '</svg>',
+        '<svg xmlns="http://www.w3.org/2000/svg>'
+          '<foreignobject width="100" height="150"></foreignobject>'
+        '</svg>');
+    });
+  });
+
+  group('throws', () {
+    var validator = new NodeValidator.throws(new NodeValidatorBuilder.common());
+
+    var validationError = throwsArgumentError;
+
+    test('does not throw on valid syntax', () {
+      expect(() {
+        document.body.createFragment('<div></div>', validator: validator);
+      }, returnsNormally);
+    });
+
+    test('throws on invalid elements', () {
+      expect(() {
+        document.body.createFragment('<foo></foo>', validator: validator);
+      }, validationError);
+    });
+
+    test('throws on invalid attributes', () {
+      expect(() {
+        document.body.createFragment('<div foo="bar"></div>',
+            validator: validator);
+      }, validationError);
+    });
+
+    test('throws on invalid attribute values', () {
+      expect(() {
+        document.body.createFragment('<img src="http://example.com/foo.jpg"/>',
+            validator: validator);
+      }, validationError);
+    });
+  });
+
+  group('svg', () {
+    test('parsing', () {
+      var svgText =
+        '<svg xmlns="http://www.w3.org/2000/svg'
+            'xmlns:xlink="http://www.w3.org/1999/xlink">'
+          '<image xlink:href="foo" data-foo="bar"/>'
+        '</svg>';
+
+      var fragment = new DocumentFragment.svg(svgText);
+      var element = fragment.nodes.first;
+      expect(element is svg.SvgSvgElement, isTrue);
+      expect(element.children[0] is svg.ImageElement, isTrue);
+    });
+  });
+}
diff --git a/tests/html/safe_dom_test.dart b/tests/html/safe_dom_test.dart
index 686c4e0..15f781c 100644
--- a/tests/html/safe_dom_test.dart
+++ b/tests/html/safe_dom_test.dart
@@ -39,7 +39,7 @@
   // Make sure that scripts did get executed, so we know our detection works.
   test('Unsafe Execution', () {
     var div = new DivElement();
-    div.innerHtml = unsafeString;
+    div.unsafeInnerHtml = unsafeString;
     // Crashing DRT ??
     // var fragment = createContextualFragment(unsafeString);
     // div.append(fragment);
@@ -74,7 +74,7 @@
     range.selectNode(contextElement);
     return range.createContextualFragment(html);
   } else {
-    contextElement.innerHtml = html;
+    contextElement.unsafeInnerHtml = html;
     var fragment = new DocumentFragment();;
     while (contextElement.firstChild != null) {
       fragment.append(contextElement.firstChild);
diff --git a/tests/html/svg_test.dart b/tests/html/svg_test.dart
index db31807..b24084a 100644
--- a/tests/html/svg_test.dart
+++ b/tests/html/svg_test.dart
@@ -3,10 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library SVGTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
 import 'dart:svg' as svg;
+import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
 
 main() {
   useHtmlIndividualConfiguration();
@@ -17,12 +17,11 @@
     test('simpleRect', () {
       var div = new Element.tag('div');
       document.body.append(div);
-      div.innerHtml = r'''
+      div.setInnerHtml(r'''
 <svg id='svg1' width='200' height='100'>
 <rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
 </svg>
-
-''';
+''', validator: new NodeValidatorBuilder()..allowSvg());
 
       var e = document.query('#svg1');
       expect(e, isNotNull);
@@ -53,11 +52,11 @@
     // only, see SVGTest3 for behavioural tests).
     insertTestDiv() {
       var element = new Element.tag('div');
-      element.innerHtml = r'''
+      element.setInnerHtml(r'''
 <svg id='svg1' width='200' height='100'>
 <rect id='rect1' x='10' y='20' width='130' height='40' rx='5'fill='blue'></rect>
 </svg>
-''';
+''', validator: new NodeValidatorBuilder()..allowSvg());
       document.body.append(element);
       return element;
     }
diff --git a/tests/html/svgelement_test.dart b/tests/html/svgelement_test.dart
index f94baae..1dad882 100644
--- a/tests/html/svgelement_test.dart
+++ b/tests/html/svgelement_test.dart
@@ -3,11 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library SvgElementTest;
-import "package:expect/expect.dart";
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
 import 'dart:svg' as svg;
+import 'package:expect/expect.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
 
 main() {
   useHtmlIndividualConfiguration();
@@ -58,12 +58,12 @@
     );
 
     test('empty', () {
-      expect(() => new svg.SvgElement.svg(""), throwsArgumentError);
+      expect(() => new svg.SvgElement.svg(""), throwsStateError);
     });
 
     test('too many elements', () {
       expect(() => new svg.SvgElement.svg("<circle></circle><path></path>"),
-          throwsArgumentError);
+          throwsStateError);
     });
   });
 
@@ -262,7 +262,9 @@
       testConstructor('polyline', (e) => e is svg.PolylineElement);
       testConstructor('radialGradient', (e) => e is svg.RadialGradientElement);
       testConstructor('rect', (e) => e is svg.RectElement);
-      testConstructor('script', (e) => e is svg.ScriptElement);
+      test('script', () {
+        expect(new svg.SvgElement.tag('script') is svg.ScriptElement, isTrue);
+      });
       testConstructor('stop', (e) => e is svg.StopElement);
       testConstructor('style', (e) => e is svg.StyleElement);
       testConstructor('switch', (e) => e is svg.SwitchElement);
diff --git a/tests/html/utils.dart b/tests/html/utils.dart
index 38ed073..2533f24 100644
--- a/tests/html/utils.dart
+++ b/tests/html/utils.dart
@@ -3,7 +3,7 @@
 import 'dart:async';
 import 'dart:html';
 import 'dart:typed_data';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
 
 /**
  * Verifies that [actual] has the same graph structure as [expected].
@@ -123,3 +123,39 @@
 
   walk('', expected, actual);
 }
+
+
+/**
+ * Sanitizer which does nothing.
+ */
+class NullTreeSanitizer implements NodeTreeSanitizer {
+  void sanitizeTree(Node node) {}
+}
+
+
+/**
+ * Validate that two DOM trees are equivalent.
+ */
+void validateNodeTree(Node a, Node b, [String path = '']) {
+  path = '${path}${a.runtimeType}';
+  expect(a.nodeType, b.nodeType, reason: '$path nodeTypes differ');
+  expect(a.nodeValue, b.nodeValue, reason: '$path nodeValues differ');
+  expect(a.text, b.text, reason: '$path texts differ');
+  expect(a.nodes.length, b.nodes.length, reason: '$path nodes.lengths differ');
+
+  if (a is Element) {
+    Element bE = b;
+    Element aE = a;
+
+    expect(aE.tagName, bE.tagName, reason: '$path tagNames differ');
+    expect(aE.attributes.length, bE.attributes.length,
+        reason: '$path attributes.lengths differ');
+    for (var key in aE.attributes.keys) {
+      expect(aE.attributes[key], bE.attributes[key],
+          reason: '$path attribute [$key] values differ');
+    }
+  }
+  for (var i = 0; i < a.nodes.length; ++i) {
+    validateNodeTree(a.nodes[i], b.nodes[i], '$path[$i].');
+  }
+}
diff --git a/tests/html/xhr_cross_origin_test.dart b/tests/html/xhr_cross_origin_test.dart
index cb56240..a9eda40 100644
--- a/tests/html/xhr_cross_origin_test.dart
+++ b/tests/html/xhr_cross_origin_test.dart
@@ -56,6 +56,25 @@
       });
     });
 
+    test('XHR.requestCrossOrigin', () {
+      var url = '$host/root_dart/tests/html/xhr_cross_origin_data.txt';
+      return HttpRequest.requestCrossOrigin(url).then((response) {
+        expect(response, contains('feed'));
+      });
+    });
+
+    test('XHR.requestCrossOrigin errors', () {
+      var gotError = false;
+      return HttpRequest.requestCrossOrigin('does_not_exist').then((response) {
+        expect(true, isFalse, reason: '404s should fail request.');
+      }).catchError((error) {}, test: (error) {
+        gotError = true;
+        return true;
+      }).whenComplete(() {
+        expect(gotError, isTrue);
+      });
+    });
+
     // Skip the rest if not supported.
     if (!HttpRequest.supportsCrossOrigin) {
       return;
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index df59051..5798289 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -84,9 +84,6 @@
 [ $compiler == dart2dart ]
 *: Skip # Issue 12629
 
-[ $compiler == none ]
-isolate_negative_test: Skip # Bug 6890
-
 [ $compiler == dart2js && $runtime == ff && ($system == windows || $system == linux) ]
 mandel_isolate_test: Pass, Fail, Timeout # Issue 7952
 mandel_isolate_stream_test: Pass, Fail, Timeout # Issue 7952
@@ -94,11 +91,9 @@
 [ $compiler == dart2js && ( $runtime == ff || $runtime == safari || $runtime == drt || $runtime == chrome ) ]
 isolate_stress_test: Pass, Slow # Issue 10697
 
-[ $arch == arm || $arch == simarm ]
-*: Skip # Issue 12589
-
-[ $arch == mips || $arch == simmips ]
-*: Skip # Issue 12590
+[ ($arch == mips || $arch == simmips) && $mode == debug ]
+mandel_isolate_test: Crash  # Issue 12823
+mandel_isolate_stream_test: Crash  # Issue 12823
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 isolate_stress_test: Skip # Issue 12537
diff --git a/tests/language/abstract_exact_selector_test.dart b/tests/language/abstract_exact_selector_test.dart
new file mode 100644
index 0000000..fd61a10
--- /dev/null
+++ b/tests/language/abstract_exact_selector_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to duplicate some `Object`
+// methods to handle `noSuchMethod`.
+
+import "package:expect/expect.dart";
+import "compiler_annotations.dart";
+
+abstract class Foo {
+  noSuchMethod(im) => 42;
+}
+
+@DontInline()
+returnFoo() {
+  (() => 42)();
+  return new Foo();
+}
+
+class Bar {
+  operator==(other) => false;
+}
+
+var a = [false, true, new Object(), new Bar()];
+
+main() {
+  if (a[0]) {
+    // This `==` call will make the compiler create a selector with an
+    // exact `TypeMask` of `Foo`. Since `Foo` is abstract, such a call
+    // cannot happen, but we still used to generate a `==` method on
+    // the `Object` class to handle `noSuchMethod`.
+    print(returnFoo() == 42);
+  } else {
+    Expect.isFalse(a[2] == 42);
+  }
+}
diff --git a/tests/language/arithmetic_test.dart b/tests/language/arithmetic_test.dart
index effcee9..c24dcb9 100644
--- a/tests/language/arithmetic_test.dart
+++ b/tests/language/arithmetic_test.dart
@@ -291,8 +291,6 @@
     Expect.equals(2, (2.1).round());
     Expect.equals(-2, (-2.1).round());
     Expect.equals(1, (0.5).round());
-    Expect.equals(0, (0.49999999999999994).round());
-    Expect.equals(0, (-0.49999999999999994).round());
     Expect.equals(-1, (-0.5).round());
     Expect.isTrue((-0.0).round() is int);
     Expect.isTrue((-0.3).round() is int);
@@ -300,8 +298,6 @@
     Expect.equals(2, (1.5).round());
     Expect.equals(-2, (-1.5).round());
     Expect.equals(1, (0.99).round());
-    Expect.equals(9007199254740991, (9007199254740991.0).round());
-    Expect.equals(-9007199254740991, (-9007199254740991.0).round());
 
     // -- toInt --.
     // Smi.
diff --git a/tests/language/call_nonexistent_constructor_test.dart b/tests/language/call_nonexistent_constructor_test.dart
index 1e661a7..fa8efe5 100644
--- a/tests/language/call_nonexistent_constructor_test.dart
+++ b/tests/language/call_nonexistent_constructor_test.dart
@@ -19,8 +19,10 @@
   int i = 0;
   new A.foo(42);
   try {
-    new A.bar(foo());  // Arguments are not evaluated with NoSuchMethodError.
-  } on NoSuchMethodError catch (e) {  // Not 'on String catch ...'
+    new A.bar(foo());  // Args are evaluated before throwing NoSuchMethodError.
+  } on NoSuchMethodError catch (e) {
+    i = -1;
+  } on String catch (e) {
     i = 1;
   }
   Expect.equals(1, i);
diff --git a/tests/language/constructor_negative_test.dart b/tests/language/constructor_call_as_function_test.dart
similarity index 69%
rename from tests/language/constructor_negative_test.dart
rename to tests/language/constructor_call_as_function_test.dart
index 864f7a7..abfa52a 100644
--- a/tests/language/constructor_negative_test.dart
+++ b/tests/language/constructor_call_as_function_test.dart
@@ -11,13 +11,6 @@
   final int y;
 }
 
-
-class ConstructorNegativeTest {
-  static testMain() {
-    Point p = Point(1, 2);   // should be const or new before Point(1,2).
-  }
-}
-
 main() {
-  ConstructorNegativeTest.testMain();
+  Point p = Point(1, 2);  /// 01: static type warning, runtime error
 }
diff --git a/tests/language/external_test.dart b/tests/language/external_test.dart
index f1c6c36..79dc545 100644
--- a/tests/language/external_test.dart
+++ b/tests/language/external_test.dart
@@ -1,7 +1,6 @@
 // Copyright (c) 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.
-// VMOptions=--compile_all
 
 class Foo {
   var x;
@@ -29,7 +28,7 @@
 main() {
 
   // Try calling an unpatched external function.
-  var foo = new Foo();                                /// 10: continued
+  var foo = new Foo();
   try {                                               /// 10: continued
     foo.f05();                                        /// 10: continued
   } on String catch (exc) {                           /// 10: continued
diff --git a/tests/language/f_bounded_quantification5_test.dart b/tests/language/f_bounded_quantification5_test.dart
new file mode 100644
index 0000000..b45cb2d
--- /dev/null
+++ b/tests/language/f_bounded_quantification5_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test for F-Bounded Quantification.
+
+import "package:expect/expect.dart";
+
+class A<T extends B<T>> {
+}
+
+class B<T extends A<T>> {
+}
+
+isCheckedMode() {
+  try {
+    var i = 1;
+    String s = i;
+    return false;
+  } catch (e) {
+    return true;
+  }
+}
+
+main() {
+  bool got_type_error = false;
+  try {
+    Expect.equals("A<B<int>>", new A<B<int>>().runtimeType.toString());
+  } on TypeError catch (error) {
+    got_type_error = true;
+  }
+  // Type error expected in checked mode only.
+  Expect.isTrue(got_type_error == isCheckedMode());
+}
+
diff --git a/tests/language/final_for_in_variable_test.dart b/tests/language/final_for_in_variable_test.dart
index abbabb0..c657579 100644
--- a/tests/language/final_for_in_variable_test.dart
+++ b/tests/language/final_for_in_variable_test.dart
@@ -4,6 +4,6 @@
 
 main() {
   for (final i in [1, 2, 3]) {
-    i = 4; /// 01: compile-time error
+    i = 4; /// 01: static type warning, runtime error
   }
 }
diff --git a/tests/language/final_param_negative_test.dart b/tests/language/final_param_test.dart
similarity index 85%
rename from tests/language/final_param_negative_test.dart
rename to tests/language/final_param_test.dart
index 8857735..ddf6e7f 100644
--- a/tests/language/final_param_negative_test.dart
+++ b/tests/language/final_param_test.dart
@@ -5,7 +5,7 @@
 
 class A {
   static void test(final x) {
-    x = 2;  // <- reassignment not allowed.
+    x = 2;  /// 01: static type warning, runtime error
   }
 }
 
diff --git a/tests/language/function_subtype_simple0_test.dart b/tests/language/function_subtype_simple0_test.dart
new file mode 100644
index 0000000..07df06b
--- /dev/null
+++ b/tests/language/function_subtype_simple0_test.dart
@@ -0,0 +1,316 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping of simple function types.
+
+import 'package:expect/expect.dart';
+
+typedef Args0();
+typedef Args1(a);
+typedef Args2(a, b);
+typedef Args3(a, b, c);
+typedef Args4(a, b, c, d);
+typedef Args5(a, b, c, d, e);
+typedef Args6(a, b, c, d, e, f);
+typedef Args7(a, b, c, d, e, f, g);
+typedef Args8(a, b, c, d, e, f, g, h);
+typedef Args9(a, b, c, d, e, f, g, h, i);
+typedef Args10(a, b, c, d, e, f, g, h, i, j);
+typedef Args11(a, b, c, d, e, f, g, h, i, j, k);
+typedef Args12(a, b, c, d, e, f, g, h, i, j, k, l);
+typedef Args13(a, b, c, d, e, f, g, h, i, j, k, l, m);
+typedef Args14(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
+typedef Args15(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
+
+args0() {}
+args1(a) {}
+args2(a, b) {}
+args3(a, b, c) {}
+args4(a, b, c, d) {}
+args5(a, b, c, d, e) {}
+args6(a, b, c, d, e, f) {}
+args7(a, b, c, d, e, f, g) {}
+args8(a, b, c, d, e, f, g, h) {}
+args9(a, b, c, d, e, f, g, h, i) {}
+args10(a, b, c, d, e, f, g, h, i, j) {}
+args11(a, b, c, d, e, f, g, h, i, j, k) {}
+args12(a, b, c, d, e, f, g, h, i, j, k, l) {}
+args13(a, b, c, d, e, f, g, h, i, j, k, l, m) {}
+args14(a, b, c, d, e, f, g, h, i, j, k, l, m, n) {}
+args15(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) {}
+
+main() {
+  Expect.isTrue(args0 is Args0);
+  Expect.isFalse(args0 is Args1);
+  Expect.isFalse(args0 is Args2);
+  Expect.isFalse(args0 is Args3);
+  Expect.isFalse(args0 is Args4);
+  Expect.isFalse(args0 is Args5);
+  Expect.isFalse(args0 is Args6);
+  Expect.isFalse(args0 is Args7);
+  Expect.isFalse(args0 is Args8);
+  Expect.isFalse(args0 is Args9);
+  Expect.isFalse(args0 is Args10);
+  Expect.isFalse(args0 is Args11);
+  Expect.isFalse(args0 is Args12);
+  Expect.isFalse(args0 is Args13);
+  Expect.isFalse(args0 is Args14);
+  Expect.isFalse(args0 is Args15);
+
+  Expect.isFalse(args1 is Args0);
+  Expect.isTrue(args1 is Args1);
+  Expect.isFalse(args1 is Args2);
+  Expect.isFalse(args1 is Args3);
+  Expect.isFalse(args1 is Args4);
+  Expect.isFalse(args1 is Args5);
+  Expect.isFalse(args1 is Args6);
+  Expect.isFalse(args1 is Args7);
+  Expect.isFalse(args1 is Args8);
+  Expect.isFalse(args1 is Args9);
+  Expect.isFalse(args1 is Args10);
+  Expect.isFalse(args1 is Args11);
+  Expect.isFalse(args1 is Args12);
+  Expect.isFalse(args1 is Args13);
+  Expect.isFalse(args1 is Args14);
+  Expect.isFalse(args1 is Args15);
+
+  Expect.isFalse(args2 is Args0);
+  Expect.isFalse(args2 is Args1);
+  Expect.isTrue(args2 is Args2);
+  Expect.isFalse(args2 is Args3);
+  Expect.isFalse(args2 is Args4);
+  Expect.isFalse(args2 is Args5);
+  Expect.isFalse(args2 is Args6);
+  Expect.isFalse(args2 is Args7);
+  Expect.isFalse(args2 is Args8);
+  Expect.isFalse(args2 is Args9);
+  Expect.isFalse(args2 is Args10);
+  Expect.isFalse(args2 is Args11);
+  Expect.isFalse(args2 is Args12);
+  Expect.isFalse(args2 is Args13);
+  Expect.isFalse(args2 is Args14);
+  Expect.isFalse(args2 is Args15);
+
+  Expect.isFalse(args3 is Args0);
+  Expect.isFalse(args3 is Args1);
+  Expect.isFalse(args3 is Args2);
+  Expect.isTrue(args3 is Args3);
+  Expect.isFalse(args3 is Args4);
+  Expect.isFalse(args3 is Args5);
+  Expect.isFalse(args3 is Args6);
+  Expect.isFalse(args3 is Args7);
+  Expect.isFalse(args3 is Args8);
+  Expect.isFalse(args3 is Args9);
+  Expect.isFalse(args3 is Args10);
+  Expect.isFalse(args3 is Args11);
+  Expect.isFalse(args3 is Args12);
+  Expect.isFalse(args3 is Args13);
+  Expect.isFalse(args3 is Args14);
+  Expect.isFalse(args3 is Args15);
+
+  Expect.isFalse(args4 is Args0);
+  Expect.isFalse(args4 is Args1);
+  Expect.isFalse(args4 is Args2);
+  Expect.isFalse(args4 is Args3);
+  Expect.isTrue(args4 is Args4);
+  Expect.isFalse(args4 is Args5);
+  Expect.isFalse(args4 is Args6);
+  Expect.isFalse(args4 is Args7);
+  Expect.isFalse(args4 is Args8);
+  Expect.isFalse(args4 is Args9);
+  Expect.isFalse(args4 is Args10);
+  Expect.isFalse(args4 is Args11);
+  Expect.isFalse(args4 is Args12);
+  Expect.isFalse(args4 is Args13);
+  Expect.isFalse(args4 is Args14);
+  Expect.isFalse(args4 is Args15);
+
+  Expect.isFalse(args5 is Args0);
+  Expect.isFalse(args5 is Args1);
+  Expect.isFalse(args5 is Args2);
+  Expect.isFalse(args5 is Args3);
+  Expect.isFalse(args5 is Args4);
+  Expect.isTrue(args5 is Args5);
+  Expect.isFalse(args5 is Args6);
+  Expect.isFalse(args5 is Args7);
+  Expect.isFalse(args5 is Args8);
+  Expect.isFalse(args5 is Args9);
+  Expect.isFalse(args5 is Args10);
+  Expect.isFalse(args5 is Args11);
+  Expect.isFalse(args5 is Args12);
+  Expect.isFalse(args5 is Args13);
+  Expect.isFalse(args5 is Args14);
+  Expect.isFalse(args5 is Args15);
+
+  Expect.isFalse(args6 is Args0);
+  Expect.isFalse(args6 is Args1);
+  Expect.isFalse(args6 is Args2);
+  Expect.isFalse(args6 is Args3);
+  Expect.isFalse(args6 is Args4);
+  Expect.isFalse(args6 is Args5);
+  Expect.isTrue(args6 is Args6);
+  Expect.isFalse(args6 is Args7);
+  Expect.isFalse(args6 is Args8);
+  Expect.isFalse(args6 is Args9);
+  Expect.isFalse(args6 is Args10);
+  Expect.isFalse(args6 is Args11);
+  Expect.isFalse(args6 is Args12);
+  Expect.isFalse(args6 is Args13);
+  Expect.isFalse(args6 is Args14);
+  Expect.isFalse(args6 is Args15);
+
+  Expect.isFalse(args7 is Args0);
+  Expect.isFalse(args7 is Args1);
+  Expect.isFalse(args7 is Args2);
+  Expect.isFalse(args7 is Args3);
+  Expect.isFalse(args7 is Args4);
+  Expect.isFalse(args7 is Args5);
+  Expect.isFalse(args7 is Args6);
+  Expect.isTrue(args7 is Args7);
+  Expect.isFalse(args7 is Args8);
+  Expect.isFalse(args7 is Args9);
+  Expect.isFalse(args7 is Args10);
+  Expect.isFalse(args7 is Args11);
+  Expect.isFalse(args7 is Args12);
+  Expect.isFalse(args7 is Args13);
+  Expect.isFalse(args7 is Args14);
+  Expect.isFalse(args7 is Args15);
+
+  Expect.isFalse(args8 is Args0);
+  Expect.isFalse(args8 is Args1);
+  Expect.isFalse(args8 is Args2);
+  Expect.isFalse(args8 is Args3);
+  Expect.isFalse(args8 is Args4);
+  Expect.isFalse(args8 is Args5);
+  Expect.isFalse(args8 is Args6);
+  Expect.isFalse(args8 is Args7);
+  Expect.isTrue(args8 is Args8);
+  Expect.isFalse(args8 is Args9);
+  Expect.isFalse(args8 is Args10);
+  Expect.isFalse(args8 is Args11);
+  Expect.isFalse(args8 is Args12);
+  Expect.isFalse(args8 is Args13);
+  Expect.isFalse(args8 is Args14);
+  Expect.isFalse(args8 is Args15);
+
+  Expect.isFalse(args9 is Args0);
+  Expect.isFalse(args9 is Args1);
+  Expect.isFalse(args9 is Args2);
+  Expect.isFalse(args9 is Args3);
+  Expect.isFalse(args9 is Args4);
+  Expect.isFalse(args9 is Args5);
+  Expect.isFalse(args9 is Args6);
+  Expect.isFalse(args9 is Args7);
+  Expect.isFalse(args9 is Args8);
+  Expect.isTrue(args9 is Args9);
+  Expect.isFalse(args9 is Args10);
+  Expect.isFalse(args9 is Args11);
+  Expect.isFalse(args9 is Args12);
+  Expect.isFalse(args9 is Args13);
+  Expect.isFalse(args9 is Args14);
+  Expect.isFalse(args9 is Args15);
+
+  Expect.isFalse(args10 is Args0);
+  Expect.isFalse(args10 is Args1);
+  Expect.isFalse(args10 is Args2);
+  Expect.isFalse(args10 is Args3);
+  Expect.isFalse(args10 is Args4);
+  Expect.isFalse(args10 is Args5);
+  Expect.isFalse(args10 is Args6);
+  Expect.isFalse(args10 is Args7);
+  Expect.isFalse(args10 is Args8);
+  Expect.isFalse(args10 is Args9);
+  Expect.isTrue(args10 is Args10);
+  Expect.isFalse(args10 is Args11);
+  Expect.isFalse(args10 is Args12);
+  Expect.isFalse(args10 is Args13);
+  Expect.isFalse(args10 is Args14);
+  Expect.isFalse(args10 is Args15);
+
+  Expect.isFalse(args11 is Args0);
+  Expect.isFalse(args11 is Args1);
+  Expect.isFalse(args11 is Args2);
+  Expect.isFalse(args11 is Args3);
+  Expect.isFalse(args11 is Args4);
+  Expect.isFalse(args11 is Args5);
+  Expect.isFalse(args11 is Args6);
+  Expect.isFalse(args11 is Args7);
+  Expect.isFalse(args11 is Args8);
+  Expect.isFalse(args11 is Args9);
+  Expect.isFalse(args11 is Args10);
+  Expect.isTrue(args11 is Args11);
+  Expect.isFalse(args11 is Args12);
+  Expect.isFalse(args11 is Args13);
+  Expect.isFalse(args11 is Args14);
+  Expect.isFalse(args11 is Args15);
+
+  Expect.isFalse(args12 is Args0);
+  Expect.isFalse(args12 is Args1);
+  Expect.isFalse(args12 is Args2);
+  Expect.isFalse(args12 is Args3);
+  Expect.isFalse(args12 is Args4);
+  Expect.isFalse(args12 is Args5);
+  Expect.isFalse(args12 is Args6);
+  Expect.isFalse(args12 is Args7);
+  Expect.isFalse(args12 is Args8);
+  Expect.isFalse(args12 is Args9);
+  Expect.isFalse(args12 is Args10);
+  Expect.isFalse(args12 is Args11);
+  Expect.isTrue(args12 is Args12);
+  Expect.isFalse(args12 is Args13);
+  Expect.isFalse(args12 is Args14);
+  Expect.isFalse(args12 is Args15);
+
+  Expect.isFalse(args13 is Args0);
+  Expect.isFalse(args13 is Args1);
+  Expect.isFalse(args13 is Args2);
+  Expect.isFalse(args13 is Args3);
+  Expect.isFalse(args13 is Args4);
+  Expect.isFalse(args13 is Args5);
+  Expect.isFalse(args13 is Args6);
+  Expect.isFalse(args13 is Args7);
+  Expect.isFalse(args13 is Args8);
+  Expect.isFalse(args13 is Args9);
+  Expect.isFalse(args13 is Args10);
+  Expect.isFalse(args13 is Args11);
+  Expect.isFalse(args13 is Args12);
+  Expect.isTrue(args13 is Args13);
+  Expect.isFalse(args13 is Args14);
+  Expect.isFalse(args13 is Args15);
+
+  Expect.isFalse(args14 is Args0);
+  Expect.isFalse(args14 is Args1);
+  Expect.isFalse(args14 is Args2);
+  Expect.isFalse(args14 is Args3);
+  Expect.isFalse(args14 is Args4);
+  Expect.isFalse(args14 is Args5);
+  Expect.isFalse(args14 is Args6);
+  Expect.isFalse(args14 is Args7);
+  Expect.isFalse(args14 is Args8);
+  Expect.isFalse(args14 is Args9);
+  Expect.isFalse(args14 is Args10);
+  Expect.isFalse(args14 is Args11);
+  Expect.isFalse(args14 is Args12);
+  Expect.isFalse(args14 is Args13);
+  Expect.isTrue(args14 is Args14);
+  Expect.isFalse(args14 is Args15);
+
+  Expect.isFalse(args15 is Args0);
+  Expect.isFalse(args15 is Args1);
+  Expect.isFalse(args15 is Args2);
+  Expect.isFalse(args15 is Args3);
+  Expect.isFalse(args15 is Args4);
+  Expect.isFalse(args15 is Args5);
+  Expect.isFalse(args15 is Args6);
+  Expect.isFalse(args15 is Args7);
+  Expect.isFalse(args15 is Args8);
+  Expect.isFalse(args15 is Args9);
+  Expect.isFalse(args15 is Args10);
+  Expect.isFalse(args15 is Args11);
+  Expect.isFalse(args15 is Args12);
+  Expect.isFalse(args15 is Args13);
+  Expect.isFalse(args15 is Args14);
+  Expect.isTrue(args15 is Args15);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_simple1_test.dart b/tests/language/function_subtype_simple1_test.dart
new file mode 100644
index 0000000..1e523cc
--- /dev/null
+++ b/tests/language/function_subtype_simple1_test.dart
@@ -0,0 +1,322 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping of simple function types.
+
+import 'package:expect/expect.dart';
+
+typedef Args0();
+typedef Args1(a);
+typedef Args2(a, b);
+typedef Args3(a, b, c);
+typedef Args4(a, b, c, d);
+typedef Args5(a, b, c, d, e);
+typedef Args6(a, b, c, d, e, f);
+typedef Args7(a, b, c, d, e, f, g);
+typedef Args8(a, b, c, d, e, f, g, h);
+typedef Args9(a, b, c, d, e, f, g, h, i);
+typedef Args10(a, b, c, d, e, f, g, h, i, j);
+typedef Args11(a, b, c, d, e, f, g, h, i, j, k);
+typedef Args12(a, b, c, d, e, f, g, h, i, j, k, l);
+typedef Args13(a, b, c, d, e, f, g, h, i, j, k, l, m);
+typedef Args14(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
+typedef Args15(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
+
+void args0() {}
+void args1(int a) {}
+void args2(int a, int b) {}
+void args3(int a, int b, int c) {}
+void args4(int a, int b, int c, int d) {}
+void args5(int a, int b, int c, int d, int e) {}
+void args6(int a, int b, int c, int d, int e, int f) {}
+void args7(int a, int b, int c, int d, int e, int f, int g) {}
+void args8(int a, int b, int c, int d, int e, int f, int g, int h) {}
+void args9(int a, int b, int c, int d, int e, int f, int g, int h, int i) {}
+void args10(int a, int b, int c, int d, int e, int f, int g, int h, int i,
+            int j) {}
+void args11(int a, int b, int c, int d, int e, int f, int g, int h, int i,
+            int j, int k) {}
+void args12(int a, int b, int c, int d, int e, int f, int g, int h, int i,
+            int j, int k, int l) {}
+void args13(int a, int b, int c, int d, int e, int f, int g, int h, int i,
+            int j, int k, int l, int m) {}
+void args14(int a, int b, int c, int d, int e, int f, int g, int h, int i,
+            int j, int k, int l, int m, int n) {}
+void args15(int a, int b, int c, int d, int e, int f, int g, int h, int i,
+            int j, int k, int l, int m, int n, int o) {}
+
+main() {
+  Expect.isTrue(args0 is Args0);
+  Expect.isFalse(args0 is Args1);
+  Expect.isFalse(args0 is Args2);
+  Expect.isFalse(args0 is Args3);
+  Expect.isFalse(args0 is Args4);
+  Expect.isFalse(args0 is Args5);
+  Expect.isFalse(args0 is Args6);
+  Expect.isFalse(args0 is Args7);
+  Expect.isFalse(args0 is Args8);
+  Expect.isFalse(args0 is Args9);
+  Expect.isFalse(args0 is Args10);
+  Expect.isFalse(args0 is Args11);
+  Expect.isFalse(args0 is Args12);
+  Expect.isFalse(args0 is Args13);
+  Expect.isFalse(args0 is Args14);
+  Expect.isFalse(args0 is Args15);
+
+  Expect.isFalse(args1 is Args0);
+  Expect.isTrue(args1 is Args1);
+  Expect.isFalse(args1 is Args2);
+  Expect.isFalse(args1 is Args3);
+  Expect.isFalse(args1 is Args4);
+  Expect.isFalse(args1 is Args5);
+  Expect.isFalse(args1 is Args6);
+  Expect.isFalse(args1 is Args7);
+  Expect.isFalse(args1 is Args8);
+  Expect.isFalse(args1 is Args9);
+  Expect.isFalse(args1 is Args10);
+  Expect.isFalse(args1 is Args11);
+  Expect.isFalse(args1 is Args12);
+  Expect.isFalse(args1 is Args13);
+  Expect.isFalse(args1 is Args14);
+  Expect.isFalse(args1 is Args15);
+
+  Expect.isFalse(args2 is Args0);
+  Expect.isFalse(args2 is Args1);
+  Expect.isTrue(args2 is Args2);
+  Expect.isFalse(args2 is Args3);
+  Expect.isFalse(args2 is Args4);
+  Expect.isFalse(args2 is Args5);
+  Expect.isFalse(args2 is Args6);
+  Expect.isFalse(args2 is Args7);
+  Expect.isFalse(args2 is Args8);
+  Expect.isFalse(args2 is Args9);
+  Expect.isFalse(args2 is Args10);
+  Expect.isFalse(args2 is Args11);
+  Expect.isFalse(args2 is Args12);
+  Expect.isFalse(args2 is Args13);
+  Expect.isFalse(args2 is Args14);
+  Expect.isFalse(args2 is Args15);
+
+  Expect.isFalse(args3 is Args0);
+  Expect.isFalse(args3 is Args1);
+  Expect.isFalse(args3 is Args2);
+  Expect.isTrue(args3 is Args3);
+  Expect.isFalse(args3 is Args4);
+  Expect.isFalse(args3 is Args5);
+  Expect.isFalse(args3 is Args6);
+  Expect.isFalse(args3 is Args7);
+  Expect.isFalse(args3 is Args8);
+  Expect.isFalse(args3 is Args9);
+  Expect.isFalse(args3 is Args10);
+  Expect.isFalse(args3 is Args11);
+  Expect.isFalse(args3 is Args12);
+  Expect.isFalse(args3 is Args13);
+  Expect.isFalse(args3 is Args14);
+  Expect.isFalse(args3 is Args15);
+
+  Expect.isFalse(args4 is Args0);
+  Expect.isFalse(args4 is Args1);
+  Expect.isFalse(args4 is Args2);
+  Expect.isFalse(args4 is Args3);
+  Expect.isTrue(args4 is Args4);
+  Expect.isFalse(args4 is Args5);
+  Expect.isFalse(args4 is Args6);
+  Expect.isFalse(args4 is Args7);
+  Expect.isFalse(args4 is Args8);
+  Expect.isFalse(args4 is Args9);
+  Expect.isFalse(args4 is Args10);
+  Expect.isFalse(args4 is Args11);
+  Expect.isFalse(args4 is Args12);
+  Expect.isFalse(args4 is Args13);
+  Expect.isFalse(args4 is Args14);
+  Expect.isFalse(args4 is Args15);
+
+  Expect.isFalse(args5 is Args0);
+  Expect.isFalse(args5 is Args1);
+  Expect.isFalse(args5 is Args2);
+  Expect.isFalse(args5 is Args3);
+  Expect.isFalse(args5 is Args4);
+  Expect.isTrue(args5 is Args5);
+  Expect.isFalse(args5 is Args6);
+  Expect.isFalse(args5 is Args7);
+  Expect.isFalse(args5 is Args8);
+  Expect.isFalse(args5 is Args9);
+  Expect.isFalse(args5 is Args10);
+  Expect.isFalse(args5 is Args11);
+  Expect.isFalse(args5 is Args12);
+  Expect.isFalse(args5 is Args13);
+  Expect.isFalse(args5 is Args14);
+  Expect.isFalse(args5 is Args15);
+
+  Expect.isFalse(args6 is Args0);
+  Expect.isFalse(args6 is Args1);
+  Expect.isFalse(args6 is Args2);
+  Expect.isFalse(args6 is Args3);
+  Expect.isFalse(args6 is Args4);
+  Expect.isFalse(args6 is Args5);
+  Expect.isTrue(args6 is Args6);
+  Expect.isFalse(args6 is Args7);
+  Expect.isFalse(args6 is Args8);
+  Expect.isFalse(args6 is Args9);
+  Expect.isFalse(args6 is Args10);
+  Expect.isFalse(args6 is Args11);
+  Expect.isFalse(args6 is Args12);
+  Expect.isFalse(args6 is Args13);
+  Expect.isFalse(args6 is Args14);
+  Expect.isFalse(args6 is Args15);
+
+  Expect.isFalse(args7 is Args0);
+  Expect.isFalse(args7 is Args1);
+  Expect.isFalse(args7 is Args2);
+  Expect.isFalse(args7 is Args3);
+  Expect.isFalse(args7 is Args4);
+  Expect.isFalse(args7 is Args5);
+  Expect.isFalse(args7 is Args6);
+  Expect.isTrue(args7 is Args7);
+  Expect.isFalse(args7 is Args8);
+  Expect.isFalse(args7 is Args9);
+  Expect.isFalse(args7 is Args10);
+  Expect.isFalse(args7 is Args11);
+  Expect.isFalse(args7 is Args12);
+  Expect.isFalse(args7 is Args13);
+  Expect.isFalse(args7 is Args14);
+  Expect.isFalse(args7 is Args15);
+
+  Expect.isFalse(args8 is Args0);
+  Expect.isFalse(args8 is Args1);
+  Expect.isFalse(args8 is Args2);
+  Expect.isFalse(args8 is Args3);
+  Expect.isFalse(args8 is Args4);
+  Expect.isFalse(args8 is Args5);
+  Expect.isFalse(args8 is Args6);
+  Expect.isFalse(args8 is Args7);
+  Expect.isTrue(args8 is Args8);
+  Expect.isFalse(args8 is Args9);
+  Expect.isFalse(args8 is Args10);
+  Expect.isFalse(args8 is Args11);
+  Expect.isFalse(args8 is Args12);
+  Expect.isFalse(args8 is Args13);
+  Expect.isFalse(args8 is Args14);
+  Expect.isFalse(args8 is Args15);
+
+  Expect.isFalse(args9 is Args0);
+  Expect.isFalse(args9 is Args1);
+  Expect.isFalse(args9 is Args2);
+  Expect.isFalse(args9 is Args3);
+  Expect.isFalse(args9 is Args4);
+  Expect.isFalse(args9 is Args5);
+  Expect.isFalse(args9 is Args6);
+  Expect.isFalse(args9 is Args7);
+  Expect.isFalse(args9 is Args8);
+  Expect.isTrue(args9 is Args9);
+  Expect.isFalse(args9 is Args10);
+  Expect.isFalse(args9 is Args11);
+  Expect.isFalse(args9 is Args12);
+  Expect.isFalse(args9 is Args13);
+  Expect.isFalse(args9 is Args14);
+  Expect.isFalse(args9 is Args15);
+
+  Expect.isFalse(args10 is Args0);
+  Expect.isFalse(args10 is Args1);
+  Expect.isFalse(args10 is Args2);
+  Expect.isFalse(args10 is Args3);
+  Expect.isFalse(args10 is Args4);
+  Expect.isFalse(args10 is Args5);
+  Expect.isFalse(args10 is Args6);
+  Expect.isFalse(args10 is Args7);
+  Expect.isFalse(args10 is Args8);
+  Expect.isFalse(args10 is Args9);
+  Expect.isTrue(args10 is Args10);
+  Expect.isFalse(args10 is Args11);
+  Expect.isFalse(args10 is Args12);
+  Expect.isFalse(args10 is Args13);
+  Expect.isFalse(args10 is Args14);
+  Expect.isFalse(args10 is Args15);
+
+  Expect.isFalse(args11 is Args0);
+  Expect.isFalse(args11 is Args1);
+  Expect.isFalse(args11 is Args2);
+  Expect.isFalse(args11 is Args3);
+  Expect.isFalse(args11 is Args4);
+  Expect.isFalse(args11 is Args5);
+  Expect.isFalse(args11 is Args6);
+  Expect.isFalse(args11 is Args7);
+  Expect.isFalse(args11 is Args8);
+  Expect.isFalse(args11 is Args9);
+  Expect.isFalse(args11 is Args10);
+  Expect.isTrue(args11 is Args11);
+  Expect.isFalse(args11 is Args12);
+  Expect.isFalse(args11 is Args13);
+  Expect.isFalse(args11 is Args14);
+  Expect.isFalse(args11 is Args15);
+
+  Expect.isFalse(args12 is Args0);
+  Expect.isFalse(args12 is Args1);
+  Expect.isFalse(args12 is Args2);
+  Expect.isFalse(args12 is Args3);
+  Expect.isFalse(args12 is Args4);
+  Expect.isFalse(args12 is Args5);
+  Expect.isFalse(args12 is Args6);
+  Expect.isFalse(args12 is Args7);
+  Expect.isFalse(args12 is Args8);
+  Expect.isFalse(args12 is Args9);
+  Expect.isFalse(args12 is Args10);
+  Expect.isFalse(args12 is Args11);
+  Expect.isTrue(args12 is Args12);
+  Expect.isFalse(args12 is Args13);
+  Expect.isFalse(args12 is Args14);
+  Expect.isFalse(args12 is Args15);
+
+  Expect.isFalse(args13 is Args0);
+  Expect.isFalse(args13 is Args1);
+  Expect.isFalse(args13 is Args2);
+  Expect.isFalse(args13 is Args3);
+  Expect.isFalse(args13 is Args4);
+  Expect.isFalse(args13 is Args5);
+  Expect.isFalse(args13 is Args6);
+  Expect.isFalse(args13 is Args7);
+  Expect.isFalse(args13 is Args8);
+  Expect.isFalse(args13 is Args9);
+  Expect.isFalse(args13 is Args10);
+  Expect.isFalse(args13 is Args11);
+  Expect.isFalse(args13 is Args12);
+  Expect.isTrue(args13 is Args13);
+  Expect.isFalse(args13 is Args14);
+  Expect.isFalse(args13 is Args15);
+
+  Expect.isFalse(args14 is Args0);
+  Expect.isFalse(args14 is Args1);
+  Expect.isFalse(args14 is Args2);
+  Expect.isFalse(args14 is Args3);
+  Expect.isFalse(args14 is Args4);
+  Expect.isFalse(args14 is Args5);
+  Expect.isFalse(args14 is Args6);
+  Expect.isFalse(args14 is Args7);
+  Expect.isFalse(args14 is Args8);
+  Expect.isFalse(args14 is Args9);
+  Expect.isFalse(args14 is Args10);
+  Expect.isFalse(args14 is Args11);
+  Expect.isFalse(args14 is Args12);
+  Expect.isFalse(args14 is Args13);
+  Expect.isTrue(args14 is Args14);
+  Expect.isFalse(args14 is Args15);
+
+  Expect.isFalse(args15 is Args0);
+  Expect.isFalse(args15 is Args1);
+  Expect.isFalse(args15 is Args2);
+  Expect.isFalse(args15 is Args3);
+  Expect.isFalse(args15 is Args4);
+  Expect.isFalse(args15 is Args5);
+  Expect.isFalse(args15 is Args6);
+  Expect.isFalse(args15 is Args7);
+  Expect.isFalse(args15 is Args8);
+  Expect.isFalse(args15 is Args9);
+  Expect.isFalse(args15 is Args10);
+  Expect.isFalse(args15 is Args11);
+  Expect.isFalse(args15 is Args12);
+  Expect.isFalse(args15 is Args13);
+  Expect.isFalse(args15 is Args14);
+  Expect.isTrue(args15 is Args15);
+}
\ No newline at end of file
diff --git a/tests/language/function_subtype_simple2_test.dart b/tests/language/function_subtype_simple2_test.dart
new file mode 100644
index 0000000..70f53f3
--- /dev/null
+++ b/tests/language/function_subtype_simple2_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping of simple function types.
+
+import 'package:expect/expect.dart';
+
+typedef Args0();
+typedef Args1(a);
+typedef Args2(a, b);
+typedef Args3(a, b, c);
+typedef Args4(a, b, c, d);
+
+args0_1([a]) {}
+args1_2(a, [b]) {}
+args0_2([a, b]) {}
+args1_3(a, [b, c]) {}
+
+args0_1_named({a}) {}
+args1_2_named(a, {b}) {}
+args0_2_named({a, b}) {}
+args1_3_named(a, {b, c}) {}
+
+main() {
+  Expect.isTrue(args0_1 is Args0);
+  Expect.isTrue(args0_1 is Args1);
+  Expect.isFalse(args0_1 is Args2);
+  Expect.isFalse(args0_1 is Args3);
+  Expect.isFalse(args0_1 is Args4);
+
+  Expect.isFalse(args1_2 is Args0);
+  Expect.isTrue(args1_2 is Args1);
+  Expect.isTrue(args1_2 is Args2);
+  Expect.isFalse(args1_2 is Args3);
+  Expect.isFalse(args1_2 is Args4);
+
+  Expect.isTrue(args0_2 is Args0);
+  Expect.isTrue(args0_2 is Args1);
+  Expect.isTrue(args0_2 is Args2);
+  Expect.isFalse(args0_2 is Args3);
+  Expect.isFalse(args0_2 is Args4);
+
+  Expect.isFalse(args1_3 is Args0);
+  Expect.isTrue(args1_3 is Args1);
+  Expect.isTrue(args1_3 is Args2);
+  Expect.isTrue(args1_3 is Args3);
+  Expect.isFalse(args1_3 is Args4);
+
+  Expect.isTrue(args0_1_named is Args0);
+  Expect.isFalse(args0_1_named is Args1);
+  Expect.isFalse(args0_1_named is Args2);
+  Expect.isFalse(args0_1_named is Args3);
+  Expect.isFalse(args0_1_named is Args4);
+
+  Expect.isFalse(args1_2_named is Args0);
+  Expect.isTrue(args1_2_named is Args1);
+  Expect.isFalse(args1_2_named is Args2);
+  Expect.isFalse(args1_2_named is Args3);
+  Expect.isFalse(args1_2_named is Args4);
+
+  Expect.isTrue(args0_2_named is Args0);
+  Expect.isFalse(args0_2_named is Args1);
+  Expect.isFalse(args0_2_named is Args2);
+  Expect.isFalse(args0_2_named is Args3);
+  Expect.isFalse(args0_2_named is Args4);
+
+  Expect.isFalse(args1_3_named is Args0);
+  Expect.isTrue(args1_3_named is Args1);
+  Expect.isFalse(args1_3_named is Args2);
+  Expect.isFalse(args1_3_named is Args3);
+  Expect.isFalse(args1_3_named is Args4);
+}
\ No newline at end of file
diff --git a/tests/language/generic_test.dart b/tests/language/generic_test.dart
index 918162c..35c5783 100644
--- a/tests/language/generic_test.dart
+++ b/tests/language/generic_test.dart
@@ -56,11 +56,6 @@
       E e = new E();  // Throws a type error, if type checks are enabled.
     } on TypeError catch (error) {
       result = 1;
-      // Location of malformed error: T extends A, but AX does not extend A.
-      Expect.isTrue(error.toString().contains("line 20 pos 9"));
-      // Location of failed type check: new B<T>(t)/
-      Expect.isTrue(error.stackTrace.toString().contains(
-          "generic_test.dart:31:21"));
     }
     return result;
   }
diff --git a/tests/language/get_set_syntax_test.dart b/tests/language/get_set_syntax_test.dart
index 9b304cf..60645fc 100644
--- a/tests/language/get_set_syntax_test.dart
+++ b/tests/language/get_set_syntax_test.dart
@@ -1,7 +1,6 @@
 // Copyright (c) 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.
-// VMOptions=--compile_all
 
 var get;
 var get a;            /// 00: compile-time error
@@ -42,5 +41,7 @@
 }
 
 main() {
+  new C0();
   new C1();
+  new C2();
 }
diff --git a/tests/language/inferrer_named_parameter_test.dart b/tests/language/inferrer_named_parameter_test.dart
new file mode 100644
index 0000000..200c239
--- /dev/null
+++ b/tests/language/inferrer_named_parameter_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js's type inferrer, that used to not
+// correclty infer optional named parameters.
+
+import "package:expect/expect.dart";
+import "compiler_annotations.dart";
+
+@DontInline()
+foo({path}) {
+  () => 42;
+  return path;
+}
+
+main() {
+  foo(path: '42');
+  Expect.isFalse(foo() is String);
+}
diff --git a/tests/language/invocation_mirror_test.dart b/tests/language/invocation_mirror_test.dart
index 48393e9..6ea715d 100644
--- a/tests/language/invocation_mirror_test.dart
+++ b/tests/language/invocation_mirror_test.dart
@@ -73,11 +73,8 @@
   Expect.isFalse(im.isSetter, "$name:isSetter");
   Expect.isFalse(im.isGetter, "$name:isGetter");
 
-  Expect.equals(positional.length, im.positionalArguments.length);
-  for (int i = 0; i < positional.length; i++) {
-    Expect.equals(positional[i], im.positionalArguments[i],
-                  "$name:positional[$i]");
-  }
+  Expect.listEquals(positional, im.positionalArguments);
+
   Expect.equals(namedArguments.length, im.namedArguments.length,
                 "$name:#named");
   namedArguments.forEach((k, v) {
diff --git a/tests/language/language.status b/tests/language/language.status
index 1d8e778..8e8443b 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -5,15 +5,6 @@
 # This directory contains tests that are intended to show the
 # current state of the language.
 
-[ $compiler == dart2js && ($runtime == ie9 || $runtime == ie10) ]
-licm2_test: Skip # Issue 12298
-
-[ $compiler == dart2dart ]
-mixin_super_constructor_named_test: Fail # Issue 12631
-mixin_super_constructor_positionals_test: Fail # Issue 12631
-function_type_alias6_test/00: Fail # Issue 11986
-function_type_alias9_test/00: Crash # Issue 11986
-
 [ $compiler == none ]
 mixin_super_constructor_named_test: Fail # Issue 12631
 mixin_super_constructor_positionals_test: Fail # Issue 12631
@@ -27,16 +18,16 @@
 constructor5_test: Fail # Issue 6422
 constructor6_test: Fail # Issue 6422
 closure_in_initializer_test: Fail # Issue 6422
+call_nonexistent_constructor_test: Fail # Issue 12820
 
 # Regular bugs which should be fixed.
 super_first_constructor_test: Fail # Issue 1372.
-parameter_initializer6_negative_test: Fail # Issue 3502
 lazy_static3_test: Fail # Issue 12593
 export_cyclic_test: Fail, Crash # Issue 6060
 duplicate_export_negative_test: Fail # Issue 6134
 on_catch_malformed_type_test: Fail # Issue 8601
-mixin_mixin_test: Fail # Issue 12636
-mixin_issue10216_2_test: Fail # Issue 12636
+mixin_mixin_test: Fail # Issue 9683
+mixin_issue10216_2_test: Fail # Issue 9683
 mixin_illegal_object_test/01: Crash # Issue 10952
 mixin_illegal_object_test/02: Crash # Issue 10952
 mixin_forwarding_constructor2_test: Fail # Issue 11888
@@ -60,204 +51,12 @@
 compile_time_constant_checked3_test/05: Fail, OK
 compile_time_constant_checked3_test/06: Fail, OK
 
-[ $runtime == dartium ]
-import_combinators_test: Fail
-
 [ $runtime == vm || ($runtime == drt && $compiler == none) ]
 first_class_types_literals_test: Fail # issue 11761
 call_test: Fail # Issue 12602
 dynamic_prefix_core_test: Fail # Issue 12478
 
-[ $runtime == chrome ]
-
-
-[ $browser ]
-
-
-[ $compiler == dart2dart ]
-built_in_identifier_prefix_test: Fail # Inherited from dart2js.
-constructor_initializer_test: Fail # VM issue
-factory3_test: Fail
-type_checks_in_factory_method_test: Fail
-
-many_overridden_no_such_method_test: Fail, Pass, OK # Fails in minified mode, test depends on method names.
-overridden_no_such_method_test: Fail, Pass, OK # Fails in minified mode, test depends on method names.
-
-on_catch_malformed_type_test: Fail # Issue 8601
-
-# False positive compile-time error is masking expected compile-time error
-mixin_type_parameters_errors_test/*: Skip
-
-# Mixins fail on the VM.
-mixin_mixin_test: Fail                      # VM issue
-mixin_issue10216_2_test: Fail               # VM issue
-mixin_forwarding_constructor2_test: Fail # Issue 11888
-mixin_typedef_constructor_test: Fail # Issue 11888
-mixin_type_parameter2_test: Fail # Issue 11888
-
-mixin_with_two_implicit_constructors_test: Fail # Issue 11889
-
-# Malformed types not handled as unresolved:
-import_core_prefix_test: Fail
-prefix16_test: Fail
-prefix22_test: Fail
-
-# Calling unresolved class constructor:
-call_nonexistent_constructor_test: Fail
-
-bad_override_test/01: Fail # Issue 11496
-bad_override_test/02: Fail # Issue 11496
-bad_override_test/06: Fail # Issue 11496
-class_override_test/00: Fail # Issue 11496
-field_override3_test/00: Fail # Issue 11496
-field_override3_test/01: Fail # Issue 11496
-field_override3_test/02: Fail # Issue 11496
-field_override3_test/03: Fail # Issue 11496
-getter_override_test/00: Fail # Issue 11496
-getter_override_test/01: Fail # Issue 11496
-getter_override_test/02: Fail # Issue 11496
-method_override7_test/00: Fail # Issue 11496
-method_override7_test/01: Fail # Issue 11496
-method_override7_test/02: Fail # Issue 11496
-method_override8_test/03: Fail # Issue 11496
-setter_override_test/00: Fail # Issue 11496
-setter_override_test/03: Fail # Issue 11496
-setter_override2_test/02: Fail # Issue 11496
-
-compile_time_constant10_test/01: Fail # http://dartbug.com/5519
-compile_time_constant10_test/02: Fail # http://dartbug.com/5519
-compile_time_constant_arguments_test/01: Fail # http://dartbug.com/5519
-compile_time_constant_arguments_test/02: Fail # http://dartbug.com/5519
-compile_time_constant_arguments_test/03: Fail # http://dartbug.com/5519
-compile_time_constant_arguments_test/05: Fail # http://dartbug.com/5519
-compile_time_constant_arguments_test/06: Fail # http://dartbug.com/5519
-const_constructor_syntax_test/04: Fail # http://dartbug.com/5519
-const_syntax_test/01: Fail # http://dartbug.com/5519
-const_syntax_test/02: Fail # http://dartbug.com/5519
-const_syntax_test/03: Fail # http://dartbug.com/5519
-const_syntax_test/04: Fail # http://dartbug.com/5519
-const_syntax_test/05: Fail # http://dartbug.com/5519
-const_syntax_test/06: Fail # http://dartbug.com/5519
-const_syntax_test/07: Fail # http://dartbug.com/5519
-const_syntax_test/08: Fail # http://dartbug.com/5519
-const_syntax_test/10: Fail # http://dartbug.com/5519
-constructor_named_arguments_test/01: Fail # http://dartbug.com/5519
-final_for_in_variable_test/01: Fail # http://dartbug.com/5519
-final_is_not_const_test/01: Fail # http://dartbug.com/5519
-final_syntax_test/01: Fail # http://dartbug.com/5519
-final_syntax_test/02: Fail # http://dartbug.com/5519
-final_syntax_test/03: Fail # http://dartbug.com/5519
-final_syntax_test/04: Fail # http://dartbug.com/5519
-getter_no_setter_test/01: Fail # http://dartbug.com/5519
-named_parameters_aggregated_test/01: Fail # http://dartbug.com/5519
-named_parameters_aggregated_test/03: Fail # http://dartbug.com/5519
-not_enough_positional_arguments_test/01: Fail # http://dartbug.com/5519
-
-metadata_test: Fail
-# Fails in conservative mode, issue 4935, passes in minifinying mode.
-argument_definition_test/*: Skip # Not implemented.
-const_var_test: Pass, Fail # Map literals take 2 type arguments.
-map_literal3_test: Fail # Map literals take 2 type arguments.
-class_cycle_negative_test: Fail, OK # Bad test: assumes eager loading.
-interface_cycle_negative_test: Fail, OK # Bad test: assumes eager loading.
-# Common problems with dart2js.  In illegal family, invalid
-# declarations are simply not parsed.  In pseudo kw dart2js
-# chokes on things like typedef(x) => "typedef $x" and alike.
-abstract_syntax_test/01: Fail
-pseudo_kw_test: Fail
-# external keyword is not yet supported by dart2js/dart2dart.
-external_test/*: Skip
-lazy_static3_test: Fail # Issue 12593
-# dart2js frontend doesn't even analyse problematic classes.
-duplicate_implements_test/01: Fail
-duplicate_implements_test/02: Fail
-duplicate_implements_test/03: Fail
-duplicate_implements_test/04: Fail
-method_override4_test: Fail
-method_override5_test: Fail
-operator1_negative_test: Fail
-static_final_field_negative_test: Fail
-static_top_level_test/00: Fail
-static_top_level_test/01: Fail
-static_top_level_test/02: Fail
-static_top_level_test/03: Fail
-static_top_level_test/04: Fail
-static_top_level_test/05: Fail
-static_top_level_test/06: Fail
-static_top_level_test/07: Fail
-# Bug in dart2js parser: it happily parses 1is int; variable declaration.
-number_identifier_negative_test: Fail
-# Common with language_dart2js.
-factory_redirection_test/0*: Skip # Flaky negative tests, crash, fail, or pass. Not implemented.
-factory_redirection_test/1*: Skip # Flaky negative tests, crash, fail, or pass. Not implemented.
-function_type_alias5_test/00: Fail
-function_type_alias5_test/01: Fail
-function_type_alias5_test/02: Fail
-function_type_alias7_test/00: Fail
-parameter_initializer6_negative_test: Fail # Issue 3502
-syntax_test/47: Fail
-# DartVM problem.
-constructor5_test: Fail
-constructor6_test: Fail
-closure_in_initializer_test: Fail
-super_first_constructor_test: Fail
-# VM specific tests.
-# This test hard codes name of file being run and precise position.
-generic_test: Fail, Ok
-# Minified mode failures.
-# TODO(antonm): proper support in test framework.
-no_such_method_test: Pass, Fail, OK # Hard codes the name of invoked method ("foo").
-
-new_expression_type_args_test/00: Fail # Wrongly reports compile-time error.
-new_expression_type_args_test/01: Fail # Wrongly reports compile-time error.
-
-get_set_syntax_test/00: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/01: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/02: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/03: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/04: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/05: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/06: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/07: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/13: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/14: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/15: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-
-# Only checked mode reports an error on type assignment
-# problems in compile time constants.
-compile_time_constant_checked_test/02: Fail, OK
-compile_time_constant_checked2_test/01: Fail, OK
-compile_time_constant_checked2_test/02: Fail, OK
-compile_time_constant_checked2_test/03: Fail, OK
-compile_time_constant_checked2_test/04: Fail, OK
-compile_time_constant_checked2_test/05: Fail, OK
-compile_time_constant_checked2_test/06: Fail, OK
-compile_time_constant_checked3_test/01: Fail, OK
-compile_time_constant_checked3_test/02: Fail, OK
-compile_time_constant_checked3_test/03: Fail, OK
-compile_time_constant_checked3_test/04: Fail, OK
-compile_time_constant_checked3_test/05: Fail, OK
-compile_time_constant_checked3_test/06: Fail, OK
-
-positional_parameters_type_test: Fail # Triage this.
-
-[ $compiler == dart2dart && $minified ]
-super_getter_setter_test: Fail # Issue 11065.
-f_bounded_quantification4_test: Fail # Issue 12605.
-
-# TODO(tball): Assign proper bug numbers.
-class_literal_test: Fail
-
-import_core_prefix_test: Pass
-prefix22_test: Pass
-invocation_mirror_test: Fail, OK # hardcoded names.
-super_call4_test: Fail, OK # hardcoded names.
-
-[ $compiler == dart2js || $compiler == dart2dart]
-null_test/03: Fail    # Issue 12445.
-
-[ $compiler == dart2js ]
-null_test/none: Fail  # Issue 12482
-
 [ $compiler == none && $runtime == drt ]
 vm/reflect_core_vm_test: Fail  # Temporarily marked as fail.
+mixin_illegal_object_test/01: pass # Issue 10952.
+mixin_illegal_object_test/02: pass # Issue 10952.
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index 381133f..80e7313 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -8,7 +8,7 @@
 closure_call_wrong_argument_count_negative_test: skip
 
 # TBD: using built-in identifers
-built_in_identifier_prefix_test: fail
+built_in_identifier_prefix_test: fail # Issue 12694
 
 # TBF: It is a static type warning if a type parameter is a supertype of its upper bound.
 cyclic_type_variable_test/01: fail
@@ -17,21 +17,21 @@
 cyclic_type_variable_test/04: fail
 
 # TBF: It is a static type warning if any of the type arguments to k' are not subtypes of the bounds of the corresponding formal type parameters of type.
-default_factory2_test/01: fail
+default_factory2_test/01: fail # Issue 12701
 
 # TBF: It is a static warning if the function type of k' is not a subtype of the type of k.
 default_implementation2_test: fail
 
 # TBD: F-bounded quantification
-f_bounded_quantification_test/01: fail
-f_bounded_quantification_test/02: fail
+f_bounded_quantification_test/01: fail # Issue 12704
+f_bounded_quantification_test/02: fail # Issue 12704
 
 function_type_alias9_test/00: crash # Issue 11987
 
 list_literal_syntax_test/01: fail # Issue 12103
 list_literal_syntax_test/02: fail # Issue 12103
 list_literal_syntax_test/03: fail # Issue 12103
-malformed_test/none: fail
+malformed_test/none: fail # Issue 12696
 
 # TBF: 1is int; invalid character in number
 number_identifier_negative_test: fail
@@ -78,29 +78,28 @@
 # Test issue 11545, using not existing constructor name in annotation
 metadata_test: fail
 
-# Test issue 11564, named parameter starts with '_'
-named_parameters_with_object_property_names_test: fail
-
 # test issue 11575, classes with abstrac members are not marked as abstract
-abstract_factory_constructor_test/none: fail
-abstract_syntax_test/none: fail
-get_set_syntax_test/none: fail
-implicit_this_test/none: fail
-interface_test/none: fail
-syntax_test/none: fail
+abstract_factory_constructor_test/none: fail # Issue 11575
+abstract_syntax_test/none: fail # Issue 11575
+get_set_syntax_test/none: fail # Issue 11575
+implicit_this_test/none: fail # Issue 11575
+interface_test/none: fail # Issue 11575
+syntax_test/none: fail # Issue 11575
 
 # test issue 11576
-bad_constructor_test/none: fail
+bad_constructor_test/none: fail # Issue 11576
 
 # test issue 11577, has return type for []=
-cascade_test/none: fail
+cascade_test/none: fail # Issue 11577
 
 # test issue 11578, redirecting factory with not subtype
-factory5_test/none: fail
-factory_redirection_test/none: fail
-type_variable_bounds_test/none: fail
-type_variable_scope_test/none: fail
-factory_implementation_test/none: fail
+factory5_test/none: fail # Issue 11578
+factory_redirection_test/none: fail # Issue 11578
+type_variable_bounds_test/none: fail # Issue 11578
+type_variable_scope_test/none: fail # Issue 11578
+factory_implementation_test/none: fail # Issue 11578
+
+redirecting_factory_malbounded_test/none: Fail # Issue 12827
 
 # test issue 11579, assignment, no setter
 getter_no_setter_test/none: fail
@@ -116,9 +115,6 @@
 constructor_call_wrong_argument_count_negative_test: fail
 instance_call_wrong_argument_count_negative_test: fail
 
-# test issue 11586, Class(args) is compile-time warning, not error
-constructor_negative_test: fail
-
 # test issue 11589, export D from 2 export directives
 export_cyclic_test: fail
 
@@ -126,8 +122,6 @@
 field_method4_negative_test: fail
 
 # test issue 11591, assigning to the final variable is warning, not error
-final_for_in_variable_test/01: fail
-final_param_negative_test: fail
 getter_no_setter_test/01: fail
 
 # test issue 11592, Function type alias (typedef) is not a constant
@@ -185,49 +179,45 @@
 type_variable_static_context_negative_test: fail
 
 # test issue 12162, 'a' has dynamic type, so it statically it is assignable to anything
-type_variable_bounds2_test/00: fail
-type_variable_bounds2_test/01: fail
-type_variable_bounds2_test/02: fail
-type_variable_bounds2_test/03: fail
-type_variable_bounds2_test/04: fail
-type_variable_bounds2_test/06: fail
+type_variable_bounds2_test/00: fail # Issue 12162
+type_variable_bounds2_test/01: fail # Issue 12162
+type_variable_bounds2_test/02: fail # Issue 12162
+type_variable_bounds2_test/03: fail # Issue 12162
+type_variable_bounds2_test/04: fail # Issue 12162
+type_variable_bounds2_test/06: fail # Issue 12162
 
 # test issue 12163, unresolved identifier is static warning in static context
-unresolved_in_factory_negative_test: fail
-unresolved_top_level_var_negative_test: fail
+unresolved_in_factory_negative_test: fail # Issue 12163
+unresolved_top_level_var_negative_test: fail # Issue 12163
 
 # test issue 12181, uses argument definition test
-constructor_initializer_test: fail
-
-# test issue 12184, It is static warning, not error, to assign to a constant variable.
-static_final_field2_negative_test: fail
+constructor_initializer_test: fail # Issue 12181
 
 # test issue 12191, ambiguous import is always warning now
-prefix3_negative_test: fail
-library_ambiguous_test/00: fail
-library_ambiguous_test/01: fail
-library_ambiguous_test/02: fail
-library_ambiguous_test/03: fail
+prefix3_negative_test: fail # Issue 12191
+library_ambiguous_test/00: fail # Issue 12191
+library_ambiguous_test/01: fail # Issue 12191
+library_ambiguous_test/02: fail # Issue 12191
+library_ambiguous_test/03: fail # Issue 12191
 
 # test issue 12289, assignment in assert statement
-type_error_test: fail
+type_error_test: fail # Issue 12289
 
 # test issue 12381, It is compile-time error to invoke not existing function
-issue11724_test: fail
-call_nonexistent_static_test/08: fail
+issue11724_test: fail # Issue 12381
+call_nonexistent_static_test/08: fail # Issue 12381
 
 # test issue 12397; it is static warning, not error to use variable before declaration (or hidden)
-scope_negative_test: fail
+scope_negative_test: fail # Issue 12397
 
 # test issue 12539, rules for finals were loosened, contradiction in spec was fixed
-const_syntax_test/09: fail
+const_syntax_test/09: fail # Issue 12539
 
 # test issue 12541; there shouldn't be a static warning
-static_field_test/01: fail
-static_field_test/02: fail
-static_field_test/03: fail
-static_field_test/04: fail
-
+static_field_test/01: fail # Issue 12541
+static_field_test/02: fail # Issue 12541
+static_field_test/03: fail # Issue 12541
+static_field_test/04: fail # Issue 12541
 
 [ $compiler == dartanalyzer && $checked ]
 factory1_test/00: fail
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 84c6492..96785d6 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -13,7 +13,7 @@
 assign_static_type_test/06: fail
 
 # TBD: using built-in identifers
-built_in_identifier_prefix_test: fail
+built_in_identifier_prefix_test: fail # Issue 12694
 
 # TBF: (o as C) is not rolled back
 cast_test/04: fail
@@ -33,21 +33,21 @@
 cyclic_type_variable_test/04: fail
 
 # TBF: It is a static type warning if any of the type arguments to k' are not subtypes of the bounds of the corresponding formal type parameters of type.
-default_factory2_test/01: fail
+default_factory2_test/01: fail # Issue 12701
 
 # TBF: It is a static warning if the function type of k' is not a subtype of the type of k.
 default_implementation2_test: fail
 
 # TBD: F-bounded quantification
-f_bounded_quantification_test/01: fail
-f_bounded_quantification_test/02: fail
+f_bounded_quantification_test/01: fail # Issue 12704
+f_bounded_quantification_test/02: fail # Issue 12704
 
 function_type_alias9_test/00: crash # Issue 11987
 
 list_literal_syntax_test/01: fail # Issue 12103
 list_literal_syntax_test/02: fail # Issue 12103
 list_literal_syntax_test/03: fail # Issue 12103
-malformed_test/none: fail
+malformed_test/none: fail # Issue 12696
 
 # TBF: disallowed in the most recent spec
 named_parameters_aggregated_test/03: fail
@@ -163,9 +163,6 @@
 constructor_call_wrong_argument_count_negative_test: fail
 instance_call_wrong_argument_count_negative_test: fail
 
-# test issue 11586, Class(args) is compile-time warning, not error
-constructor_negative_test: fail
-
 # test issue 11589, export D from 2 export directives
 export_cyclic_test: fail
 
@@ -173,8 +170,6 @@
 field_method4_negative_test: fail
 
 # test issue 11591, assigning to the final variable is warning, not error
-final_for_in_variable_test/01: fail
-final_param_negative_test: fail
 getter_no_setter_test/01: fail
 
 # test issue 11592, Function type alias (typedef) is not a constant
@@ -232,33 +227,30 @@
 type_variable_static_context_negative_test: fail
 
 # test issue 12162, 'a' has dynamic type, so it statically it is assignable to anything
-type_variable_bounds2_test/00: fail
-type_variable_bounds2_test/01: fail
-type_variable_bounds2_test/02: fail
-type_variable_bounds2_test/03: fail
-type_variable_bounds2_test/04: fail
-type_variable_bounds2_test/06: fail
+type_variable_bounds2_test/00: fail # Issue 12162
+type_variable_bounds2_test/01: fail # Issue 12162
+type_variable_bounds2_test/02: fail # Issue 12162
+type_variable_bounds2_test/03: fail # Issue 12162
+type_variable_bounds2_test/04: fail # Issue 12162
+type_variable_bounds2_test/06: fail # Issue 12162
 
 # test issue 12163, unresolved identifier is static warning in static context
-unresolved_in_factory_negative_test: fail
-unresolved_top_level_method_negative_test: fail
-unresolved_top_level_var_negative_test: fail
+unresolved_in_factory_negative_test: fail # Issue 12163
+unresolved_top_level_method_negative_test: fail # Issue 12163
+unresolved_top_level_var_negative_test: fail # Issue 12163
 
 # test issue 12181, uses argument definition test
-constructor_initializer_test: fail
-
-# test issue 12184, It is static warning, not error, to assign to a constant variable.
-static_final_field2_negative_test: fail
+constructor_initializer_test: fail # Issue 12181
 
 # test issue 12191, ambuguous import is always warning now
-prefix3_negative_test: fail
-library_ambiguous_test/00: fail
-library_ambiguous_test/01: fail
-library_ambiguous_test/02: fail
-library_ambiguous_test/03: fail
+prefix3_negative_test: fail # Issue 12191
+library_ambiguous_test/00: fail # Issue 12191
+library_ambiguous_test/01: fail # Issue 12191
+library_ambiguous_test/02: fail # Issue 12191
+library_ambiguous_test/03: fail # Issue 12191
 
 # test issue 12289, assignment in assert statement
-type_error_test: fail
+type_error_test: fail # Issue 12289
 
 [ $compiler == dart2analyzer && $checked ]
 factory1_test/00: fail
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 7b31008..113b668 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -5,50 +5,51 @@
 [ $compiler == dart2js || $compiler == dart2dart ]
 compile_time_constant_c_test/none: Fail # Map literal with int key.
 constructor_initializer_test: Fail, OK # Depends on ?parameter check.
+null_test/03: Fail # Issue 12445.
 
 black_listed_test/none: Fail # Issue 12446.
 
 # Issues related to undeclared prefix resolution.
-malformed_test/none: Fail
-malformed_test/05: Fail
-malformed_test/06: Fail
+malformed_test/none: Fail # Issue 12695
+malformed_test/05: Fail # Issue 12695
+malformed_test/06: Fail # Issue 12695
 
-# Fails due to inlining. Not all expected frames are in the trace.
-full_stacktrace1_test: Pass, Fail
-full_stacktrace2_test: Pass, Fail
-full_stacktrace3_test: Pass, Fail
-# Stack traces may or may not end in a newline depending on the JS enging.
-stacktrace_test: Pass, Fail # Assumes stack trace string ends in newline.
+full_stacktrace1_test: Pass, Fail # Issue 12698
+full_stacktrace2_test: Pass, Fail # Issue 12698
+full_stacktrace3_test: Pass, Fail # Issue 12698
+stacktrace_test: Pass, Fail # # Issue 12698
 
 # VM specific tests that should not be run by dart2js.
-*vm_test: Skip
+vm/*: Skip # Issue 12699
 
 [ $compiler == dart2js && $checked ]
-checked_setter2_test: Fail # dartbug.com/11273
-default_factory2_test/01: Fail
-type_variable_bounds_test/01: Fail
-type_variable_bounds_test/02: Fail
-type_variable_bounds_test/04: Fail
-type_variable_bounds_test/05: Fail
-type_variable_bounds2_test/00: Fail
-type_variable_bounds2_test/03: Fail
-type_variable_bounds2_test/05: Fail
-type_variable_bounds2_test/06: Pass # For the wrong reasons.
-type_variable_bounds3_test/00: Fail
-f_bounded_quantification_test/01: Fail
-f_bounded_quantification_test/02: Fail
-closure_type_test: Fail # does not detect type error in checked mode.
-function_subtype_setter0_test: Fail # dartbug.com/11273
+checked_setter2_test: Fail # Issue 11273
+default_factory2_test/01: Fail # Issue 12700
+type_variable_bounds_test/01: Fail # Issue 12702
+type_variable_bounds_test/02: Fail # Issue 12702
+type_variable_bounds_test/04: Fail # Issue 12702
+type_variable_bounds_test/05: Fail # Issue 12702
+type_variable_bounds2_test/00: Fail # Issue 12702
+type_variable_bounds2_test/03: Fail # Issue 12702
+type_variable_bounds2_test/05: Fail # Issue 12702
+type_variable_bounds2_test/06: Pass # Issue 12702 (pass for the wrong reasons).
+type_variable_bounds3_test/00: Fail # Issue 12702
+f_bounded_quantification_test/01: Fail # Issue 12703
+f_bounded_quantification_test/02: Fail # Issue 12703
+f_bounded_quantification5_test: Fail # Issue 12703
+closure_type_test: Fail # Issue 12745
+function_subtype_setter0_test: Fail # Issue 11273
+redirecting_factory_malbounded_test/01: Fail # Issue 12825
 
 [ $compiler == dart2js && $unchecked ]
-factory_redirection_test/14: Fail # redirecting to redirecting factory
-type_checks_in_factory_method_test: Fail # Expect.equals(expected: <true>, actual: <false>) fails. -- checked mode test.
+factory_redirection_test/14: Fail # Issue 10959
+type_checks_in_factory_method_test: Fail # Issue 12746
 
-assertion_test: Fail
+assertion_test: Fail # Issue 12748
 
-double_to_string_as_exponential2_test: Fail # toStringAsExponential doesn't check if argument is an integer.
-double_to_string_as_fixed2_test: Fail # toStringAsFixed doesn't check if argument is an integer.
-double_to_string_as_precision2_test: Fail # toStringAsPrecision doesn't check if argument is an integer.
+double_to_string_as_exponential2_test: Fail # Issue 12749
+double_to_string_as_fixed2_test: Fail # Issue 12749
+double_to_string_as_precision2_test: Fail # Issue 12749
 
 # Only checked mode reports an error on type assignment
 # problems in compile time constants.
@@ -65,27 +66,29 @@
 compile_time_constant_checked3_test/04: Fail, OK
 compile_time_constant_checked3_test/05: Fail, OK
 compile_time_constant_checked3_test/06: Fail, OK
+generic_test: Fail, OK
 
 [ $compiler == dart2js && $minified ]
 f_bounded_quantification4_test: Fail # Issue 12605.
+f_bounded_quantification5_test: Fail # Issue 12605.
 
 [ $compiler == dart2js ]
-function_type_alias6_test/00: Crash # dartbug.com/9792
-function_type_alias9_test/00: Crash # dartbug.com/9792
+function_type_alias6_test/00: Crash # Issue 9792
+function_type_alias9_test/00: Crash # Issue 9792
 branch_canonicalization_test: Fail # Issue 638.
 div_with_power_of_two_test: Fail # Issue 8301.
 class_literal_test: Fail # Issue 7626.
 identical_closure2_test: Fail # Issue 1533, Issue 12596
-invocation_mirror_test: Fail
-built_in_identifier_prefix_test: Fail # http://dartbug.com/6972
-number_identity2_test: Fail # Issue 12596: identity of NaN
-new_expression_type_args_test/00: Fail # Wrongly reports compile-time error.
-new_expression_type_args_test/01: Fail # Wrongly reports compile-time error.
-double_int_to_string_test: Fail # Issue 1533 (double/integer distinction)
-mint_arithmetic_test: Fail # Issue 1533 (big integer arithmetic).
+invocation_mirror_test: Fail # Issue 12705
+built_in_identifier_prefix_test: Fail # Issue 6972
+number_identity2_test: Fail # Issue 12596
+new_expression_type_args_test/00: Fail # Issue 5519
+new_expression_type_args_test/01: Fail # Issue 5519
+double_int_to_string_test: Fail # Issue 1533
+mint_arithmetic_test: Fail # Issue 1533
 left_shift_test: Fail # Issue 1533
-factory_redirection_test/01: Fail
-factory_redirection_test/07: Fail
+factory_redirection_test/01: Fail # Issue 12752
+factory_redirection_test/07: Fail # Issue 12752
 bad_override_test/01: Fail # Issue 11496
 bad_override_test/02: Fail # Issue 11496
 bad_override_test/06: Fail # Issue 11496
@@ -104,49 +107,38 @@
 setter_override_test/00: Fail # Issue 11496
 setter_override_test/03: Fail # Issue 11496
 setter_override2_test/02: Fail # Issue 11496
-call_nonexistent_constructor_test: Fail
-constructor_named_arguments_test/01: Fail # http://dartbug.com/5519
-getter_no_setter_test/01: Fail # http://dartbug.com/5519
-not_enough_positional_arguments_test/01: Fail # http://dartbug.com/5519
-dynamic_test: Fail # http://dartbug.com/12398
-dynamic_prefix_core_test: Fail # http://dartbug.com/12398
-
-constructor_negative_test: Pass # Wrong reason: the expression 'C()' is valid with class literals.
-
-metadata_test: Fail # Metadata on type parameters not supported.
+constructor_named_arguments_test/01: Fail # Issue 5519
+getter_no_setter_test/01: Fail # Issue 5519
+not_enough_positional_arguments_test/01: Fail # Issue 12838
+not_enough_positional_arguments_test/02: Fail # Issue 12838
+not_enough_positional_arguments_test/04: Fail # Issue 12838
+not_enough_positional_arguments_test/05: Fail # Issue 12838
+dynamic_test: Fail # Issue 12398
+dynamic_prefix_core_test: Fail # Issue 12398
+metadata_test: Fail # Issue 5841
 infinity_test: Fail # Issue 4984
-positive_bit_operations_test: Fail # (floitsch): This will be fixed when dart2js uses unsigned input for >>.
-
-
-# Support for optional parameters not conform to latest spec.
+positive_bit_operations_test: Fail # Issue 12795
 named_parameters_type_test: Fail
 positional_parameters_type_test: Fail
 
 # Compilation errors.
-const_var_test: Fail # Map literals take 2 type arguments.
-map_literal3_test: Fail # Map literals take 2 type arguments.
-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_alias7_test/00: Fail # wrongly accepts default values in typedef
-generic_test: Fail # cannot resolve type T
-get_set_syntax_test/00: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/01: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/02: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/03: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/04: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/05: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/06: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/07: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/13: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/14: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-get_set_syntax_test/15: Fail # Fixed by https://chromiumcodereview.appspot.com/10915111
-method_binding_test: Fail # internal error: super property read not implemented.
-method_override_test: Fail # cannot resolve type GetKeysFunctionType
-method_override5_test: Pass, Fail # Issue 11496 (passes if it's inlined)
+const_var_test: Fail # Issue 12793
+map_literal3_test: Fail # Issue 12793
+function_type_alias5_test/00: Fail # Issue 12754
+function_type_alias5_test/01: Fail # Issue 12754
+function_type_alias5_test/02: Fail # Issue 12754
+function_type_alias7_test/00: Fail # Issue 12801
+get_set_syntax_test/00: Fail # Issue 12805
+get_set_syntax_test/01: Fail # Issue 12805
+get_set_syntax_test/02: Fail # Issue 12805
+get_set_syntax_test/03: Fail # Issue 12805
+get_set_syntax_test/04: Fail # Issue 12805
+method_binding_test: Fail # Issue 12807
+method_override_test: Fail # Issue 12808
+method_override5_test: Fail # Issue 12809
 parameter_initializer6_negative_test: Fail # Issue 3502
-named_parameters_aggregated_test/01: Fail # Presence of default values for optional params is not properly validated in type definitions.
-named_parameters_aggregated_test/03: Fail # Presence of default values for optional params is not properly validated in closure types.
+named_parameters_aggregated_test/01: Fail # Issue 12801
+named_parameters_aggregated_test/03: Fail # Issue 12812
 pseudo_kw_test: Fail # Unexpected token '('
 super_implicit_closure_test: Fail # internal error: super property read not implemented
 
@@ -174,12 +166,9 @@
 instanceof4_test: Fail # Expect.isTrue(false) fails.
 list_literal4_test: Fail # Illegal argument(s): 0 -- checked mode test.
 map_literal4_test: Fail # Attempt to modify an immutable object -- checked mode test.
-named_parameters_type_test: Fail # Expect.equals(expected: <111>, actual: <0>) fails. -- checked mode test.
 
 class_cycle_negative_test: Fail, OK # Bad test: assumes eager loading.
-external_test/16: Fail, OK # Bad test: assumes eager loading.
 interface_cycle_negative_test: Fail, OK # Bad test: assumes eager loading.
-syntax_test/47: Fail, OK # Bad test: assumes eager loading.
 
 
 #
@@ -198,7 +187,6 @@
 duplicate_implements_test/03: Fail # Negative language test.
 duplicate_implements_test/04: Fail # Negative language test.
 field3_negative_test: Fail # Negative language test.
-final_for_in_variable_test/01: Fail # Negative language test
 instantiate_type_variable_negative_test: Pass  # For the wrong reason.
 list_literal1_negative_test: Fail # Negative language test.
 map_literal1_negative_test: Fail # Negative language test.
@@ -241,28 +229,25 @@
 const_factory_negative_test: Crash, Fail
 
 assign_top_method_test: Fail
+null_test/none: Fail  # Issue 12482
 
 
 [ $compiler == dart2js && $runtime == none ]
 *: Fail, Pass # TODO(ahe): Triage these tests.
 
 
-[ $compiler == dart2js && ($runtime == ff || $runtime == jsshell || $runtime == ie9)]
-arithmetic_test: Fail # Issue 7881
+[ $compiler == dart2js && ($runtime == ff || $runtime == jsshell || $runtime == ie9 || $runtime == safari)]
+round_test: Fail, OK # Common JavaScript engine Math.round bug.
 
 
 [ $compiler == dart2js && $runtime == ie9 ]
-double_to_string_as_exponential3_test: Fail
-double_to_string_as_fixed_test: Fail
-double_to_string_as_precision3_test: Fail
+double_to_string_as_exponential3_test: Fail # Issue 12750
+double_to_string_as_fixed_test: Fail # Issue 12750
+double_to_string_as_precision3_test: Fail # Issue 12750
 expect_test: Fail
 stack_overflow_test: Fail
 stack_overflow_stacktrace_test: Fail
-licm2_test: Timeout # Issue: 11848
-
-
-[ $compiler == dart2js && $runtime == safari ]
-arithmetic_test: Fail # Issue: 7414
+licm2_test: Pass, Timeout # Issue: 11848
 
 
 [ $runtime == opera ]
@@ -276,3 +261,183 @@
 stack_overflow_stacktrace_test: Fail
 closure_call_wrong_argument_count_negative_test: Skip
 label_test: Skip
+
+
+[ $compiler == dart2dart ]
+mixin_super_constructor_named_test: Fail # Issue 12631
+mixin_super_constructor_positionals_test: Fail # Issue 12631
+function_type_alias6_test/00: Fail # Issue 11986
+function_type_alias9_test/00: Crash # Issue 11986
+
+built_in_identifier_prefix_test: Fail # Issue 6972
+constructor_initializer_test: Fail # VM issue
+factory3_test: Fail
+type_checks_in_factory_method_test: Fail # Issue 12747
+
+many_overridden_no_such_method_test: Fail, Pass, OK # Fails in minified mode, test depends on method names.
+overridden_no_such_method_test: Fail, Pass, OK # Fails in minified mode, test depends on method names.
+
+on_catch_malformed_type_test: Fail # Issue 8601
+
+# False positive compile-time error is masking expected compile-time error
+mixin_type_parameters_errors_test/*: Skip
+
+# Mixins fail on the VM.
+mixin_mixin_test: Fail # Issue 9683
+mixin_issue10216_2_test: Fail # Issue 9683
+mixin_forwarding_constructor2_test: Fail # Issue 11888
+mixin_typedef_constructor_test: Fail # Issue 11888
+mixin_type_parameter2_test: Fail # Issue 11888
+
+mixin_with_two_implicit_constructors_test: Fail # Issue 11889
+
+# Malformed types not handled as unresolved:
+import_core_prefix_test: Fail
+prefix16_test: Fail
+prefix22_test: Fail
+
+# Calling unresolved class constructor:
+call_nonexistent_constructor_test: Fail
+
+bad_override_test/01: Fail # Issue 11496
+bad_override_test/02: Fail # Issue 11496
+bad_override_test/06: Fail # Issue 11496
+class_override_test/00: Fail # Issue 11496
+field_override3_test/00: Fail # Issue 11496
+field_override3_test/01: Fail # Issue 11496
+field_override3_test/02: Fail # Issue 11496
+field_override3_test/03: Fail # Issue 11496
+getter_override_test/00: Fail # Issue 11496
+getter_override_test/01: Fail # Issue 11496
+getter_override_test/02: Fail # Issue 11496
+method_override7_test/00: Fail # Issue 11496
+method_override7_test/01: Fail # Issue 11496
+method_override7_test/02: Fail # Issue 11496
+method_override8_test/03: Fail # Issue 11496
+setter_override_test/00: Fail # Issue 11496
+setter_override_test/03: Fail # Issue 11496
+setter_override2_test/02: Fail # Issue 11496
+
+compile_time_constant10_test/01: Fail # Issue 5519
+compile_time_constant10_test/02: Fail # Issue 5519
+compile_time_constant_arguments_test/01: Fail # Issue 5519
+compile_time_constant_arguments_test/02: Fail # Issue 5519
+compile_time_constant_arguments_test/03: Fail # Issue 5519
+compile_time_constant_arguments_test/05: Fail # Issue 5519
+compile_time_constant_arguments_test/06: Fail # Issue 5519
+const_constructor_syntax_test/04: Fail # Issue 5519
+const_syntax_test/01: Fail # Issue 5519
+const_syntax_test/02: Fail # Issue 5519
+const_syntax_test/03: Fail # Issue 5519
+const_syntax_test/04: Fail # Issue 5519
+const_syntax_test/05: Fail # Issue 5519
+const_syntax_test/06: Fail # Issue 5519
+const_syntax_test/07: Fail # Issue 5519
+const_syntax_test/08: Fail # Issue 5519
+const_syntax_test/10: Fail # Issue 5519
+constructor_named_arguments_test/01: Fail # Issue 5519
+final_syntax_test/01: Fail # Issue 5519
+final_syntax_test/02: Fail # Issue 5519
+final_syntax_test/03: Fail # Issue 5519
+final_syntax_test/04: Fail # Issue 5519
+getter_no_setter_test/01: Fail # Issue 5519
+named_parameters_aggregated_test/01: Fail # Issue 12802
+named_parameters_aggregated_test/03: Fail # Issue 12813
+not_enough_positional_arguments_test/01: Fail # Issue 12839
+not_enough_positional_arguments_test/02: Fail # Issue 12839
+not_enough_positional_arguments_test/04: Fail # Issue 12839
+not_enough_positional_arguments_test/05: Fail # Issue 12839
+
+metadata_test: Fail # Issue 12762
+const_var_test: Pass, Fail # Issue 12794
+map_literal3_test: Fail # Issue 12794
+class_cycle_negative_test: Fail, OK # Bad test: assumes eager loading.
+interface_cycle_negative_test: Fail, OK # Bad test: assumes eager loading.
+# Common problems with dart2js.  In illegal family, invalid
+# declarations are simply not parsed.  In pseudo kw dart2js
+# chokes on things like typedef(x) => "typedef $x" and alike.
+abstract_syntax_test/01: Fail
+pseudo_kw_test: Fail
+# external keyword is not yet supported by dart2js/dart2dart.
+external_test/*: Skip
+lazy_static3_test: Fail # Issue 12593
+# dart2js frontend doesn't even analyse problematic classes.
+duplicate_implements_test/01: Fail
+duplicate_implements_test/02: Fail
+duplicate_implements_test/03: Fail
+duplicate_implements_test/04: Fail
+method_override4_test: Fail # Issue 12810
+method_override5_test: Fail # Issue 12810
+operator1_negative_test: Fail
+static_final_field_negative_test: Fail
+static_top_level_test/00: Fail
+static_top_level_test/01: Fail
+static_top_level_test/02: Fail
+static_top_level_test/03: Fail
+static_top_level_test/04: Fail
+static_top_level_test/05: Fail
+static_top_level_test/06: Fail
+static_top_level_test/07: Fail
+# Bug in dart2js parser: it happily parses 1is int; variable declaration.
+number_identifier_negative_test: Fail
+# Common with language_dart2js.
+factory_redirection_test/01: Fail # Issue 12753
+factory_redirection_test/02: Crash # Issue 12753
+factory_redirection_test/03: Crash # Issue 12753
+factory_redirection_test/07: Fail # Issue 12753
+factory_redirection_test/09: Fail # Issue 12753
+factory_redirection_test/14: Fail # Issue 10959
+function_type_alias5_test/00: Fail # Issue 12755
+function_type_alias5_test/01: Fail # Issue 12755
+function_type_alias5_test/02: Fail # Issue 12755
+function_type_alias7_test/00: Fail # Issue 12802
+parameter_initializer6_negative_test: Fail # Issue 3502
+# DartVM problem.
+constructor5_test: Fail
+constructor6_test: Fail
+closure_in_initializer_test: Fail
+super_first_constructor_test: Fail
+# Minified mode failures.
+# TODO(antonm): proper support in test framework.
+no_such_method_test: Pass, Fail, OK # Hard codes the name of invoked method ("foo").
+
+new_expression_type_args_test/00: Fail # Wrongly reports compile-time error.
+new_expression_type_args_test/01: Fail # Wrongly reports compile-time error.
+
+get_set_syntax_test/00: Fail # Issue 12806
+get_set_syntax_test/01: Fail # Issue 12806
+get_set_syntax_test/02: Fail # Issue 12806
+get_set_syntax_test/03: Fail # Issue 12806
+get_set_syntax_test/04: Fail # Issue 12806
+
+# Only checked mode reports an error on type assignment
+# problems in compile time constants.
+compile_time_constant_checked_test/02: Fail, OK
+compile_time_constant_checked2_test/01: Fail, OK
+compile_time_constant_checked2_test/02: Fail, OK
+compile_time_constant_checked2_test/03: Fail, OK
+compile_time_constant_checked2_test/04: Fail, OK
+compile_time_constant_checked2_test/05: Fail, OK
+compile_time_constant_checked2_test/06: Fail, OK
+compile_time_constant_checked3_test/01: Fail, OK
+compile_time_constant_checked3_test/02: Fail, OK
+compile_time_constant_checked3_test/03: Fail, OK
+compile_time_constant_checked3_test/04: Fail, OK
+compile_time_constant_checked3_test/05: Fail, OK
+compile_time_constant_checked3_test/06: Fail, OK
+
+positional_parameters_type_test: Fail # Triage this.
+final_is_not_const_test/01: Fail # Issue 12692
+
+[ $compiler == dart2dart && $minified ]
+super_getter_setter_test: Fail # Issue 11065.
+f_bounded_quantification4_test: Fail # Issue 12605.
+f_bounded_quantification5_test: Fail # Issue 12605.
+
+# TODO(tball): Assign proper bug numbers.
+class_literal_test: Fail
+
+import_core_prefix_test: Pass
+prefix22_test: Pass
+invocation_mirror_test: Fail, OK # Issue 12706 (hardcoded names).
+super_call4_test: Fail, OK # hardcoded names.
diff --git a/tests/language/named_parameters_with_object_property_names_test.dart b/tests/language/named_parameters_with_object_property_names_test.dart
index e291bc8..069200b 100644
--- a/tests/language/named_parameters_with_object_property_names_test.dart
+++ b/tests/language/named_parameters_with_object_property_names_test.dart
@@ -12,12 +12,6 @@
 main() {
   // Test properties found on instances of Object in Chrome 15 and Firefox 6.
   test_constructor();
-  test___proto__();
-  test___defineGetter__();
-  test___defineSetter__();
-  test___lookupGetter__();
-  test___lookupSetter__();
-  test___noSuchMethod__();
   test_hasOwnProperty();
   test_isPrototypeOf();
   test_propertyIsEnumerable();
@@ -50,132 +44,6 @@
   Expect.equals(0, globalMethod_constructor(constructor: 0));
 }
 
-// '__proto__' property.
-
-class TestClass___proto__ {
-  method({__proto__}) => __proto__;
-  static staticMethod({__proto__}) => __proto__;
-}
-globalMethod___proto__({__proto__}) => __proto__;
-
-test___proto__() {
-  var obj = new TestClass___proto__();
-
-  Expect.equals(null, obj.method());
-  Expect.equals(0, obj.method(__proto__: 0));
-
-  Expect.equals(null, TestClass___proto__.staticMethod());
-  Expect.equals(0, TestClass___proto__.staticMethod(__proto__: 0));
-
-  Expect.equals(null, globalMethod___proto__());
-  Expect.equals(0, globalMethod___proto__(__proto__: 0));
-}
-
-// '__defineGetter__' property.
-
-class TestClass___defineGetter__ {
-  method({__defineGetter__}) => __defineGetter__;
-  static staticMethod({__defineGetter__}) => __defineGetter__;
-}
-globalMethod___defineGetter__({__defineGetter__}) => __defineGetter__;
-
-test___defineGetter__() {
-  var obj = new TestClass___defineGetter__();
-
-  Expect.equals(null, obj.method());
-  Expect.equals(0, obj.method(__defineGetter__: 0));
-
-  Expect.equals(null, TestClass___defineGetter__.staticMethod());
-  Expect.equals(0, TestClass___defineGetter__.staticMethod(__defineGetter__: 0));
-
-  Expect.equals(null, globalMethod___defineGetter__());
-  Expect.equals(0, globalMethod___defineGetter__(__defineGetter__: 0));
-}
-
-// '__defineSetter__' property.
-
-class TestClass___defineSetter__ {
-  method({__defineSetter__}) => __defineSetter__;
-  static staticMethod({__defineSetter__}) => __defineSetter__;
-}
-globalMethod___defineSetter__({__defineSetter__}) => __defineSetter__;
-
-test___defineSetter__() {
-  var obj = new TestClass___defineSetter__();
-
-  Expect.equals(null, obj.method());
-  Expect.equals(0, obj.method(__defineSetter__: 0));
-
-  Expect.equals(null, TestClass___defineSetter__.staticMethod());
-  Expect.equals(0, TestClass___defineSetter__.staticMethod(__defineSetter__: 0));
-
-  Expect.equals(null, globalMethod___defineSetter__());
-  Expect.equals(0, globalMethod___defineSetter__(__defineSetter__: 0));
-}
-
-// '__lookupGetter__' property.
-
-class TestClass___lookupGetter__ {
-  method({__lookupGetter__}) => __lookupGetter__;
-  static staticMethod({__lookupGetter__}) => __lookupGetter__;
-}
-globalMethod___lookupGetter__({__lookupGetter__}) => __lookupGetter__;
-
-test___lookupGetter__() {
-  var obj = new TestClass___lookupGetter__();
-
-  Expect.equals(null, obj.method());
-  Expect.equals(0, obj.method(__lookupGetter__: 0));
-
-  Expect.equals(null, TestClass___lookupGetter__.staticMethod());
-  Expect.equals(0, TestClass___lookupGetter__.staticMethod(__lookupGetter__: 0));
-
-  Expect.equals(null, globalMethod___lookupGetter__());
-  Expect.equals(0, globalMethod___lookupGetter__(__lookupGetter__: 0));
-}
-
-// '__lookupSetter__' property.
-
-class TestClass___lookupSetter__ {
-  method({__lookupSetter__}) => __lookupSetter__;
-  static staticMethod({__lookupSetter__}) => __lookupSetter__;
-}
-globalMethod___lookupSetter__({__lookupSetter__}) => __lookupSetter__;
-
-test___lookupSetter__() {
-  var obj = new TestClass___lookupSetter__();
-
-  Expect.equals(null, obj.method());
-  Expect.equals(0, obj.method(__lookupSetter__: 0));
-
-  Expect.equals(null, TestClass___lookupSetter__.staticMethod());
-  Expect.equals(0, TestClass___lookupSetter__.staticMethod(__lookupSetter__: 0));
-
-  Expect.equals(null, globalMethod___lookupSetter__());
-  Expect.equals(0, globalMethod___lookupSetter__(__lookupSetter__: 0));
-}
-
-// '__noSuchMethod__' property.
-
-class TestClass___noSuchMethod__ {
-  method({__noSuchMethod__}) => __noSuchMethod__;
-  static staticMethod({__noSuchMethod__}) => __noSuchMethod__;
-}
-globalMethod___noSuchMethod__({__noSuchMethod__}) => __noSuchMethod__;
-
-test___noSuchMethod__() {
-  var obj = new TestClass___noSuchMethod__();
-
-  Expect.equals(null, obj.method());
-  Expect.equals(0, obj.method(__noSuchMethod__: 0));
-
-  Expect.equals(null, TestClass___noSuchMethod__.staticMethod());
-  Expect.equals(0, TestClass___noSuchMethod__.staticMethod(__noSuchMethod__: 0));
-
-  Expect.equals(null, globalMethod___noSuchMethod__());
-  Expect.equals(0, globalMethod___noSuchMethod__(__noSuchMethod__: 0));
-}
-
 // 'hasOwnProperty' property.
 
 class TestClass_hasOwnProperty {
diff --git a/runtime/lib/json_patch.dart b/tests/language/new_prefix_test.dart
similarity index 63%
rename from runtime/lib/json_patch.dart
rename to tests/language/new_prefix_test.dart
index 0b637a1..0988b90 100644
--- a/runtime/lib/json_patch.dart
+++ b/tests/language/new_prefix_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.
 
-// JSON parsing and serialization.
+import 'dart:core' as prefix;
 
-patch parse(String json, [reviver(var key, var value)]) {
-  return _parse(json, reviver);
+main() {
+  return new prefix(); /// 01: static type warning, runtime error
 }
diff --git a/tests/language/no_such_method_empty_selector_test.dart b/tests/language/no_such_method_empty_selector_test.dart
new file mode 100644
index 0000000..dff407c
--- /dev/null
+++ b/tests/language/no_such_method_empty_selector_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  noSuchMethod(_) => 'foo';
+  get hashCode => 42;
+}
+
+// Keep that list empty to make the inferrer infer an empty element
+// type.
+var a = [];
+var b = [new A(), new Object()];
+
+main() {
+  // The following [hashCode] call will create a selector whose
+  // receiver type is empty. This used to make dart2js generate a
+  // [noSuchMethod] handler for [hashCode] on the Object class, which
+  // would override the actual implementation.
+  Expect.throws(() => a[0].hashCode, (e) => e is RangeError);
+
+  // This code calls the [hashCode] method put on the [Object] class,
+  // which used to be a [noSuchMethod] handler method.
+  Expect.isTrue(b[1].hashCode is int);
+
+  // Sanity checks.
+  Expect.equals(42, b[0].hashCode);
+  Expect.equals('foo', b[0].foo());
+
+  // Prevent optimizations on the [b] variable.
+  b.clear();
+}
diff --git a/tests/language/not_enough_positional_arguments_test.dart b/tests/language/not_enough_positional_arguments_test.dart
index a49f864..1070783 100644
--- a/tests/language/not_enough_positional_arguments_test.dart
+++ b/tests/language/not_enough_positional_arguments_test.dart
@@ -5,17 +5,43 @@
 foo(a, [b]) {
 }
 
+bar(a, {b}) {
+}
+
 class A {
-  A(a, [b]);
+  A();
+  A.test(a, [b]);
 }
 
 class B {
   B()
-    : super(b: 1) /// 01: runtime error
+    : super.test(b: 1)  /// 01: runtime error
+  ;
+}
+
+class C extends A {
+  C()
+    : super.test(b: 1)  /// 02: runtime error
+  ;
+}
+
+class D {
+  D();
+  D.test(a, {b});
+}
+
+class E extends D {
+  E()
+    : super.test(b: 1)  /// 05: runtime error
   ;
 }
 
 main() {
-  new B(); /// 01: continued
-  foo(b: 1); /// 02: runtime error
+  new A.test(b: 1);  /// 00: runtime error
+  new B();
+  new C();
+  new D.test(b: 1);  /// 03: runtime error
+  new E();
+  foo(b: 1);  /// 06: runtime error
+  bar(b: 1);  /// 07: runtime error
 }
diff --git a/tests/language/redirecting_factory_malbounded_test.dart b/tests/language/redirecting_factory_malbounded_test.dart
new file mode 100644
index 0000000..4c2ad37
--- /dev/null
+++ b/tests/language/redirecting_factory_malbounded_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Foo<T> extends Bar<T> {
+
+  factory Foo() = Bar;
+
+  Foo.create() : super.create() { }  // Super call required due to issue 5838.
+}
+
+class Bar<T
+            extends num  /// 01: static type warning, dynamic type error
+                       > {
+  factory Bar() {
+    return new Foo<T>.create();
+  }
+
+  Bar.create() { }
+}
+
+main() {
+  new Foo<String>();
+}
diff --git a/tests/language/round_test.dart b/tests/language/round_test.dart
new file mode 100644
index 0000000..e1b3c3e
--- /dev/null
+++ b/tests/language/round_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test of a common rounding bug.
+///
+/// This bug is common in JavaScript implementations because the ECMA-262
+/// specification of JavaScript incorrectly claims:
+///
+///     The value of [:Math.round(x):] is the same as the value of
+///     [:Math.floor(x+0.5):], except when x is 0 or is less than 0 but greater
+///     than or equal to -0.5; for these cases [:Math.round(x):] returns 0, but
+///     [:Math.floor(x+0.5):] returns +0.
+///
+/// However, 0.49999999999999994 + 0.5 is 1 and 9007199254740991 + 0.5 is
+/// 9007199254740992, so you cannot implement Math.round in terms of
+/// Math.floor.
+
+import 'package:expect/expect.dart';
+
+main() {
+  Expect.equals(0, (0.49999999999999994).round());
+  Expect.equals(0, (-0.49999999999999994).round());
+
+  Expect.equals(9007199254740991, (9007199254740991.0).round());
+  Expect.equals(-9007199254740991, (-9007199254740991.0).round());
+}
diff --git a/tests/language/static_final_field2_negative_test.dart b/tests/language/static_final_field2_test.dart
similarity index 84%
rename from tests/language/static_final_field2_negative_test.dart
rename to tests/language/static_final_field2_test.dart
index aef1cef..4e4c188 100644
--- a/tests/language/static_final_field2_negative_test.dart
+++ b/tests/language/static_final_field2_test.dart
@@ -8,5 +8,5 @@
 }
 
 main() {
-  A.x = 2;  // <- reassignment not allowed.
+  A.x = 2;  /// 01: static type warning, runtime error
 }
diff --git a/tests/language/string_optimizations_test.dart b/tests/language/string_optimizations_test.dart
new file mode 100644
index 0000000..1374bb3
--- /dev/null
+++ b/tests/language/string_optimizations_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js's type inferrer, that used to not
+// correclty infer optional named parameters.
+
+import "package:expect/expect.dart";
+import "compiler_annotations.dart";
+
+@DontInline()
+foo({path}) {
+  () => 42;
+  return path.toString();
+}
+
+@DontInline()
+bar({path}) {
+  () => 42;
+  return path;
+}
+
+main() {
+  var a = [foo(path: '42'), foo(), 42, bar(path: '54')];
+  Expect.isTrue(a[1] is String);
+  Expect.throws(() => bar().concat('54'), (e) => e is NoSuchMethodError);
+}
diff --git a/tests/language/switch_int_double_test.dart b/tests/language/switch_int_double_test.dart
index d6e02dd..8ae95e2 100644
--- a/tests/language/switch_int_double_test.dart
+++ b/tests/language/switch_int_double_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.
 
-// Test that double literals with no fractional part is not treated as having
-// static type int.
+// Test reporting a compile-time error if case expressions do not all have
+// the same type.
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/syntax_test.dart b/tests/language/syntax_test.dart
index bc2bfc2..11aee70 100644
--- a/tests/language/syntax_test.dart
+++ b/tests/language/syntax_test.dart
@@ -1,7 +1,6 @@
 // Copyright (c) 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.
-// VMOptions=--compile_all
 
 class SyntaxTest {
   // "this" cannot be used as a field name.
@@ -230,6 +229,7 @@
     void v; /// 60: compile-time error
     void v = null; /// 61: compile-time error
     print(null is void); /// 62: compile-time error
+    new A();
     new B();
 
     new Bad();
diff --git a/tests/language/allocation_sinking_vm_test.dart b/tests/language/vm/allocation_sinking_vm_test.dart
similarity index 100%
rename from tests/language/allocation_sinking_vm_test.dart
rename to tests/language/vm/allocation_sinking_vm_test.dart
diff --git a/tests/language/deopt_hoisted_smi_check_vm_test.dart b/tests/language/vm/deopt_hoisted_smi_check_vm_test.dart
similarity index 100%
rename from tests/language/deopt_hoisted_smi_check_vm_test.dart
rename to tests/language/vm/deopt_hoisted_smi_check_vm_test.dart
diff --git a/tests/language/if_conversion_vm_test.dart b/tests/language/vm/if_conversion_vm_test.dart
similarity index 100%
rename from tests/language/if_conversion_vm_test.dart
rename to tests/language/vm/if_conversion_vm_test.dart
diff --git a/tests/language/issue11087_vm_test.dart b/tests/language/vm/issue11087_vm_test.dart
similarity index 100%
rename from tests/language/issue11087_vm_test.dart
rename to tests/language/vm/issue11087_vm_test.dart
diff --git a/tests/language/load_to_load_forwarding_vm_test.dart b/tests/language/vm/load_to_load_forwarding_vm_test.dart
similarity index 100%
rename from tests/language/load_to_load_forwarding_vm_test.dart
rename to tests/language/vm/load_to_load_forwarding_vm_test.dart
diff --git a/tests/language/math_vm_test.dart b/tests/language/vm/math_vm_test.dart
similarity index 100%
rename from tests/language/math_vm_test.dart
rename to tests/language/vm/math_vm_test.dart
diff --git a/tests/language/no_such_method_error_message_vm_test.dart b/tests/language/vm/no_such_method_error_message_vm_test.dart
similarity index 100%
rename from tests/language/no_such_method_error_message_vm_test.dart
rename to tests/language/vm/no_such_method_error_message_vm_test.dart
diff --git a/tests/language/null_hashcode_optimized_vm_test.dart b/tests/language/vm/null_hashcode_optimized_vm_test.dart
similarity index 100%
rename from tests/language/null_hashcode_optimized_vm_test.dart
rename to tests/language/vm/null_hashcode_optimized_vm_test.dart
diff --git a/tests/language/vm/reflect_core_vm_test.dart b/tests/language/vm/reflect_core_vm_test.dart
new file mode 100644
index 0000000..d6e52f1
--- /dev/null
+++ b/tests/language/vm/reflect_core_vm_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test reflection of private functions in core classes.
+
+import "package:expect/expect.dart";
+import "dart:mirrors";
+
+main() {
+  var s = "string";
+  var im = reflect(s);
+  try {
+    im.invoke(const Symbol("_setAt"), [0, 65]);
+    Expect.isTrue(false);  // Unreachable.
+  } catch (e) {
+    Expect.equals(true, e is NoSuchMethodError);
+  }
+}
+
diff --git a/tests/language/store_to_load_forwarding_phis_vm_test.dart b/tests/language/vm/store_to_load_forwarding_phis_vm_test.dart
similarity index 100%
rename from tests/language/store_to_load_forwarding_phis_vm_test.dart
rename to tests/language/vm/store_to_load_forwarding_phis_vm_test.dart
diff --git a/tests/language/type_cast_vm_test.dart b/tests/language/vm/type_cast_vm_test.dart
similarity index 100%
rename from tests/language/type_cast_vm_test.dart
rename to tests/language/vm/type_cast_vm_test.dart
diff --git a/tests/language/type_vm_test.dart b/tests/language/vm/type_vm_test.dart
similarity index 100%
rename from tests/language/type_vm_test.dart
rename to tests/language/vm/type_vm_test.dart
diff --git a/tests/lib/analyzer/analyze_tests.status b/tests/lib/analyzer/analyze_tests.status
index b1e51479..a398c55 100644
--- a/tests/lib/analyzer/analyze_tests.status
+++ b/tests/lib/analyzer/analyze_tests.status
@@ -23,7 +23,6 @@
 standalone/io/stdout_bad_argument_test: fail
 standalone/io/skipping_dart2js_compilations_test: fail
 standalone/io/dependency_graph_test: fail # http/dartbug.com/12449
-standalone/io/url_encoding_test: fail
 standalone/io/web_socket_protocol_processor_test: fail
 standalone/io/test_runner_test: fail
 standalone/package/invalid_uri_test: fail
@@ -52,7 +51,6 @@
 standalone/io/stdout_bad_argument_test: fail
 standalone/io/skipping_dart2js_compilations_test: fail
 standalone/io/dependency_graph_test: fail # http/dartbug.com/12449
-standalone/io/url_encoding_test: fail
 standalone/io/web_socket_protocol_processor_test: fail
 standalone/io/test_runner_test: fail
 standalone/package/invalid_uri_test: fail
diff --git a/tests/lib/async/stream_controller_async_test.dart b/tests/lib/async/stream_controller_async_test.dart
index 0cae4fa..2bfb4f0 100644
--- a/tests/lib/async/stream_controller_async_test.dart
+++ b/tests/lib/async/stream_controller_async_test.dart
@@ -246,7 +246,7 @@
   test("elementAt 2", () {
     StreamController c = new StreamController();
     Future f = c.stream.elementAt(20);
-    f.catchError(expectAsync1((error) { Expect.isTrue(error is StateError); }));
+    f.catchError(expectAsync1((error) { Expect.isTrue(error is RangeError); }));
     sentEvents.replay(c);
   });
 
diff --git a/tests/lib/convert/codec2_test.dart b/tests/lib/convert/codec2_test.dart
index fce07ea..e8fa875 100644
--- a/tests/lib/convert/codec2_test.dart
+++ b/tests/lib/convert/codec2_test.dart
@@ -22,12 +22,12 @@
 
   // Test that the reviver is passed to the decoder.
   var decoded = JSON.decode('{"p": 5}', reviver: (k, v) {
-    if (k == "") return v;
+    if (k == null) return v;
     return v * 2;
   });
   Expect.equals(10, decoded["p"]);
   var jsonWithReviver = new JsonCodec.withReviver((k, v) {
-    if (k == "") return v;
+    if (k == null) return v;
     return v * 2;
   });
   decoded = jsonWithReviver.decode('{"p": 5}');
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index b90b26e..54ff120 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -20,11 +20,14 @@
 mirrors/method_mirror_name_test: Fail # Issue 6335
 mirrors/method_mirror_properties_test: Fail # Issue 11861
 mirrors/method_mirror_returntype_test : Fail # Issue 11928
+mirrors/method_mirror_source_test : Fail # Issue 6490
 mirrors/mirrors_test: Fail # TODO(ahe): I'm working on fixing this.
 mirrors/null_test : Fail # Issue 12129
+mirrors/parameter_test: Fail # Issue 6490
 mirrors/library_metadata_test: Fail # Issue 10905
 mirrors/library_uri_io_test: Skip # Not intended for dart2js as it uses dart:io.
 mirrors/reflected_type_test: Fail # Issue 12607
+mirrors/typedef_metadata_test: Fail # Issue 12785
 mirrors/unnamed_library_test: Fail # Issue 10580
 async/run_async3_test: Fail # _enqueueImmediate runs after Timer. http://dartbug.com/9002
 async/run_async4_test: Pass, Fail # no global exception handler in isolates. http://dartbug.com/9012
@@ -83,6 +86,7 @@
 timer_test: Pass, Fail
 convert/chunked_conversion_utf88_test: Pass, Timeout  # Issue 12029
 convert/streamed_conversion_utf8_encode_test: Pass, Timeout  # Issue 12029
+convert/streamed_conversion_utf8_decode_test: Pass, Slow  # Issue 12029
 
 [ $runtime == ie9 ]
 # IE9 doesn't support typed arrays.
@@ -91,6 +95,8 @@
 convert/streamed_conversion_utf8_encode_test: Pass, Timeout  # Issue 12029
 convert/streamed_conversion_json_utf8_decode_test: Pass, Timeout # Issue 12029
 async/deferred/deferred_api_test: Pass, Timeout # Issue 12029
+async/run_zoned6_test/01: fail # http://dartbug.com/12817
+
 
 [ $runtime == opera ]
 async/multiple_timer_test: Pass, Fail
@@ -128,3 +134,7 @@
 
 [ $arch == simarm ]
 convert/chunked_conversion_utf88_test: Pass, Slow # Issue 12644.
+
+[ $compiler == none && $runtime == drt ]
+run_zoned6_test/01: fail # Issue 12756.
+run_zoned9_test/01: fail # Issue 12756.
diff --git a/tests/lib/mirrors/method_mirror_source_test.dart b/tests/lib/mirrors/method_mirror_source_test.dart
new file mode 100644
index 0000000..fcbc7c6
--- /dev/null
+++ b/tests/lib/mirrors/method_mirror_source_test.dart
@@ -0,0 +1,98 @@
+// 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:mirrors";
+
+import "package:expect/expect.dart";
+
+expectSource(Mirror mirror, String source) {
+  if (mirror is ClosureMirror) {
+    mirror = mirror.function;
+  }
+  Expect.isTrue(mirror is MethodMirror);
+  Expect.equals(mirror.source, source);
+}
+
+foo1() {}
+doSomething(e) => e;
+
+int get x => 42;
+set x(value) { }
+
+class S {}
+
+class C extends S {
+
+  var _x;
+  var _y;
+
+  C(this._x, y)
+    : _y = y,
+      super();
+
+  factory C.other(num z) {}
+  factory C.other2() {}
+  factory C.other3() = C.other2;
+
+  static dynamic foo() {
+    // Happy foo.
+  }
+
+  // Some comment.
+
+  void bar() { /* Not so happy bar. */ }
+
+  num get someX =>
+    181;
+
+  set someX(v) {
+    // Discard this one.
+  }
+}
+    
+
+main() {
+  // Top-level members
+  LibraryMirror lib = reflectClass(C).owner;
+  expectSource(lib.members[const Symbol("foo1")],
+      "foo1() {}");
+  expectSource(lib.members[const Symbol("x")],
+      "int get x => 42;");
+  expectSource(lib.members[const Symbol("x=")],
+      "set x(value) { }");
+
+  // Class members
+  ClassMirror cm = reflectClass(C);
+  expectSource(cm.members[const Symbol("foo")],
+      "static dynamic foo() {\n"
+      "    // Happy foo.\n"
+      "  }");
+  expectSource(cm.members[const Symbol("bar")],
+      "void bar() { /* Not so happy bar. */ }");
+  expectSource(cm.members[const Symbol("someX")],
+      "num get someX =>\n"
+      "    181;");
+  expectSource(cm.members[const Symbol("someX=")],
+      "set someX(v) {\n"
+      "    // Discard this one.\n"
+      "  }");
+  expectSource(cm.constructors[const Symbol("C")],
+      "C(this._x, y)\n"
+      "    : _y = y,\n"
+      "      super();");
+  expectSource(cm.constructors[const Symbol("C.other")],
+      "factory C.other(num z) {}");
+  expectSource(cm.constructors[const Symbol("C.other3")],
+      "factory C.other3() = C.other2;");
+
+  // Closures
+  expectSource(reflect((){}), "(){}");
+  expectSource(reflect((x,y,z) { return x*y*z; }), "(x,y,z) { return x*y*z; }");
+  expectSource(reflect((e) => doSomething(e)), "(e) => doSomething(e)");
+
+  namedClosure(x,y,z) => 1;
+  var a = () {};
+  expectSource(reflect(namedClosure), "namedClosure(x,y,z) => 1;");
+  expectSource(reflect(a), "() {}");
+}
diff --git a/tests/lib/mirrors/parameter_dart2js_test.dart b/tests/lib/mirrors/parameter_dart2js_test.dart
new file mode 100644
index 0000000..aa5cdee
--- /dev/null
+++ b/tests/lib/mirrors/parameter_dart2js_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test of [ParameterMirror].
+library test.parameter_test;
+
+@MirrorsUsed(targets: 'test.parameter_test', override: '*')
+import 'dart:mirrors';
+
+import 'stringify.dart';
+
+class B {
+  B();
+  B.foo(int x);
+  B.bar(int z, x);
+}
+
+main() {
+  var constructors = reflectClass(B).constructors;
+
+  expect('{B: Method(s(B) in s(B), constructor), '
+         'B.bar: Method(s(B.bar) in s(B), constructor), '
+         'B.foo: Method(s(B.foo) in s(B), constructor)}',
+         constructors);
+
+  var unnamedConstructor = constructors[new Symbol('B')];
+
+  expect('[]', unnamedConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+         unnamedConstructor.returnType);
+
+  var fooConstructor = constructors[new Symbol('B.foo')];
+  expect('[Parameter(s(x) in s(B.foo),'
+         ' type = Class(s(int) in s(dart.core), top-level))]',
+         fooConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+         fooConstructor.returnType);
+
+  var barConstructor = constructors[new Symbol('B.bar')];
+  expect('[Parameter(s(z) in s(B.bar),'
+         ' type = Class(s(int) in s(dart.core), top-level)), '
+         'Parameter(s(x) in s(B.bar),'
+         ' type = Type(s(dynamic), top-level))]',
+         barConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+         barConstructor.returnType);
+
+  print(constructors);
+}
diff --git a/tests/lib/mirrors/parameter_test.dart b/tests/lib/mirrors/parameter_test.dart
index aa5cdee..7c538a7 100644
--- a/tests/lib/mirrors/parameter_test.dart
+++ b/tests/lib/mirrors/parameter_test.dart
@@ -8,36 +8,55 @@
 @MirrorsUsed(targets: 'test.parameter_test', override: '*')
 import 'dart:mirrors';
 
+import 'package:expect/expect.dart';
 import 'stringify.dart';
 
 class B {
   B();
   B.foo(int x);
   B.bar(int z, x);
+
+  // TODO(6490): Currently only supported by the VM.
+  B.baz(final int x, int y, final int z);
+  B.qux(int x, [int y= 3 + 1]);
+  B.quux(int x, {String str: "foo"});
+  B.corge({int x: 3 * 17, String str: "bar"});
+
+  var _x;
+  get x =>  _x;
+  set x(final value) { _x = value; }
+
+  grault([int x]);
+  garply({int y});
+  waldo(int z);
 }
 
 main() {
-  var constructors = reflectClass(B).constructors;
+  ClassMirror cm = reflectClass(B);
+  Map<Symbol, MethodMirror> constructors = cm.constructors;
 
-  expect('{B: Method(s(B) in s(B), constructor), '
-         'B.bar: Method(s(B.bar) in s(B), constructor), '
-         'B.foo: Method(s(B.foo) in s(B), constructor)}',
-         constructors);
+  List<Symbol> constructorKeys = [
+      const Symbol('B'), const Symbol('B.bar'), const Symbol('B.baz'),
+      const Symbol('B.foo'), const Symbol('B.quux'), const Symbol('B.qux'),
+      const Symbol('B.corge')];
+  Expect.setEquals(constructorKeys, constructors.keys);
 
-  var unnamedConstructor = constructors[new Symbol('B')];
-
+  MethodMirror unnamedConstructor = constructors[const Symbol('B')];
+  expect('Method(s(B) in s(B), constructor)', unnamedConstructor);
   expect('[]', unnamedConstructor.parameters);
   expect('Class(s(B) in s(test.parameter_test), top-level)',
          unnamedConstructor.returnType);
 
-  var fooConstructor = constructors[new Symbol('B.foo')];
+  MethodMirror fooConstructor = constructors[const Symbol('B.foo')];
+  expect('Method(s(B.foo) in s(B), constructor)', fooConstructor);
   expect('[Parameter(s(x) in s(B.foo),'
          ' type = Class(s(int) in s(dart.core), top-level))]',
          fooConstructor.parameters);
   expect('Class(s(B) in s(test.parameter_test), top-level)',
          fooConstructor.returnType);
 
-  var barConstructor = constructors[new Symbol('B.bar')];
+  MethodMirror barConstructor = constructors[const Symbol('B.bar')];
+  expect('Method(s(B.bar) in s(B), constructor)', barConstructor);
   expect('[Parameter(s(z) in s(B.bar),'
          ' type = Class(s(int) in s(dart.core), top-level)), '
          'Parameter(s(x) in s(B.bar),'
@@ -46,5 +65,80 @@
   expect('Class(s(B) in s(test.parameter_test), top-level)',
          barConstructor.returnType);
 
-  print(constructors);
+  MethodMirror bazConstructor = constructors[const Symbol('B.baz')];
+  expect('Method(s(B.baz) in s(B), constructor)', bazConstructor);
+  expect('[Parameter(s(x) in s(B.baz), final,'
+         ' type = Class(s(int) in s(dart.core), top-level)), '
+         'Parameter(s(y) in s(B.baz),'
+         ' type = Class(s(int) in s(dart.core), top-level)), '
+         'Parameter(s(z) in s(B.baz), final,'
+         ' type = Class(s(int) in s(dart.core), top-level))]',
+         bazConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+         bazConstructor.returnType);
+
+  MethodMirror quxConstructor = constructors[const Symbol('B.qux')];
+  expect('Method(s(B.qux) in s(B), constructor)', quxConstructor);
+  expect('[Parameter(s(x) in s(B.qux),'
+         ' type = Class(s(int) in s(dart.core), top-level)), '
+         'Parameter(s(y) in s(B.qux), optional,'
+         ' value = Instance(value = 4),'
+         ' type = Class(s(int) in s(dart.core), top-level))]',
+         quxConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+         quxConstructor.returnType);
+
+  MethodMirror quuxConstructor = constructors[const Symbol('B.quux')];
+  expect('Method(s(B.quux) in s(B), constructor)', quuxConstructor);
+  expect('[Parameter(s(x) in s(B.quux),'
+         ' type = Class(s(int) in s(dart.core), top-level)), '
+         'Parameter(s(str) in s(B.quux), optional, named,'
+         ' value = Instance(value = foo),'
+         ' type = Class(s(String) in s(dart.core), top-level))]',
+         quuxConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+         quuxConstructor.returnType);
+
+  MethodMirror corgeConstructor = constructors[const Symbol('B.corge')];
+  expect('Method(s(B.corge) in s(B), constructor)', corgeConstructor);
+  expect('[Parameter(s(x) in s(B.corge), optional, named,'
+         ' value = Instance(value = 51),'
+         ' type = Class(s(int) in s(dart.core), top-level)), '
+         'Parameter(s(str) in s(B.corge), optional, named,'
+         ' value = Instance(value = bar),'
+         ' type = Class(s(String) in s(dart.core), top-level))]',
+         corgeConstructor.parameters);
+  expect('Class(s(B) in s(test.parameter_test), top-level)',
+         corgeConstructor.returnType);
+
+  MethodMirror xGetter = cm.getters[const Symbol('x')];
+  expect('Method(s(x) in s(B), getter)', xGetter);
+  expect('[]', xGetter.parameters);
+
+  MethodMirror xSetter = cm.setters[const Symbol('x=')];
+  expect('Method(s(x=) in s(B), setter)', xSetter);
+  expect('[Parameter(s(value) in s(x=), final,'
+         ' type = Type(s(dynamic), top-level))]',
+         xSetter.parameters);
+
+  MethodMirror grault = cm.members[const Symbol("grault")];
+  expect('Method(s(grault) in s(B))', grault);
+  expect('[Parameter(s(x) in s(grault), optional,'
+         ' type = Class(s(int) in s(dart.core), top-level))]',
+         grault.parameters);
+  expect('Instance(value = <null>)', grault.parameters[0].defaultValue);
+
+  MethodMirror garply = cm.members[const Symbol("garply")];
+  expect('Method(s(garply) in s(B))', garply);
+  expect('[Parameter(s(y) in s(garply), optional, named,'
+         ' type = Class(s(int) in s(dart.core), top-level))]',
+         garply.parameters);
+  expect('Instance(value = <null>)', garply.parameters[0].defaultValue);
+
+  MethodMirror waldo = cm.members[const Symbol("waldo")];
+  expect('Method(s(waldo) in s(B))', waldo);
+  expect('[Parameter(s(z) in s(waldo),' 
+         ' type = Class(s(int) in s(dart.core), top-level))]',
+         waldo.parameters);
+  expect('<null>', waldo.parameters[0].defaultValue);
 }
diff --git a/tests/lib/mirrors/stringify.dart b/tests/lib/mirrors/stringify.dart
index 9778772..ddb0668 100644
--- a/tests/lib/mirrors/stringify.dart
+++ b/tests/lib/mirrors/stringify.dart
@@ -37,6 +37,14 @@
   return '[$buffer]';
 }
 
+stringifyInstance(InstanceMirror instance) {
+  var buffer = new StringBuffer();
+  if (instance.hasReflectee) {
+    buffer.write('value = ${stringify(instance.reflectee)}');
+  }
+  return 'Instance(${buffer})';
+}
+
 stringifySymbol(Symbol symbol) => 's(${MirrorSystem.getName(symbol)})';
 
 writeDeclarationOn(DeclarationMirror mirror, StringBuffer buffer) {
@@ -66,11 +74,10 @@
   writeVariableOn(parameter, buffer);
   if (parameter.isOptional) buffer.write(', optional');
   if (parameter.isNamed) buffer.write(', named');
-  // TODO(6490,12430): Add this check as soon as it's properly implemented in
-  // the VM and dart2js.
-  // if (parameter.hasDefaultValue) {
-  //  buffer.write(', value = ${stringify(parameter.defaultValue)}');
-  // }
+  // TODO(6490): dart2js always returns false for hasDefaultValue.
+  if (parameter.hasDefaultValue) {
+    buffer.write(', value = ${stringify(parameter.defaultValue)}');
+  }
   // TODO(ahe): Move to writeVariableOn.
   buffer.write(', type = ${stringify(parameter.type)}');
   return 'Parameter($buffer)';
@@ -101,9 +108,12 @@
 stringify(value) {
   if (value is Map) return stringifyMap(value);
   if (value is Iterable) return stringifyIterable(value);
+  if (value is InstanceMirror) return stringifyInstance(value);
   if (value is ParameterMirror) return stringifyParameter(value);
   if (value is VariableMirror) return stringifyVariable(value);
   if (value is MethodMirror) return stringifyMethod(value);
+  if (value is num) return value.toString();
+  if (value is String) return value;
   if (value is Symbol) return stringifySymbol(value);
   if (value is ClassMirror) return stringifyClass(value);
   if (value is TypeMirror) return stringifyType(value);
diff --git a/tests/lib/mirrors/typedef_metadata_test.dart b/tests/lib/mirrors/typedef_metadata_test.dart
new file mode 100644
index 0000000..e07339a
--- /dev/null
+++ b/tests/lib/mirrors/typedef_metadata_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@string @symbol
+library test.typedef_metadata_test;
+
+import 'dart:mirrors';
+
+import 'metadata_test.dart';
+
+class S {}
+class M {}
+@symbol
+typedef MA = S with M;
+
+@string
+typedef bool Predicate(Object o);
+
+main() {
+  checkMetadata(reflectClass(MA), [symbol]);
+  checkMetadata(reflectClass(Predicate), [string]);
+}
diff --git a/tests/standalone/debugger/debug_lib.dart b/tests/standalone/debugger/debug_lib.dart
index 0377ae9..66030d9 100644
--- a/tests/standalone/debugger/debug_lib.dart
+++ b/tests/standalone/debugger/debug_lib.dart
@@ -10,7 +10,6 @@
 import "dart:convert";
 import "dart:io";
 import "dart:math";
-import "dart:utf";
 import "dart:json" as JSON;
 
 // Whether or not to print the debugger wire messages on the console.
diff --git a/tests/standalone/io/http_cross_process_test.dart b/tests/standalone/io/http_cross_process_test.dart
new file mode 100644
index 0000000..08329a9
--- /dev/null
+++ b/tests/standalone/io/http_cross_process_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'dart:io';
+
+const int NUM_SERVERS = 10;
+
+void main() {
+  var args = new Options().arguments;
+  if (args.isEmpty) {
+    for (int i = 0; i < NUM_SERVERS; ++i) {
+      makeServer().then((server) {
+        runClientProcess(server.port).then((_) => server.close());
+      });
+    }
+  } else if (args[0] == '--client') {
+    int port = int.parse(args[1]);
+    runClient(port);
+  } else {
+    Expect.fail('Unknown arguments to http_cross_process_test.dart');
+  }
+}
+
+Future makeServer() {
+  return HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
+    server.listen((request) {
+      request.pipe(request.response);
+    });
+    return server;
+  });
+}
+
+Future runClientProcess(int port) {
+  return Process.run(Platform.executable,
+                     []..addAll(Platform.executableArguments)
+                       ..add(Platform.script)
+                       ..add('--client')
+                       ..add(port.toString())).then((ProcessResult result) {
+    if (result.exitCode != 0 || !result.stdout.contains('SUCCESS')) {
+      print("Client failed, exit code ${result.exitCode}");
+      print("  stdout:");
+      print(result.stdout);
+      print("  stderr:");
+      print(result.stderr);
+      Expect.fail('Client subprocess exit code: ${result.exitCode}');
+    }
+  });
+}
+
+runClient(int port) {
+  var client = new HttpClient();
+  client.get('127.0.0.1', port, "/")
+      .then((request) => request.close())
+      .then((response) => response.listen((data) {},
+                                          onDone: () => print('SUCCESS')));
+}
diff --git a/tests/standalone/io/http_detach_socket_test.dart b/tests/standalone/io/http_detach_socket_test.dart
index 1ced3d8..6b38de2 100644
--- a/tests/standalone/io/http_detach_socket_test.dart
+++ b/tests/standalone/io/http_detach_socket_test.dart
@@ -78,12 +78,15 @@
       socket.listen(
         (data) => body.write(new String.fromCharCodes(data)),
         onDone: () {
-          Expect.equals("GET / HTTP/1.1\r\n"
-                        "accept-encoding: gzip\r\n"
-                        "content-length: 0\r\n"
-                        "host: 127.0.0.1:${server.port}\r\n\r\n"
-                        "Some data",
-                        body.toString());
+          List<String> lines = body.toString().split("\r\n");
+          Expect.equals(6, lines.length);
+          Expect.equals("GET / HTTP/1.1", lines[0]);
+          Expect.equals("", lines[4]);
+          Expect.equals("Some data", lines[5]);
+          lines.sort();  // Lines 1-3 becomes 3-5 in a fixed order.
+          Expect.equals("accept-encoding: gzip", lines[3]);
+          Expect.equals("content-length: 0", lines[4]);
+          Expect.equals("host: 127.0.0.1:${server.port}", lines[5]);
           socket.close();
         });
       server.close();
diff --git a/tests/standalone/io/raw_socket_cross_process_test.dart b/tests/standalone/io/raw_socket_cross_process_test.dart
new file mode 100644
index 0000000..188d9d3
--- /dev/null
+++ b/tests/standalone/io/raw_socket_cross_process_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'dart:io';
+
+const int NUM_SERVERS = 10;
+
+void main() {
+  var args = new Options().arguments;
+  if (args.isEmpty) {
+    for (int i = 0; i < NUM_SERVERS; ++i) {
+      makeServer().then((server) {
+        runClientProcess(server.port).then((_) => server.close());
+      });
+    }
+  } else if (args[0] == '--client') {
+    int port = int.parse(args[1]);
+    runClient(port);
+  } else {
+    Expect.fail('Unknown arguments to raw_socket_cross_process_test.dart');
+  }
+}
+
+Future makeServer() {
+  return RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
+    server.listen((connection) {
+      connection.writeEventsEnabled = false;
+      connection.listen((event) {
+        switch(event) {
+          case RawSocketEvent.READ:
+            Expect.fail("No read event expected");
+            break;
+          case RawSocketEvent.READ_CLOSED:
+            connection.shutdown(SocketDirection.SEND);
+            break;
+          case RawSocketEvent.WRITE:
+            Expect.fail("No write event expected");
+            break;
+        }
+      });
+    });
+    return server;
+  });
+}
+
+Future runClientProcess(int port) {
+  return Process.run(Platform.executable,
+                     []..addAll(Platform.executableArguments)
+                       ..add(Platform.script)
+                       ..add('--client')
+                       ..add(port.toString())).then((ProcessResult result) {
+    if (result.exitCode != 0 || !result.stdout.contains('SUCCESS')) {
+      print("Client failed, exit code ${result.exitCode}");
+      print("  stdout:");
+      print(result.stdout);
+      print("  stderr:");
+      print(result.stderr);
+      Expect.fail('Client subprocess exit code: ${result.exitCode}');
+    }
+  });
+}
+
+runClient(int port) {
+  RawSocket.connect(InternetAddress.LOOPBACK_IP_V4, port).then((connection) {
+    connection.listen((_) { }, onDone: () => print('SUCCESS'));
+    connection.shutdown(SocketDirection.SEND);
+  });
+}
diff --git a/tests/standalone/io/secure_builtin_roots_database_test.dart b/tests/standalone/io/secure_builtin_roots_database_test.dart
deleted file mode 100644
index 7b0893e..0000000
--- a/tests/standalone/io/secure_builtin_roots_database_test.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "package:expect/expect.dart";
-import "package:path/path.dart";
-import "dart:io";
-import "dart:isolate";
-import "dart:async";
-
-void testGoogleUrl() {
-  ReceivePort keepAlive = new ReceivePort();
-  HttpClient client = new HttpClient();
-  client.getUrl(Uri.parse('https://www.google.com'))
-      .then((request) => request.close())
-      .then((response)=> response.last)
-      .then((_) {
-        client.close();
-        keepAlive.close();
-      });
-}
-
-void InitializeSSL() {
-  // If the built-in root certificates aren't loaded, the connection
-  // should signal an error.  Even when an external database is loaded,
-  // they should not be loaded.
-  var certificateDatabase = join(dirname(Platform.script), 'pkcert');
-  SecureSocket.initialize(database: certificateDatabase,
-                          password: 'dartdart',
-                          useBuiltinRoots: true);
-}
-
-void main() {
-  InitializeSSL();
-  testGoogleUrl();
-}
diff --git a/tests/standalone/io/secure_builtin_roots_test.dart b/tests/standalone/io/secure_builtin_roots_test.dart
index 32609a8..be0a467 100644
--- a/tests/standalone/io/secure_builtin_roots_test.dart
+++ b/tests/standalone/io/secure_builtin_roots_test.dart
@@ -3,29 +3,87 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+import "package:path/path.dart";
 import "dart:io";
 import "dart:isolate";
 import "dart:async";
 
-void testGoogleUrl() {
-  ReceivePort keepAlive = new ReceivePort();
-  HttpClient client = new HttpClient();
-  client.getUrl(Uri.parse('https://www.google.com'))
-      .then((request) => request.close())
-      .then((response) => response.last)
-      .then((_) {
-        client.close();
-        keepAlive.close();
-      });
-}
-
-void InitializeSSL() {
-  // If the built-in root certificates aren't loaded, the connection
-  // should signal an error.
-  SecureSocket.initialize(useBuiltinRoots: true);
-}
-
 void main() {
-  InitializeSSL();
-  testGoogleUrl();
+  var args = new Options().arguments;
+  if (!args.contains('--child')) {
+    runAllTestsInChildProcesses();
+  } else {
+    InitializeSSL(useDatabase: args.contains('--database'),
+                  useBuiltinRoots: args.contains('--builtin-roots'));
+    testGoogleUrl(args.contains('--builtin-roots'));
+  }
 }
+
+void InitializeSSL({bool useDatabase, bool useBuiltinRoots}) {
+  // If the built-in root certificates aren't loaded, the connection
+  // should signal an error.  Even when an external database is loaded,
+  // they should not be loaded.
+  if (useDatabase) {
+    var certificateDatabase = join(dirname(Platform.script), 'pkcert');
+    SecureSocket.initialize(database: certificateDatabase,
+                            password: 'dartdart',
+                            useBuiltinRoots: useBuiltinRoots);
+  } else {
+    SecureSocket.initialize(useBuiltinRoots: useBuiltinRoots);
+  }
+}
+
+void testGoogleUrl(bool expectSuccess) {
+  // We need to use an external server that is backed by a
+  // built-in root certificate authority.
+
+  // First, check if the lookup fails.  If not then run the test.
+  InternetAddress.lookup('www.google.com').then((_) {
+    HttpClient client = new HttpClient();
+    client.getUrl(Uri.parse('https://www.google.com'))
+      .then((request) => request.close())
+      .then((response) {
+        Expect.isTrue(expectSuccess, "Unexpected successful connection");
+        print('SUCCESS');
+        return response.last;
+      })
+      .catchError((error) {
+        // Allow SocketExceptions if www.google.com is unreachable or down.
+        Expect.isTrue((!expectSuccess && error is HandshakeException) ||
+                      error is SocketException);
+        print('SUCCESS');
+      })
+      .whenComplete(client.close);
+  },
+  onError: (e) {
+    // Lookup failed.
+    Expect.isTrue(e is SocketException);
+    print('SUCCESS');
+  });
+}
+
+void runAllTestsInChildProcesses() {
+  Future runChild(List<String> scriptArguments) {
+    return Process.run(Platform.executable,
+                       []..addAll(Platform.executableArguments)
+                         ..add(Platform.script)
+                         ..addAll(scriptArguments))
+    .then((ProcessResult result) {
+      if (result.exitCode != 0 || !result.stdout.contains('SUCCESS')) {
+        print("Client failed");
+        print("  stdout:");
+        print(result.stdout);
+        print("  stderr:");
+        print(result.stderr);
+        Expect.fail('Client subprocess exit code: ${result.exitCode}');
+      }
+    });
+  }
+
+  ReceivePort keepAlive = new ReceivePort();
+  Future.wait([runChild(['--child']),
+               runChild(['--child', '--database']),
+               runChild(['--child', '--builtin-roots']),
+               runChild(['--child', '--builtin-roots', '--database'])])
+      .then((_) => keepAlive.close());
+  }
diff --git a/tests/standalone/io/secure_no_builtin_roots_database_test.dart b/tests/standalone/io/secure_no_builtin_roots_database_test.dart
deleted file mode 100644
index 7f1276b..0000000
--- a/tests/standalone/io/secure_no_builtin_roots_database_test.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "package:expect/expect.dart";
-import "package:path/path.dart";
-import "dart:io";
-import "dart:isolate";
-import "dart:async";
-
-void testGoogleUrl() {
-  // We need to use an external server here because it is backed by a
-  // built-in root certificate authority.
-  InternetAddress.lookup('www.google.com').then((_) {
-    ReceivePort keepAlive = new ReceivePort();
-    HttpClient client = new HttpClient();
-    client.getUrl(Uri.parse('https://www.google.com'))
-        .then((request) => request.close())
-        .then((response) => Expect.fail("Unexpected successful connection"))
-        .catchError((error) {
-          Expect.isTrue(error is HandshakeException);
-          keepAlive.close();
-          client.close();
-        });
-  },
-  onError: (e) {
-    Expect.isTrue(e is SocketException);
-  });
-}
-
-void InitializeSSL() {
-  // If the built-in root certificates aren't loaded, the connection
-  // should signal an error.  Even when an external database is loaded,
-  // they should not be loaded.
-  var certificateDatabase = join(dirname(Platform.script), 'pkcert');
-  SecureSocket.initialize(database: certificateDatabase,
-                          password: 'dartdart',
-                          useBuiltinRoots: false);
-}
-
-void main() {
-  InitializeSSL();
-  testGoogleUrl();
-}
diff --git a/tests/standalone/io/secure_no_builtin_roots_test.dart b/tests/standalone/io/secure_no_builtin_roots_test.dart
deleted file mode 100644
index 49026b4..0000000
--- a/tests/standalone/io/secure_no_builtin_roots_test.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "package:expect/expect.dart";
-import "dart:io";
-import "dart:isolate";
-import "dart:async";
-
-void testGoogleUrl() {
-  // We need to use an external server here because it is backed by a
-  // built-in root certificate authority.
-  InternetAddress.lookup('www.google.com').then((_) {
-    ReceivePort keepAlive = new ReceivePort();
-    HttpClient client = new HttpClient();
-    client.getUrl(Uri.parse('https://www.google.com'))
-        .then((request) => request.close())
-        .then((response) => Expect.fail("Unexpected successful connection"))
-        .catchError((error) {
-          Expect.isTrue(error is HandshakeException);
-          keepAlive.close();
-          client.close();
-        });
-  },
-  onError: (e) {
-    Expect.isTrue(e is SocketException);
-  });
-}
-
-void InitializeSSL() {
-  // If the built-in root certificates aren't loaded, the connection
-  // should signal an error.
-  SecureSocket.initialize(useBuiltinRoots: false);
-}
-
-void main() {
-  InitializeSSL();
-  testGoogleUrl();
-}
diff --git a/tests/standalone/io/socket_cross_process_test.dart b/tests/standalone/io/socket_cross_process_test.dart
new file mode 100644
index 0000000..f44b369
--- /dev/null
+++ b/tests/standalone/io/socket_cross_process_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'dart:io';
+
+const int NUM_SERVERS = 10;
+
+void main() {
+  var args = new Options().arguments;
+  if (args.isEmpty) {
+    for (int i = 0; i < NUM_SERVERS; ++i) {
+      makeServer().then((server) {
+        runClientProcess(server.port).then((_) => server.close());
+      });
+    }
+  } else if (args[0] == '--client') {
+    int port = int.parse(args[1]);
+    runClient(port);
+  } else {
+    Expect.fail('Unknown arguments to socket_cross_process_test.dart');
+  }
+}
+
+Future makeServer() {
+  return ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
+    server.listen((request) {
+      request.pipe(request);
+    });
+    return server;
+  });
+}
+
+Future runClientProcess(int port) {
+  return Process.run(Platform.executable,
+                     []..addAll(Platform.executableArguments)
+                       ..add(Platform.script)
+                       ..add('--client')
+                       ..add(port.toString())).then((ProcessResult result) {
+    if (result.exitCode != 0 || !result.stdout.contains('SUCCESS')) {
+      print("Client failed, exit code ${result.exitCode}");
+      print("  stdout:");
+      print(result.stdout);
+      print("  stderr:");
+      print(result.stderr);
+      Expect.fail('Client subprocess exit code: ${result.exitCode}');
+    }
+  });
+}
+
+runClient(int port) {
+  Socket.connect(InternetAddress.LOOPBACK_IP_V4, port).then((connection) {
+    connection.listen((_) { }, onDone: () => print('SUCCESS'));
+    connection.close();
+  });
+}
diff --git a/tests/standalone/io/test_runner_test.dart b/tests/standalone/io/test_runner_test.dart
index 1bb41df..5e01f11 100644
--- a/tests/standalone/io/test_runner_test.dart
+++ b/tests/standalone/io/test_runner_test.dart
@@ -5,7 +5,6 @@
 import "dart:io";
 import "dart:isolate";
 import "dart:async";
-import "dart:utf";
 import "../../../tools/testing/dart/test_runner.dart";
 import "../../../tools/testing/dart/test_suite.dart";
 import "../../../tools/testing/dart/test_progress.dart" as progress;
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index b50b03f..19ce35c 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -140,7 +140,6 @@
 
 [ $compiler == dart2js && $checked ]
 io/http_read_test: Skip # Timeout TODO(ngeoffray): investigate
-io/list_input_stream_test: Skip # Timeout TODO(ngeoffray): investigate
 
 [ $compiler == dart2dart ]
 # Skip until we stabilize language tests.
diff --git a/tests/standalone/vmservice/test_helper.dart b/tests/standalone/vmservice/test_helper.dart
index f70e0f0..1eb81aed 100644
--- a/tests/standalone/vmservice/test_helper.dart
+++ b/tests/standalone/vmservice/test_helper.dart
@@ -8,7 +8,6 @@
 import 'dart:convert';
 import 'dart:io';
 import 'dart:json' as JSON;
-import 'dart:utf' as UTF;
 import 'package:expect/expect.dart';
 
 abstract class VmServiceRequestHelper {
@@ -38,7 +37,7 @@
     Expect.equals(200, response.statusCode, 'Invalid HTTP Status Code');
     var replyAsString;
     try {
-      replyAsString = UTF.decodeUtf8(data, 0, null, null);
+      replyAsString = UTF8.decode(data);
     } catch (e) {
       onRequestFailed(e);
       return;
diff --git a/tests/utils/dummy_compiler_test.dart b/tests/utils/dummy_compiler_test.dart
index f95a289..5c7c1da 100644
--- a/tests/utils/dummy_compiler_test.dart
+++ b/tests/utils/dummy_compiler_test.dart
@@ -85,7 +85,7 @@
     } else if (uri.path.endsWith('isolate_helper.dart')) {
       source = 'library isolatehelper; class _WorkerStub {}';
     } else {
-      source = "library lib;";
+      source = "library lib${uri.path.replaceAll('/', '.')};";
     }
   } else {
    throw "unexpected URI $uri";
diff --git a/tests/utils/png_layout_test.dart b/tests/utils/png_layout_test.dart
index 13a30f7..2c986db 100644
--- a/tests/utils/png_layout_test.dart
+++ b/tests/utils/png_layout_test.dart
@@ -13,10 +13,10 @@
 import 'dart:html';
 
 main() {
-  var div1Style = _style('blue', 20, 10, 40, 10);
-  var div2Style = _style('red', 25, 30, 40, 10);
-  var div1 = new Element.html('<div style="$div1Style"></div>');
-  var div2 = new Element.html('<div style="$div2Style"></div>');
+  var div1 = new DivElement();
+  div1.attributes['style'] = _style('blue', 20, 10, 40, 10);
+  var div2 = new DivElement();
+  div2.attributes['style'] = _style('red', 25, 30, 40, 10);
   document.body.children.add(div1);
   document.body.children.add(div2);
 }
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index 7bc1414..34e6ff0 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -19,15 +19,3 @@
 
 [ $system == macos || $system == windows ]
 *_layout_test: Skip
-
-[ $arch == arm ]
-*: Skip
-
-[ $arch == simarm ]
-*: Skip
-
-[ $arch == mips ]
-*: Skip
-
-[ $arch == simmips ]
-*: Skip
diff --git a/tools/VERSION b/tools/VERSION
index d90d5d2..b00c238 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
-MINOR 6
-BUILD 21
-PATCH 3
+MINOR 7
+BUILD 0
+PATCH 0
diff --git a/tools/coverage.dart b/tools/coverage.dart
index 37bb2bf..678fe57 100644
--- a/tools/coverage.dart
+++ b/tools/coverage.dart
@@ -15,7 +15,6 @@
 
 import "dart:convert";
 import "dart:io";
-import "dart:utf";
 import "dart:json" as JSON;
 
 
diff --git a/tools/ddbg.dart b/tools/ddbg.dart
index 132be10..29a86f4 100644
--- a/tools/ddbg.dart
+++ b/tools/ddbg.dart
@@ -5,9 +5,9 @@
 // Simple interactive debugger shell that connects to the Dart VM's debugger
 // connection port.
 
+import "dart:convert";
 import "dart:io";
 import "dart:json" as json;
-import "dart:utf";
 import "dart:async";
 
 
@@ -38,7 +38,8 @@
   sbp [<file>] <line> Set breakpoint
   rbp <id> Remove breakpoint with given id
   po <id> Print object info for given id
-  eval <id> <expr> Evaluate expr on object id
+  eval obj <id> <expr> Evaluate expr on object id
+  eval cls <id> <expr> Evaluate expr on class id
   pl <id> <idx> [<len>] Print list element/slice
   pc <id> Print class info for given id
   ll  List loaded libraries
@@ -74,8 +75,12 @@
   return completer.future;
 }
 
-
 void processCommand(String cmdLine) {
+  
+  void huh() {
+    print("'$cmdLine' not understood, try h for help");
+  }
+
   seqNum++;
   var args = cmdLine.split(' ');
   if (args.length == 0) {
@@ -127,12 +132,21 @@
                 "params": { "isolateId" : isolate_id,
                             "libraryId": int.parse(args[1]) } };
     sendCmd(cmd).then((result) => handleGetScriptsResponse(result));
-  } else if (command == "eval" && args.length > 2) {
-    var expr = args.getRange(2, args.length).join(" ");
+  } else if (command == "eval" && args.length > 3) {
+    var expr = args.getRange(3, args.length).join(" ");
+    var target = args[1];
+    if (target == "obj") {
+      target = "objectId";
+    } else if (target == "cls") {
+      target = "classId";
+    } else {
+      huh();
+      return;
+    }
     var cmd = { "id": seqNum,
                 "command": "evaluateExpr",
                 "params": { "isolateId": isolate_id,
-                            "objectId": int.parse(args[1]),
+                            target: int.parse(args[2]),
                             "expression": expr } };
     sendCmd(cmd).then((result) => handleEvalResponse(result));
   } else if (command == "po" && args.length == 2) {
@@ -216,7 +230,7 @@
   } else if (command == "h") {
     printHelp();
   } else {
-    print("command '$command' not understood, try h for help");
+    huh();
   }
 }
 
@@ -605,7 +619,7 @@
           quitShell();
         });
     stdinSubscription = stdin.transform(UTF8.decoder)
-                             .transform(new LineTransformer())
+                             .transform(new LineSplitter())
                              .listen((String line) => processCommand(line));
   });
 }
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index 3299577..ef81ce5 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -116,27 +116,9 @@
     },
     "Document": {
       "members": {
-        "body": [
-          "/// Moved to [HtmlDocument]."
-        ],
-        "caretRangeFromPoint": [
-          "/// Use the [Range] constructor instead."
-        ],
         "createElement": [
           "/// Deprecated: use new Element.tag(tagName) instead."
         ],
-        "createTouchList": [
-          "/// Use the [TouchList] constructor instead."
-        ],
-        "getCSSCanvasContext": [
-          "/// Moved to [HtmlDocument]."
-        ],
-        "head": [
-          "/// Moved to [HtmlDocument]."
-        ],
-        "lastModified": [
-          "/// Moved to [HtmlDocument]."
-        ],
         "querySelector": [
           "/**",
           " * Finds the first descendant element of this document that matches the",
@@ -153,42 +135,6 @@
           " * For details about CSS selector syntax, see the",
           " * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).",
           " */"
-        ],
-        "querySelectorAll": [
-          "/// Deprecated: use query(\"#$elementId\") instead."
-        ],
-        "referrer": [
-          "/// Moved to [HtmlDocument]."
-        ],
-        "styleSheets": [
-          "/// Moved to [HtmlDocument]"
-        ],
-        "title": [
-          "/// Moved to [HtmlDocument]."
-        ],
-        "webkitCancelFullScreen": [
-          "/// Moved to [HtmlDocument]."
-        ],
-        "webkitExitFullscreen": [
-          "/// Moved to [HtmlDocument]."
-        ],
-        "webkitExitPointerLock": [
-          "/// Moved to [HtmlDocument]."
-        ],
-        "webkitFullscreenElement": [
-          "/// Moved to [HtmlDocument]."
-        ],
-        "webkitFullscreenEnabled": [
-          "/// Moved to [HtmlDocument]."
-        ],
-        "webkitHidden": [
-          "/// Moved to [HtmlDocument]."
-        ],
-        "webkitIsFullScreen": [
-          "/// Moved to [HtmlDocument]."
-        ],
-        "webkitPointerLockElement": [
-          "/// Moved to [HtmlDocument]."
         ]
       }
     },
@@ -234,48 +180,6 @@
         "height": [
           "/// The height of this canvas element in CSS pixels."
         ],
-        "toDataURL": [
-          "/**",
-          "   * Returns a data URI containing a representation of the image in the",
-          "   * format specified by type (defaults to 'image/png').",
-          "   *",
-          "   * Data Uri format is as follow `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`",
-          "   *",
-          "   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when requesting [type]",
-          "   * 'image/jpeg' or 'image/webp'. If [quality] is not passed the default",
-          "   * value is used. Note: the default value varies by browser.",
-          "   *",
-          "   * If the height or width of this canvas element is 0, then 'data:' is returned,",
-          "   * representing no data.",
-          "   *",
-          "   * If the type requested is not 'image/png', and the returned value is",
-          "   * 'data:image/png', then the requested type is not supported.",
-          "   *",
-          "   * Example usage:",
-          "   *",
-          "   *     CanvasElement canvas = new CanvasElement();",
-          "   *     var ctx = canvas.context2D",
-          "   *     ..fillStyle = \"rgb(200,0,0)\"",
-          "   *     ..fillRect(10, 10, 55, 50);",
-          "   *     var dataUrl = canvas.toDataUrl(\"image/jpeg\", 0.95);",
-          "   *     // The Data Uri would look similar to",
-          "   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA",
-          "   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO",
-          "   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='",
-          "   *     //Create a new image element from the data URI.",
-          "   *     var img = new ImageElement();",
-          "   *     img.src = dataUrl;",
-          "   *     document.body.children.add(img);",
-          "   *",
-          "   * See also:",
-          "   *",
-          "   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.",
-          "   *",
-          "   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.",
-          "   *",
-          "   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.",
-          "   */"
-        ],
         "width": [
           "/// The width of this canvas element in CSS pixels."
         ]
diff --git a/tools/dom/dom.json b/tools/dom/dom.json
index d9a9dec..57ac1bf 100644
--- a/tools/dom/dom.json
+++ b/tools/dom/dom.json
@@ -2452,9 +2452,13 @@
   },
   "EventTarget": {
     "members": {
-      "addEventListener": {},
+      "addEventListener": {
+        "support_level": "deprecated"
+      },
       "dispatchEvent": {},
-      "removeEventListener": {}
+      "removeEventListener": {
+        "support_level": "deprecated"
+      }
     },
     "support_level": "stable"
   },
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 34911cf..73c5d92 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -12,7 +12,7 @@
     TypeOrNothing, ConvertToFuture, GetCallbackInfo
 from copy import deepcopy
 from htmlrenamer import convert_to_future_members, keep_overloaded_members, \
-    private_html_members, renamed_html_members, renamed_overloads, \
+    private_html_members, dom_private_html_members, renamed_html_members, renamed_overloads, \
     removed_html_members
 import logging
 import monitored
@@ -200,6 +200,7 @@
         operation_str not in keep_overloaded_members and
         operation_str not in renamed_html_members and
         operation_str not in private_html_members and
+        operation_str not in dom_private_html_members and
         operation_str not in removed_html_members and
         operation.id != '__getter__' and
         operation.id != '__setter__' and
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index ceee9ba..6834f8e0 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -152,25 +152,46 @@
   'WorkerGlobalScope.webkitRequestFileSystem',
 ])
 
+# "Private" members in the form $dom_foo.
+# TODO(efortuna): Remove this set. This allows us to make the change of removing
+# $dom in installments instead of all at once, but the intent is to move all of
+# these either into private_html_members or remove them from this list entirely.
+dom_private_html_members = monitored.Set('htmlrenamer.private_html_members', [
+  'Document.createElement',
+  'Document.createElementNS',
+  'Document.createRange',
+  'Element.getAttribute',
+  'Element.getAttributeNS',
+  'Element.setAttribute',
+  'Element.setAttributeNS',
+  'EventTarget.addEventListener',
+  'EventTarget.removeEventListener',
+  'Node.childNodes',
+])
+
 # 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.
+# browser. They are exposed simply by placing an underscore in front of the
+# name.
 private_html_members = monitored.Set('htmlrenamer.private_html_members', [
   'AudioNode.connect',
   'CanvasRenderingContext2D.arc',
+  'CanvasRenderingContext2D.drawImage',
   'CompositionEvent.initCompositionEvent',
   'CustomEvent.initCustomEvent',
+  'CSSStyleDeclaration.getPropertyValue',
+  'CSSStyleDeclaration.setProperty',
+  'CSSStyleDeclaration.var',
   'DeviceOrientationEvent.initDeviceOrientationEvent',
-  'Document.createElement',
-  'Document.createElementNS',
   'Document.createEvent',
   'Document.createNodeIterator',
-  'Document.createRange',
   'Document.createTextNode',
   'Document.createTouch',
   'Document.createTouchList',
   'Document.createTreeWalker',
   'Document.querySelectorAll',
+  'DocumentFragment.querySelector',
+  'DocumentFragment.querySelectorAll',
 
   # Moved to HTMLDocument.
   'Document.body',
@@ -194,40 +215,28 @@
   'Document.webkitPointerLockElement',
   'Document.webkitVisibilityState',
 
-  'DocumentFragment.querySelector',
-  'DocumentFragment.querySelectorAll',
-  'Element.childElementCount',
   'Element.children',
+  'Element.childElementCount',
   'Element.firstElementChild',
-  'ParentNode.childElementCount',
-  'ParentNode.children',
-  'ParentNode.firstElementChild',
-  'Element.getAttribute',
-  'Element.getAttributeNS',
   'Element.getElementsByTagName',
-  'Element.hasAttribute',
-  'Element.hasAttributeNS',
-  'ParentNode.lastElementChild',
-  'Element.querySelectorAll',
-  'Element.removeAttribute',
-  'Element.removeAttributeNS',
   'Element.scrollIntoView',
   'Element.scrollIntoViewIfNeeded',
-  'Element.setAttributeNS',
-  'Element.setAttribute',
-  'Element.setAttributeNS',
+  'Element.removeAttribute',
+  'Element.removeAttributeNS',
+  'Element.hasAttribute',
+  'Element.hasAttributeNS',
+  'Element.innerHTML',
+  'Element.querySelectorAll',
   'Event.initEvent',
-  'EventTarget.addEventListener',
-  'EventTarget.removeEventListener',
   'Geolocation.clearWatch',
   'Geolocation.getCurrentPosition',
   'Geolocation.watchPosition',
   'HashChangeEvent.initHashChangeEvent',
   'HTMLCanvasElement.toDataURL',
   'HTMLTableElement.createCaption',
-  'HTMLTableElement.createTBody',
   'HTMLTableElement.createTFoot',
   'HTMLTableElement.createTHead',
+  'HTMLTableElement.createTBody',
   'HTMLTableElement.insertRow',
   'HTMLTableElement.rows',
   'HTMLTableElement.tBodies',
@@ -268,12 +277,18 @@
   'MouseEvent.screenX',
   'MouseEvent.screenY',
   'MutationEvent.initMutationEvent',
+  'MutationObserver.observe',
   'Node.attributes',
-  'Node.childNodes',
   'Node.localName',
   'Node.namespaceURI',
   'Node.removeChild',
   'Node.replaceChild',
+  'ParentNode.childElementCount',
+  'ParentNode.children',
+  'ParentNode.firstElementChild',
+  'ParentNode.lastElementChild',
+  'RTCPeerConnection.createAnswer',
+  'RTCPeerConnection.createOffer',
   'Screen.availHeight',
   'Screen.availLeft',
   'Screen.availTop',
@@ -285,6 +300,7 @@
   'Storage.removeItem',
   'Storage.setItem',
   'StorageEvent.initStorageEvent',
+  'StorageInfo.queryUsageAndQuota',
   'TextEvent.initTextEvent',
   'Touch.clientX',
   'Touch.clientY',
@@ -300,29 +316,29 @@
   'UIEvent.layerY',
   'UIEvent.pageX',
   'UIEvent.pageY',
+  'WebGLRenderingContext.texImage2D',
   'WheelEvent.initWebKitWheelEvent',
+  'WheelEvent.wheelDeltaX',
+  'WheelEvent.wheelDeltaY',
+  'Window.createImageBitmap',
   'Window.getComputedStyle',
   'Window.moveTo',
+  'Window.clearTimeout',
+  'Window.clearInterval',
+  'Window.setTimeout',
+  'Window.setInterval',
 ])
 
 # Members from the standard dom that exist in the dart:html library with
 # identical functionality but with cleaner names.
 renamed_html_members = monitored.Dict('htmlrenamer.renamed_html_members', {
-    'CanvasRenderingContext2D.drawImage': '_drawImage',
     'WebKitCSSKeyframesRule.insertRule': 'appendRule',
-    'CSSStyleDeclaration.getPropertyValue': '_getPropertyValue',
-    'CSSStyleDeclaration.setProperty': '_setProperty',
-    'CSSStyleDeclaration.var': '_var',
     'DirectoryEntry.getDirectory': '_getDirectory',
     'DirectoryEntry.getFile': '_getFile',
     'Document.createCDATASection': 'createCDataSection',
     'Document.defaultView': 'window',
     'Document.querySelector': 'query',
     'Window.CSS': 'css',
-    'Window.clearTimeout': '_clearTimeout',
-    'Window.clearInterval': '_clearInterval',
-    'Window.setTimeout': '_setTimeout',
-    'Window.setInterval': '_setInterval',
     'Window.webkitConvertPointFromNodeToPage': '_convertPointFromNodeToPage',
     'Window.webkitConvertPointFromPageToNode': '_convertPointFromPageToNode',
     'Window.webkitNotifications': 'notifications',
@@ -330,7 +346,6 @@
     'Window.webkitResolveLocalFileSystemURL': 'resolveLocalFileSystemUrl',
     'Element.querySelector': 'query',
     'Element.webkitMatchesSelector' : 'matches',
-    'MutationObserver.observe': '_observe',
     'Navigator.webkitGetUserMedia': '_getUserMedia',
     'Node.appendChild': 'append',
     'Node.cloneNode': 'clone',
@@ -339,18 +354,11 @@
     'Node.parentElement': 'parent',
     'Node.previousSibling': 'previousNode',
     'Node.textContent': 'text',
-    'RTCPeerConnection.createAnswer': '_createAnswer',
-    'RTCPeerConnection.createOffer': '_createOffer',
-    'StorageInfo.queryUsageAndQuota': '_queryUsageAndQuota',
-    'SVGElement.className': '$dom_svgClassName',
+    'SVGElement.className': '_svgClassName',
     'SVGStopElement.offset': 'gradientOffset',
     'URL.createObjectURL': 'createObjectUrl',
     'URL.revokeObjectURL': 'revokeObjectUrl',
-    'WebGLRenderingContext.texImage2D': '_texImage2D',
     'WebGLRenderingContext.texSubImage2D': '_texSubImageImage2D',
-    'WheelEvent.wheelDeltaX': '_wheelDeltaX',
-    'WheelEvent.wheelDeltaY': '_wheelDeltaY',
-    'Window.createImageBitmap': '_createImageBitmap',
     #'WorkerContext.webkitRequestFileSystem': '_requestFileSystem',
     #'WorkerContext.webkitRequestFileSystemSync': '_requestFileSystemSync',
 })
@@ -790,6 +798,10 @@
 
     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('_'):  # e.g. _svgClassName
+        target_name = '_' + target_name
+    elif self._FindMatch(interface, member, member_prefix,
+        dom_private_html_members):
       if not target_name.startswith('$dom_'):  # e.g. $dom_svgClassName
         target_name = '$dom_' + target_name
 
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 9770a59..5133ef6 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -49,7 +49,6 @@
     'WebKitCSSKeyframesRule.insertRule',
     'CSSStyleDeclaration.setProperty',
     'Element.createShadowRoot',
-    'Element.innerHTML',
     'Element.insertAdjacentElement',
     'Element.insertAdjacentHTML',
     'Element.insertAdjacentText',
diff --git a/tools/dom/src/AttributeMap.dart b/tools/dom/src/AttributeMap.dart
index 76a9064..de088a7 100644
--- a/tools/dom/src/AttributeMap.dart
+++ b/tools/dom/src/AttributeMap.dart
@@ -40,7 +40,7 @@
 
   Iterable<String> get keys {
     // TODO: generate a lazy collection instead.
-    var attributes = _element.$dom_attributes;
+    var attributes = _element._attributes;
     var keys = new List<String>();
     for (int i = 0, len = attributes.length; i < len; i++) {
       if (_matches(attributes[i])) {
@@ -52,7 +52,7 @@
 
   Iterable<String> get values {
     // TODO: generate a lazy collection instead.
-    var attributes = _element.$dom_attributes;
+    var attributes = _element._attributes;
     var values = new List<String>();
     for (int i = 0, len = attributes.length; i < len; i++) {
       if (_matches(attributes[i])) {
@@ -88,7 +88,7 @@
   _ElementAttributeMap(Element element): super(element);
 
   bool containsKey(String key) {
-    return _element.$dom_hasAttribute(key);
+    return _element._hasAttribute(key);
   }
 
   String operator [](String key) {
@@ -101,7 +101,7 @@
 
   String remove(String key) {
     String value = _element.$dom_getAttribute(key);
-    _element.$dom_removeAttribute(key);
+    _element._removeAttribute(key);
     return value;
   }
 
@@ -112,7 +112,7 @@
     return keys.length;
   }
 
-  bool _matches(Node node) => node.$dom_namespaceUri == null;
+  bool _matches(Node node) => node._namespaceUri == null;
 }
 
 /**
@@ -125,7 +125,7 @@
   _NamespacedAttributeMap(Element element, this._namespace): super(element);
 
   bool containsKey(String key) {
-    return _element.$dom_hasAttributeNS(_namespace, key);
+    return _element._hasAttributeNS(_namespace, key);
   }
 
   String operator [](String key) {
@@ -138,7 +138,7 @@
 
   String remove(String key) {
     String value = this[key];
-    _element.$dom_removeAttributeNS(_namespace, key);
+    _element._removeAttributeNS(_namespace, key);
     return value;
   }
 
@@ -149,7 +149,7 @@
     return keys.length;
   }
 
-  bool _matches(Node node) => node.$dom_namespaceUri == _namespace;
+  bool _matches(Node node) => node._namespaceUri == _namespace;
 }
 
 
@@ -159,27 +159,27 @@
  */
 class _DataAttributeMap implements Map<String, String> {
 
-  final Map<String, String> $dom_attributes;
+  final Map<String, String> _attributes;
 
-  _DataAttributeMap(this.$dom_attributes);
+  _DataAttributeMap(this._attributes);
 
   // interface Map
 
   // TODO: Use lazy iterator when it is available on Map.
   bool containsValue(String value) => values.any((v) => v == value);
 
-  bool containsKey(String key) => $dom_attributes.containsKey(_attr(key));
+  bool containsKey(String key) => _attributes.containsKey(_attr(key));
 
-  String operator [](String key) => $dom_attributes[_attr(key)];
+  String operator [](String key) => _attributes[_attr(key)];
 
   void operator []=(String key, String value) {
-    $dom_attributes[_attr(key)] = value;
+    _attributes[_attr(key)] = value;
   }
 
   String putIfAbsent(String key, String ifAbsent()) =>
-    $dom_attributes.putIfAbsent(_attr(key), ifAbsent);
+    _attributes.putIfAbsent(_attr(key), ifAbsent);
 
-  String remove(String key) => $dom_attributes.remove(_attr(key));
+  String remove(String key) => _attributes.remove(_attr(key));
 
   void clear() {
     // Needs to operate on a snapshot since we are mutating the collection.
@@ -189,7 +189,7 @@
   }
 
   void forEach(void f(String key, String value)) {
-    $dom_attributes.forEach((String key, String value) {
+    _attributes.forEach((String key, String value) {
       if (_matches(key)) {
         f(_strip(key), value);
       }
@@ -198,7 +198,7 @@
 
   Iterable<String> get keys {
     final keys = new List<String>();
-    $dom_attributes.forEach((String key, String value) {
+    _attributes.forEach((String key, String value) {
       if (_matches(key)) {
         keys.add(_strip(key));
       }
@@ -208,7 +208,7 @@
 
   Iterable<String> get values {
     final values = new List<String>();
-    $dom_attributes.forEach((String key, String value) {
+    _attributes.forEach((String key, String value) {
       if (_matches(key)) {
         values.add(value);
       }
diff --git a/tools/dom/src/Html5NodeValidator.dart b/tools/dom/src/Html5NodeValidator.dart
new file mode 100644
index 0000000..a5e0e57
--- /dev/null
+++ b/tools/dom/src/Html5NodeValidator.dart
@@ -0,0 +1,450 @@
+// DO NOT EDIT- this file is generated from running tool/generator.sh.
+
+// 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.dom.html;
+
+/**
+ * A Dart DOM validator generated from Caja whitelists.
+ *
+ * This contains a whitelist of known HTML tagNames and attributes and will only
+ * accept known good values.
+ *
+ * See also:
+ *
+ * * <https://code.google.com/p/google-caja/wiki/CajaWhitelists>
+ */
+class _Html5NodeValidator implements NodeValidator {
+
+  static final Set<String> _allowedElements = new Set.from([
+    'A',
+    'ABBR',
+    'ACRONYM',
+    'ADDRESS',
+    'AREA',
+    'ARTICLE',
+    'ASIDE',
+    'AUDIO',
+    'B',
+    'BDI',
+    'BDO',
+    'BIG',
+    'BLOCKQUOTE',
+    'BR',
+    'BUTTON',
+    'CANVAS',
+    'CAPTION',
+    'CENTER',
+    'CITE',
+    'CODE',
+    'COL',
+    'COLGROUP',
+    'COMMAND',
+    'DATA',
+    'DATALIST',
+    'DD',
+    'DEL',
+    'DETAILS',
+    'DFN',
+    'DIR',
+    'DIV',
+    'DL',
+    'DT',
+    'EM',
+    'FIELDSET',
+    'FIGCAPTION',
+    'FIGURE',
+    'FONT',
+    'FOOTER',
+    'FORM',
+    'H1',
+    'H2',
+    'H3',
+    'H4',
+    'H5',
+    'H6',
+    'HEADER',
+    'HGROUP',
+    'HR',
+    'I',
+    'IFRAME',
+    'IMG',
+    'INPUT',
+    'INS',
+    'KBD',
+    'LABEL',
+    'LEGEND',
+    'LI',
+    'MAP',
+    'MARK',
+    'MENU',
+    'METER',
+    'NAV',
+    'NOBR',
+    'OL',
+    'OPTGROUP',
+    'OPTION',
+    'OUTPUT',
+    'P',
+    'PRE',
+    'PROGRESS',
+    'Q',
+    'S',
+    'SAMP',
+    'SECTION',
+    'SELECT',
+    'SMALL',
+    'SOURCE',
+    'SPAN',
+    'STRIKE',
+    'STRONG',
+    'SUB',
+    'SUMMARY',
+    'SUP',
+    'TABLE',
+    'TBODY',
+    'TD',
+    'TEXTAREA',
+    'TFOOT',
+    'TH',
+    'THEAD',
+    'TIME',
+    'TR',
+    'TRACK',
+    'TT',
+    'U',
+    'UL',
+    'VAR',
+    'VIDEO',
+    'WBR',
+  ]);
+
+  static const _standardAttributes = const <String>[
+    '*::class',
+    '*::dir',
+    '*::draggable',
+    '*::hidden',
+    '*::id',
+    '*::inert',
+    '*::itemprop',
+    '*::itemref',
+    '*::itemscope',
+    '*::lang',
+    '*::spellcheck',
+    '*::title',
+    '*::translate',
+    'A::accesskey',
+    'A::coords',
+    'A::hreflang',
+    'A::name',
+    'A::shape',
+    'A::tabindex',
+    'A::target',
+    'A::type',
+    'AREA::accesskey',
+    'AREA::alt',
+    'AREA::coords',
+    'AREA::nohref',
+    'AREA::shape',
+    'AREA::tabindex',
+    'AREA::target',
+    'AUDIO::controls',
+    'AUDIO::loop',
+    'AUDIO::mediagroup',
+    'AUDIO::muted',
+    'AUDIO::preload',
+    'BDO::dir',
+    'BODY::alink',
+    'BODY::bgcolor',
+    'BODY::link',
+    'BODY::text',
+    'BODY::vlink',
+    'BR::clear',
+    'BUTTON::accesskey',
+    'BUTTON::disabled',
+    'BUTTON::name',
+    'BUTTON::tabindex',
+    'BUTTON::type',
+    'BUTTON::value',
+    'CANVAS::height',
+    'CANVAS::width',
+    'CAPTION::align',
+    'COL::align',
+    'COL::char',
+    'COL::charoff',
+    'COL::span',
+    'COL::valign',
+    'COL::width',
+    'COLGROUP::align',
+    'COLGROUP::char',
+    'COLGROUP::charoff',
+    'COLGROUP::span',
+    'COLGROUP::valign',
+    'COLGROUP::width',
+    'COMMAND::checked',
+    'COMMAND::command',
+    'COMMAND::disabled',
+    'COMMAND::label',
+    'COMMAND::radiogroup',
+    'COMMAND::type',
+    'DATA::value',
+    'DEL::datetime',
+    'DETAILS::open',
+    'DIR::compact',
+    'DIV::align',
+    'DL::compact',
+    'FIELDSET::disabled',
+    'FONT::color',
+    'FONT::face',
+    'FONT::size',
+    'FORM::accept',
+    'FORM::autocomplete',
+    'FORM::enctype',
+    'FORM::method',
+    'FORM::name',
+    'FORM::novalidate',
+    'FORM::target',
+    'FRAME::name',
+    'H1::align',
+    'H2::align',
+    'H3::align',
+    'H4::align',
+    'H5::align',
+    'H6::align',
+    'HR::align',
+    'HR::noshade',
+    'HR::size',
+    'HR::width',
+    'HTML::version',
+    'IFRAME::align',
+    'IFRAME::frameborder',
+    'IFRAME::height',
+    'IFRAME::marginheight',
+    'IFRAME::marginwidth',
+    'IFRAME::width',
+    'IMG::align',
+    'IMG::alt',
+    'IMG::border',
+    'IMG::height',
+    'IMG::hspace',
+    'IMG::ismap',
+    'IMG::name',
+    'IMG::usemap',
+    'IMG::vspace',
+    'IMG::width',
+    'INPUT::accept',
+    'INPUT::accesskey',
+    'INPUT::align',
+    'INPUT::alt',
+    'INPUT::autocomplete',
+    'INPUT::checked',
+    'INPUT::disabled',
+    'INPUT::inputmode',
+    'INPUT::ismap',
+    'INPUT::list',
+    'INPUT::max',
+    'INPUT::maxlength',
+    'INPUT::min',
+    'INPUT::multiple',
+    'INPUT::name',
+    'INPUT::placeholder',
+    'INPUT::readonly',
+    'INPUT::required',
+    'INPUT::size',
+    'INPUT::step',
+    'INPUT::tabindex',
+    'INPUT::type',
+    'INPUT::usemap',
+    'INPUT::value',
+    'INS::datetime',
+    'KEYGEN::disabled',
+    'KEYGEN::keytype',
+    'KEYGEN::name',
+    'LABEL::accesskey',
+    'LABEL::for',
+    'LEGEND::accesskey',
+    'LEGEND::align',
+    'LI::type',
+    'LI::value',
+    'LINK::sizes',
+    'MAP::name',
+    'MENU::compact',
+    'MENU::label',
+    'MENU::type',
+    'METER::high',
+    'METER::low',
+    'METER::max',
+    'METER::min',
+    'METER::value',
+    'OBJECT::typemustmatch',
+    'OL::compact',
+    'OL::reversed',
+    'OL::start',
+    'OL::type',
+    'OPTGROUP::disabled',
+    'OPTGROUP::label',
+    'OPTION::disabled',
+    'OPTION::label',
+    'OPTION::selected',
+    'OPTION::value',
+    'OUTPUT::for',
+    'OUTPUT::name',
+    'P::align',
+    'PRE::width',
+    'PROGRESS::max',
+    'PROGRESS::min',
+    'PROGRESS::value',
+    'SELECT::autocomplete',
+    'SELECT::disabled',
+    'SELECT::multiple',
+    'SELECT::name',
+    'SELECT::required',
+    'SELECT::size',
+    'SELECT::tabindex',
+    'SOURCE::type',
+    'TABLE::align',
+    'TABLE::bgcolor',
+    'TABLE::border',
+    'TABLE::cellpadding',
+    'TABLE::cellspacing',
+    'TABLE::frame',
+    'TABLE::rules',
+    'TABLE::summary',
+    'TABLE::width',
+    'TBODY::align',
+    'TBODY::char',
+    'TBODY::charoff',
+    'TBODY::valign',
+    'TD::abbr',
+    'TD::align',
+    'TD::axis',
+    'TD::bgcolor',
+    'TD::char',
+    'TD::charoff',
+    'TD::colspan',
+    'TD::headers',
+    'TD::height',
+    'TD::nowrap',
+    'TD::rowspan',
+    'TD::scope',
+    'TD::valign',
+    'TD::width',
+    'TEXTAREA::accesskey',
+    'TEXTAREA::autocomplete',
+    'TEXTAREA::cols',
+    'TEXTAREA::disabled',
+    'TEXTAREA::inputmode',
+    'TEXTAREA::name',
+    'TEXTAREA::placeholder',
+    'TEXTAREA::readonly',
+    'TEXTAREA::required',
+    'TEXTAREA::rows',
+    'TEXTAREA::tabindex',
+    'TEXTAREA::wrap',
+    'TFOOT::align',
+    'TFOOT::char',
+    'TFOOT::charoff',
+    'TFOOT::valign',
+    'TH::abbr',
+    'TH::align',
+    'TH::axis',
+    'TH::bgcolor',
+    'TH::char',
+    'TH::charoff',
+    'TH::colspan',
+    'TH::headers',
+    'TH::height',
+    'TH::nowrap',
+    'TH::rowspan',
+    'TH::scope',
+    'TH::valign',
+    'TH::width',
+    'THEAD::align',
+    'THEAD::char',
+    'THEAD::charoff',
+    'THEAD::valign',
+    'TR::align',
+    'TR::bgcolor',
+    'TR::char',
+    'TR::charoff',
+    'TR::valign',
+    'TRACK::default',
+    'TRACK::kind',
+    'TRACK::label',
+    'TRACK::srclang',
+    'UL::compact',
+    'UL::type',
+    'VIDEO::controls',
+    'VIDEO::height',
+    'VIDEO::loop',
+    'VIDEO::mediagroup',
+    'VIDEO::muted',
+    'VIDEO::preload',
+    'VIDEO::width',
+  ];
+
+  static const _uriAttributes = const <String>[
+    'A::href',
+    'AREA::href',
+    'BLOCKQUOTE::cite',
+    'BODY::background',
+    'COMMAND::icon',
+    'DEL::cite',
+    'FORM::action',
+    'IMG::src',
+    'INPUT::src',
+    'INS::cite',
+    'Q::cite',
+    'VIDEO::poster',
+  ];
+
+  final UriPolicy uriPolicy;
+
+  static final Map<String, Function> _attributeValidators = {};
+
+  /**
+   * All known URI attributes will be validated against the UriPolicy, if
+   * [uriPolicy] is null then a default UriPolicy will be used.
+   */
+  _Html5NodeValidator({UriPolicy uriPolicy})
+      :uriPolicy = uriPolicy != null ? uriPolicy : new UriPolicy() {
+
+    if (_attributeValidators.isEmpty) {
+      for (var attr in _standardAttributes) {
+        _attributeValidators[attr] = _standardAttributeValidator;
+      }
+
+      for (var attr in _uriAttributes) {
+        _attributeValidators[attr] = _uriAttributeValidator;
+      }
+    }
+  }
+
+  bool allowsElement(Element element) {
+    return _allowedElements.contains(element.tagName);
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    var tagName = element.tagName;
+    var validator = _attributeValidators['$tagName::$attributeName'];
+    if (validator == null) {
+      validator = _attributeValidators['*::$attributeName'];
+    }
+    if (validator == null) {
+      return false;
+    }
+    return validator(element, attributeName, value, this);
+  }
+
+  static bool _standardAttributeValidator(Element element, String attributeName,
+      String value, _Html5NodeValidator context) {
+    return true;
+  }
+
+  static bool _uriAttributeValidator(Element element, String attributeName,
+      String value, _Html5NodeValidator context) {
+    return context.uriPolicy.allowsUri(value);
+  }
+}
diff --git a/tools/dom/src/NodeValidatorBuilder.dart b/tools/dom/src/NodeValidatorBuilder.dart
new file mode 100644
index 0000000..c5f0c80
--- /dev/null
+++ b/tools/dom/src/NodeValidatorBuilder.dart
@@ -0,0 +1,453 @@
+// 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.dom.html;
+
+
+/**
+ * Class which helps construct standard node validation policies.
+ *
+ * By default this will not accept anything, but the 'allow*' functions can be
+ * used to expand what types of elements or attributes are allowed.
+ *
+ * All allow functions are additive- elements will be accepted if they are
+ * accepted by any specific rule.
+ *
+ * It is important to remember that sanitization is not just intended to prevent
+ * cross-site scripting attacks, but also to prevent information from being
+ * displayed in unexpected ways. For example something displaying basic
+ * formatted text may not expect `<video>` tags to appear. In this case an
+ * empty NodeValidatorBuilder with just [allowTextElements] might be
+ * appropriate.
+ */
+class NodeValidatorBuilder implements NodeValidator {
+
+  final List<NodeValidator> _validators = <NodeValidator>[];
+
+  NodeValidatorBuilder() {
+  }
+
+  /**
+   * Creates a new NodeValidatorBuilder which accepts common constructs.
+   *
+   * By default this will accept HTML5 elements and attributes with the default
+   * [UriPolicy] and templating elements.
+   *
+   * Notable syntax which is filtered:
+   *
+   * * Only known-good HTML5 elements and attributes are allowed.
+   * * All URLs must be same-origin, use [allowNavigation] and [allowImages] to
+   * specify additional URI policies.
+   * * Inline-styles are not allowed.
+   * * Custom element tags are disallowed, use [allowCustomElement].
+   * * Custom tags extensions are disallowed, use [allowTagExtension].
+   * * SVG Elements are not allowed, use [allowSvg].
+   *
+   * For scenarios where the HTML should only contain formatted text
+   * [allowTextElements] is more appropriate.
+   *
+   * Use [allowSvg] to allow SVG elements.
+   */
+  NodeValidatorBuilder.common() {
+    allowHtml5();
+    allowTemplating();
+  }
+
+  /**
+   * Allows navigation elements- Form and Anchor tags, along with common
+   * attributes.
+   *
+   * The UriPolicy can be used to restrict the locations the navigation elements
+   * are allowed to direct to. By default this will use the default [UriPolicy].
+   */
+  void allowNavigation([UriPolicy uriPolicy]) {
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+    add(new _SimpleNodeValidator.allowNavigation(uriPolicy));
+  }
+
+  /**
+   * Allows image elements.
+   *
+   * The UriPolicy can be used to restrict the locations the images may be
+   * loaded from. By default this will use the default [UriPolicy].
+   */
+  void allowImages([UriPolicy uriPolicy]) {
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+    add(new _SimpleNodeValidator.allowImages(uriPolicy));
+  }
+
+  /**
+   * Allow basic text elements.
+   *
+   * This allows a subset of HTML5 elements, specifically just these tags and
+   * no attributes.
+   *
+   * * B
+   * * BLOCKQUOTE
+   * * BR
+   * * EM
+   * * H1
+   * * H2
+   * * H3
+   * * H4
+   * * H5
+   * * H6
+   * * HR
+   * * I
+   * * LI
+   * * OL
+   * * P
+   * * SPAN
+   * * UL
+   */
+  void allowTextElements() {
+    add(new _SimpleNodeValidator.allowTextElements());
+  }
+
+  /**
+   * Allow common safe HTML5 elements and attributes.
+   *
+   * This list is based off of the Caja whitelists at:
+   * https://code.google.com/p/google-caja/wiki/CajaWhitelists.
+   *
+   * Common things which are not allowed are script elements, style attributes
+   * and any script handlers.
+   */
+  void allowHtml5({UriPolicy uriPolicy}) {
+    add(new _Html5NodeValidator(uriPolicy: uriPolicy));
+  }
+
+  /**
+   * Allow SVG elements and attributes except for known bad ones.
+   */
+  void allowSvg() {
+    add(new _SvgNodeValidator());
+  }
+
+  /**
+   * Allow custom elements with the specified tag name and specified attributes.
+   *
+   * This will allow the elements as custom tags (such as <x-foo></x-foo>),
+   * but will not allow tag extensions. Use [allowTagExtension] to allow
+   * tag extensions.
+   */
+  void allowCustomElement(String tagName,
+      {UriPolicy uriPolicy,
+      Iterable<String> attributes,
+      Iterable<String> uriAttributes}) {
+
+    var tagNameUpper = tagName.toUpperCase();
+    var attrs;
+    if (attributes != null) {
+      attrs =
+          attributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
+    }
+    var uriAttrs;
+    if (uriAttributes != null) {
+      uriAttrs =
+          uriAttributes.map((name) => '$tagNameUpper::${name.toLowerCase()}');
+    }
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+
+    add(new _CustomElementNodeValidator(
+        uriPolicy,
+        [tagNameUpper],
+        attrs,
+        uriAttrs,
+        false,
+        true));
+  }
+
+  /**
+   * Allow custom tag extensions with the specified type name and specified
+   * attributes.
+   *
+   * This will allow tag extensions (such as <div is="x-foo"></div>),
+   * but will not allow custom tags. Use [allowCustomElement] to allow
+   * custom tags.
+   */
+  void allowTagExtension(String tagName, String baseName,
+      {UriPolicy uriPolicy,
+      Iterable<String> attributes,
+      Iterable<String> uriAttributes}) {
+
+    var baseNameUpper = baseName.toUpperCase();
+    var tagNameUpper = tagName.toUpperCase();
+    var attrs;
+    if (attributes != null) {
+      attrs =
+          attributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
+    }
+    var uriAttrs;
+    if (uriAttributes != null) {
+      uriAttrs =
+          uriAttributes.map((name) => '$baseNameUpper::${name.toLowerCase()}');
+    }
+    if (uriPolicy == null) {
+      uriPolicy = new UriPolicy();
+    }
+
+    add(new _CustomElementNodeValidator(
+        uriPolicy,
+        [tagNameUpper, baseNameUpper],
+        attrs,
+        uriAttrs,
+        true,
+        false));
+  }
+
+  void allowElement(String tagName, {UriPolicy uriPolicy,
+    Iterable<String> attributes,
+    Iterable<String> uriAttributes}) {
+
+    allowCustomElement(tagName, uriPolicy: uriPolicy,
+        attributes: attributes,
+        uriAttributes: uriAttributes);
+  }
+
+  /**
+   * Allow templating elements (such as <template> and template-related
+   * attributes.
+   *
+   * This still requires other validators to allow regular attributes to be
+   * bound (such as [allowHtml5]).
+   */
+  void allowTemplating() {
+    add(new _TemplatingNodeValidator());
+  }
+
+  /**
+   * Add an additional validator to the current list of validators.
+   *
+   * Elements and attributes will be accepted if they are accepted by any
+   * validators.
+   */
+  void add(NodeValidator validator) {
+    _validators.add(validator);
+  }
+
+  bool allowsElement(Element element) {
+    return _validators.any((v) => v.allowsElement(element));
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    return _validators.any(
+        (v) => v.allowsAttribute(element, attributeName, value));
+  }
+}
+
+class _SimpleNodeValidator implements NodeValidator {
+  final Set<String> allowedElements;
+  final Set<String> allowedAttributes;
+  final Set<String> allowedUriAttributes;
+  final UriPolicy uriPolicy;
+
+  factory _SimpleNodeValidator.allowNavigation(UriPolicy uriPolicy) {
+    return new _SimpleNodeValidator(uriPolicy,
+      allowedElements: [
+        'A',
+        'FORM'],
+      allowedAttributes: [
+        'A::accesskey',
+        'A::coords',
+        'A::hreflang',
+        'A::name',
+        'A::shape',
+        'A::tabindex',
+        'A::target',
+        'A::type',
+        'FORM::accept',
+        'FORM::autocomplete',
+        'FORM::enctype',
+        'FORM::method',
+        'FORM::name',
+        'FORM::novalidate',
+        'FORM::target',
+      ],
+      allowedUriAttributes: [
+        'A::href',
+        'FORM::action',
+      ]);
+  }
+
+  factory _SimpleNodeValidator.allowImages(UriPolicy uriPolicy) {
+    return new _SimpleNodeValidator(uriPolicy,
+      allowedElements: [
+        'IMG'
+      ],
+      allowedAttributes: [
+        'IMG::align',
+        'IMG::alt',
+        'IMG::border',
+        'IMG::height',
+        'IMG::hspace',
+        'IMG::ismap',
+        'IMG::name',
+        'IMG::usemap',
+        'IMG::vspace',
+        'IMG::width',
+      ],
+      allowedUriAttributes: [
+        'IMG::src',
+      ]);
+  }
+
+  factory _SimpleNodeValidator.allowTextElements() {
+    return new _SimpleNodeValidator(null,
+      allowedElements: [
+        'B',
+        'BLOCKQUOTE',
+        'BR',
+        'EM',
+        'H1',
+        'H2',
+        'H3',
+        'H4',
+        'H5',
+        'H6',
+        'HR',
+        'I',
+        'LI',
+        'OL',
+        'P',
+        'SPAN',
+        'UL',
+      ]);
+  }
+
+  /**
+   * Elements must be uppercased tag names. For example `'IMG'`.
+   * Attributes must be uppercased tag name followed by :: followed by
+   * lowercase attribute name. For example `'IMG:src'`.
+   */
+  _SimpleNodeValidator(this.uriPolicy,
+      {Iterable<String> allowedElements, Iterable<String> allowedAttributes,
+      Iterable<String> allowedUriAttributes}):
+      this.allowedElements = allowedElements != null ?
+          new Set.from(allowedElements) : new Set(),
+      this.allowedAttributes = allowedAttributes != null ?
+          new Set.from(allowedAttributes) : new Set(),
+      this.allowedUriAttributes = allowedUriAttributes != null ?
+          new Set.from(allowedUriAttributes) : new Set();
+
+  bool allowsElement(Element element) {
+    return allowedElements.contains(element.tagName);
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    var tagName = element.tagName;
+    if (allowedUriAttributes.contains('$tagName::$attributeName')) {
+      return uriPolicy.allowsUri(value);
+    } else if (allowedUriAttributes.contains('*::$attributeName')) {
+      return uriPolicy.allowsUri(value);
+    } else if (allowedAttributes.contains('$tagName::$attributeName')) {
+      return true;
+    } else if (allowedAttributes.contains('*::$attributeName')) {
+      return true;
+    } else if (allowedAttributes.contains('$tagName::*')) {
+      return true;
+    } else if (allowedAttributes.contains('*::*')) {
+      return true;
+    }
+    return false;
+  }
+}
+
+class _CustomElementNodeValidator extends _SimpleNodeValidator {
+  final bool allowTypeExtension;
+  final bool allowCustomTag;
+
+  _CustomElementNodeValidator(UriPolicy uriPolicy,
+      Iterable<String> allowedElements,
+      Iterable<String> allowedAttributes,
+      Iterable<String> allowedUriAttributes,
+      bool allowTypeExtension,
+      bool allowCustomTag):
+
+      super(uriPolicy,
+          allowedElements: allowedElements,
+          allowedAttributes: allowedAttributes,
+          allowedUriAttributes: allowedUriAttributes),
+      this.allowTypeExtension = allowTypeExtension == true,
+      this.allowCustomTag = allowCustomTag == true;
+
+  bool allowsElement(Element element) {
+    if (allowTypeExtension) {
+      var isAttr = element.attributes['is'];
+      if (isAttr != null) {
+        return allowedElements.contains(isAttr.toUpperCase()) &&
+          allowedElements.contains(element.tagName);
+      }
+    }
+    return allowCustomTag && allowedElements.contains(element.tagName);
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+   if (allowsElement(element)) {
+      if (allowTypeExtension && attributeName == 'is' &&
+          allowedElements.contains(value.toUpperCase())) {
+        return true;
+      }
+      return super.allowsAttribute(element, attributeName, value);
+    }
+    return false;
+  }
+}
+
+class _TemplatingNodeValidator extends _SimpleNodeValidator {
+  static const _TEMPLATE_ATTRS =
+      const <String>['bind', 'if', 'ref', 'repeat', 'syntax'];
+
+  final Set<String> _templateAttrs;
+
+  _TemplatingNodeValidator():
+      super(null,
+          allowedElements: [
+            'TEMPLATE'
+          ],
+          allowedAttributes: _TEMPLATE_ATTRS.map((attr) => 'TEMPLATE::$attr')),
+      _templateAttrs = new Set<String>.from(_TEMPLATE_ATTRS) {
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (super.allowsAttribute(element, attributeName, value)) {
+      return true;
+    }
+
+    if (attributeName == 'template' && value == "") {
+      return true;
+    }
+
+    if (element.attributes['template'] == "" ) {
+      return _templateAttrs.contains(attributeName);
+    }
+    return false;
+  }
+}
+
+
+class _SvgNodeValidator implements NodeValidator {
+  bool allowsElement(Element element) {
+    if (element is svg.ScriptElement) {
+      return false;
+    }
+    if (element is svg.SvgElement) {
+      return true;
+    }
+    return false;
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (attributeName == 'is' || attributeName.startsWith('on')) {
+      return false;
+    }
+    return allowsElement(element);
+  }
+}
diff --git a/tools/dom/src/Validators.dart b/tools/dom/src/Validators.dart
new file mode 100644
index 0000000..430658e
--- /dev/null
+++ b/tools/dom/src/Validators.dart
@@ -0,0 +1,205 @@
+// 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.dom.html;
+
+
+/**
+ * Interface used to validate that only accepted elements and attributes are
+ * allowed while parsing HTML strings into DOM nodes.
+ *
+ * In general, customization of validation behavior should be done via the
+ * [NodeValidatorBuilder] class to mitigate the chances of incorrectly
+ * implementing validation rules.
+ */
+abstract class NodeValidator {
+
+  /**
+   * Construct a default NodeValidator which only accepts whitelisted HTML5
+   * elements and attributes.
+   *
+   * If a uriPolicy is not specified then the default uriPolicy will be used.
+   */
+  factory NodeValidator({UriPolicy uriPolicy}) =>
+      new _Html5NodeValidator(uriPolicy: uriPolicy);
+
+  factory NodeValidator.throws(NodeValidator base) =>
+      new _ThrowsNodeValidator(base);
+
+  /**
+   * Returns true if the tagName is an accepted type.
+   */
+  bool allowsElement(Element element);
+
+  /**
+   * Returns true if the attribute is allowed.
+   *
+   * The attributeName parameter will always be in lowercase.
+   *
+   * See [allowsElement] for format of tagName.
+   */
+  bool allowsAttribute(Element element, String attributeName, String value);
+}
+
+/**
+ * Performs sanitization of a node tree after construction to ensure that it
+ * does not contain any disallowed elements or attributes.
+ *
+ * In general custom implementations of this class should not be necessary and
+ * all validation customization should be done in custom NodeValidators, but
+ * custom implementations of this class can be created to perform more complex
+ * tree sanitization.
+ */
+abstract class NodeTreeSanitizer {
+
+  /**
+   * Constructs a default tree sanitizer which will remove all elements and
+   * attributes which are not allowed by the provided validator.
+   */
+  factory NodeTreeSanitizer(NodeValidator validator) =>
+      new _ValidatingTreeSanitizer(validator);
+
+  /**
+   * Called with the root of the tree which is to be sanitized.
+   *
+   * This method needs to walk the entire tree and either remove elements and
+   * attributes which are not recognized as safe or throw an exception which
+   * will mark the entire tree as unsafe.
+   */
+  void sanitizeTree(Node node);
+}
+
+/**
+ * Defines the policy for what types of uris are allowed for particular
+ * attribute values.
+ *
+ * This can be used to provide custom rules such as allowing all http:// URIs
+ * for image attributes but only same-origin URIs for anchor tags.
+ */
+abstract class UriPolicy {
+  /**
+   * Constructs the default UriPolicy which is to only allow Uris to the same
+   * origin as the application was launched from.
+   *
+   * This will block all ftp: mailto: URIs. It will also block accessing
+   * https://example.com if the app is running from http://example.com.
+   */
+  factory UriPolicy() => new _SameOriginUriPolicy();
+
+  /**
+   * Checks if the uri is allowed on the specified attribute.
+   *
+   * The uri provided may or may not be a relative path.
+   */
+  bool allowsUri(String uri);
+}
+
+/**
+ * Allows URIs to the same origin as the current application was loaded from
+ * (such as https://example.com:80).
+ */
+class _SameOriginUriPolicy implements UriPolicy {
+  final AnchorElement _hiddenAnchor = new AnchorElement();
+  final Location _loc = window.location;
+
+  bool allowsUri(String uri) {
+    _hiddenAnchor.href = uri;
+    // IE leaves an empty hostname for same-origin URIs.
+    return (_hiddenAnchor.hostname == _loc.hostname &&
+        _hiddenAnchor.port == _loc.port &&
+        _hiddenAnchor.protocol == _loc.protocol) ||
+        (_hiddenAnchor.hostname == '' &&
+        _hiddenAnchor.port == '' &&
+        _hiddenAnchor.protocol == ':');
+  }
+}
+
+
+class _ThrowsNodeValidator implements NodeValidator {
+  final NodeValidator validator;
+
+  _ThrowsNodeValidator(this.validator) {}
+
+  bool allowsElement(Element element) {
+    if (!validator.allowsElement(element)) {
+      throw new ArgumentError(element.tagName);
+    }
+    return true;
+  }
+
+  bool allowsAttribute(Element element, String attributeName, String value) {
+    if (!validator.allowsAttribute(element, attributeName, value)) {
+      throw new ArgumentError('${element.tagName}[$attributeName="$value"]');
+    }
+  }
+}
+
+
+/**
+ * Standard tree sanitizer which validates a node tree against the provided
+ * validator and removes any nodes or attributes which are not allowed.
+ */
+class _ValidatingTreeSanitizer implements NodeTreeSanitizer {
+  NodeValidator validator;
+  _ValidatingTreeSanitizer(this.validator) {}
+
+  void sanitizeTree(Node node) {
+    void walk(Node node) {
+      sanitizeNode(node);
+
+      var child = node.lastChild;
+      while (child != null) {
+        // Child may be removed during the walk.
+        var nextChild = child.previousNode;
+        walk(child);
+        child = nextChild;
+      }
+    }
+    walk(node);
+  }
+
+  void sanitizeNode(Node node) {
+    switch (node.nodeType) {
+      case Node.ELEMENT_NODE:
+        Element element = node;
+        var attrs = element.attributes;
+        if (!validator.allowsElement(element)) {
+          element.remove();
+          break;
+        }
+
+        var isAttr = attrs['is'];
+        if (isAttr != null) {
+          if (!validator.allowsAttribute(element, 'is', isAttr)) {
+            element.remove();
+            break;
+          }
+        }
+
+        // TODO(blois): Need to be able to get all attributes, irrespective of
+        // XMLNS.
+        var keys = attrs.keys.toList();
+        for (var i = attrs.length - 1; i >= 0; --i) {
+          var name = keys[i];
+          if (!validator.allowsAttribute(element, name.toLowerCase(),
+              attrs[name])) {
+            attrs.remove(name);
+          }
+        }
+
+        if (element is TemplateElement) {
+          TemplateElement template = element;
+          sanitizeTree(template.content);
+        }
+        break;
+      case Node.COMMENT_NODE:
+      case Node.DOCUMENT_FRAGMENT_NODE:
+      case Node.TEXT_NODE:
+      case Node.CDATA_SECTION_NODE:
+        break;
+      default:
+        node.remove();
+    }
+  }
+}
diff --git a/tools/dom/src/WrappedEvent.dart b/tools/dom/src/WrappedEvent.dart
index 92b13f9..b701cef 100644
--- a/tools/dom/src/WrappedEvent.dart
+++ b/tools/dom/src/WrappedEvent.dart
@@ -34,7 +34,7 @@
 
   String get type => wrapped.type;
 
-  void $dom_initEvent(String eventTypeArg, bool canBubbleArg,
+  void _initEvent(String eventTypeArg, bool canBubbleArg,
       bool cancelableArg) {
     throw new UnsupportedError(
         'Cannot initialize this Event.');
diff --git a/tools/dom/src/dart2js_CustomElementSupport.dart b/tools/dom/src/dart2js_CustomElementSupport.dart
index e601ef0..95c64b6 100644
--- a/tools/dom/src/dart2js_CustomElementSupport.dart
+++ b/tools/dom/src/dart2js_CustomElementSupport.dart
@@ -4,8 +4,8 @@
 
 part of dart.dom.html;
 
-_callOnCreated(receiver) {
-  return receiver.onCreated();
+_callCreated(receiver) {
+  return receiver.created();
 }
 
 _makeCreatedCallbackMethod() {
@@ -15,7 +15,7 @@
                return invokeCallback(this);
              };
           })(#))''',
-      convertDartClosureToJS(_callOnCreated, 1));
+      convertDartClosureToJS(_callCreated, 1));
 }
 
 void _registerCustomElement(context, document, String tag, Type type) {
diff --git a/tools/dom/src/dart2js_KeyEvent.dart b/tools/dom/src/dart2js_KeyEvent.dart
index 15a7153..303d445 100644
--- a/tools/dom/src/dart2js_KeyEvent.dart
+++ b/tools/dom/src/dart2js_KeyEvent.dart
@@ -84,18 +84,18 @@
   /** True if the shift key was pressed during this event. */
   bool get shiftKey => _parent.shiftKey;
   Window get view => _parent.view;
-  void $dom_initUIEvent(String type, bool canBubble, bool cancelable,
+  void _initUIEvent(String type, bool canBubble, bool cancelable,
       Window view, int detail) {
     throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
   }
   String get _shadowKeyIdentifier => JS('String', '#.keyIdentifier', _parent);
 
-  int get $dom_charCode => charCode;
-  int get $dom_keyCode => keyCode;
-  String get $dom_keyIdentifier {
+  int get _charCode => charCode;
+  int get _keyCode => keyCode;
+  String get _keyIdentifier {
     throw new UnsupportedError("keyIdentifier is unsupported.");
   }
-  void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
+  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
       Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
       bool altKey, bool shiftKey, bool metaKey,
       bool altGraphKey) {
diff --git a/tools/dom/src/dartium_KeyEvent.dart b/tools/dom/src/dartium_KeyEvent.dart
index 5be433b..6be8d67 100644
--- a/tools/dom/src/dartium_KeyEvent.dart
+++ b/tools/dom/src/dartium_KeyEvent.dart
@@ -84,18 +84,18 @@
   /** True if the shift key was pressed during this event. */
   bool get shiftKey => _parent.shiftKey;
   Window get view => _parent.view;
-  void $dom_initUIEvent(String type, bool canBubble, bool cancelable,
+  void _initUIEvent(String type, bool canBubble, bool cancelable,
       Window view, int detail) {
     throw new UnsupportedError("Cannot initialize a UI Event from a KeyEvent.");
   }
-  String get _shadowKeyIdentifier => _parent.$dom_keyIdentifier;
+  String get _shadowKeyIdentifier => _parent._keyIdentifier;
 
-  int get $dom_charCode => charCode;
-  int get $dom_keyCode => keyCode;
-  String get $dom_keyIdentifier {
+  int get _charCode => charCode;
+  int get _keyCode => keyCode;
+  String get _keyIdentifier {
     throw new UnsupportedError("keyIdentifier is unsupported.");
   }
-  void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
+  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
       Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
       bool altKey, bool shiftKey, bool metaKey,
       bool altGraphKey) {
diff --git a/tools/dom/src/dartium_Platform.dart b/tools/dom/src/dartium_Platform.dart
index 48f3238..34fdecc 100644
--- a/tools/dom/src/dartium_Platform.dart
+++ b/tools/dom/src/dartium_Platform.dart
@@ -24,8 +24,15 @@
    *
    * This is needed to cover timing scenarios which the custom element polyfill
    * does not cover.
+   *
+   * This is also a workaround for dartbug.com/12642 in Dartium.
    */
-  void upgradeCustomElements(Node node) {
+  static void upgradeCustomElements(Node node) {
     // no-op, provided for dart2js polyfill.
+    if (node is Element) {
+      (node as Element).queryAll('*');
+    } else {
+      node.nodes.forEach(upgradeCustomElements);
+    }
   }
 }
diff --git a/tools/dom/src/shared_SVGFactoryProviders.dart b/tools/dom/src/shared_SVGFactoryProviders.dart
index a6960b8..6f4b9a7 100644
--- a/tools/dom/src/shared_SVGFactoryProviders.dart
+++ b/tools/dom/src/shared_SVGFactoryProviders.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.
 
-part of svg;
-
-final _START_TAG_REGEXP = new RegExp('<(\\w+)');
+part of dart.dom.svg;
 
 class _SvgElementFactoryProvider {
   static SvgElement createSvgElement_tag(String tag) {
@@ -12,30 +10,4 @@
       document.$dom_createElementNS("http://www.w3.org/2000/svg", tag);
     return temp;
   }
-
-  static SvgElement createSvgElement_svg(String svg) {
-    Element parentTag;
-    final match = _START_TAG_REGEXP.firstMatch(svg);
-    if (match != null && match.group(1).toLowerCase() == 'svg') {
-      parentTag = new Element.tag('div');
-    } else {
-      parentTag = new SvgSvgElement();
-    }
-
-    parentTag.innerHtml = svg;
-    if (parentTag.children.length == 1) return parentTag.children.removeLast();
-
-    throw new ArgumentError(
-        'SVG had ${parentTag.children.length} '
-        'top-level children but 1 expected');
-  }
-}
-
-class _SvgSvgElementFactoryProvider {
-  static SvgSvgElement createSvgSvgElement() {
-    final el = new SvgElement.tag("svg");
-    // The SVG spec requires the version attribute to match the spec version
-    el.attributes['version'] = "1.1";
-    return el;
-  }
 }
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 62fcb28..5519ebc 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -46,27 +46,30 @@
 part '$AUXILIARY_DIR/Dimension.dart';
 part '$AUXILIARY_DIR/EventListener.dart';
 part '$AUXILIARY_DIR/EventStreamProvider.dart';
+part '$AUXILIARY_DIR/Html5NodeValidator.dart';
 part '$AUXILIARY_DIR/ImmutableListMixin.dart';
-part '$AUXILIARY_DIR/KeyboardEventStream.dart';
+part '$AUXILIARY_DIR/Isolates.dart';
 part '$AUXILIARY_DIR/KeyCode.dart';
 part '$AUXILIARY_DIR/KeyLocation.dart';
 part '$AUXILIARY_DIR/KeyName.dart';
+part '$AUXILIARY_DIR/KeyboardEventStream.dart';
+part '$AUXILIARY_DIR/Microtask.dart';
+part '$AUXILIARY_DIR/NodeValidatorBuilder.dart';
 part '$AUXILIARY_DIR/Point.dart';
 part '$AUXILIARY_DIR/ReadyState.dart';
 part '$AUXILIARY_DIR/Rectangle.dart';
-part '$AUXILIARY_DIR/_HttpRequestUtils.dart';
-part '$AUXILIARY_DIR/Isolates.dart';
-part '$AUXILIARY_DIR/Microtask.dart';
 part '$AUXILIARY_DIR/Serialization.dart';
 part '$AUXILIARY_DIR/WrappedEvent.dart';
 part '$AUXILIARY_DIR/WrappedList.dart';
+part '$AUXILIARY_DIR/_HttpRequestUtils.dart';
+part '$AUXILIARY_DIR/_ListIterators.dart';
 part '$AUXILIARY_DIR/dart2js_Conversions.dart';
 part '$AUXILIARY_DIR/dart2js_CustomElementSupport.dart';
 part '$AUXILIARY_DIR/dart2js_DOMImplementation.dart';
 part '$AUXILIARY_DIR/dart2js_KeyEvent.dart';
 part '$AUXILIARY_DIR/dart2js_LocationWrapper.dart';
 part '$AUXILIARY_DIR/dart2js_Platform.dart';
-part '$AUXILIARY_DIR/_ListIterators.dart';
+part '$AUXILIARY_DIR/Validators.dart';
 
 
 /**
diff --git a/tools/dom/templates/html/dart2js/impl_KeyboardEvent.darttemplate b/tools/dom/templates/html/dart2js/impl_KeyboardEvent.darttemplate
index 3c1a60d..2f1edac 100644
--- a/tools/dom/templates/html/dart2js/impl_KeyboardEvent.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_KeyboardEvent.darttemplate
@@ -14,22 +14,32 @@
  */
 $(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 
+  /** 
+   * Programmatically create a KeyboardEvent. 
+   *
+   * Due to browser differences, keyCode, charCode, or keyIdentifier values
+   * cannot be specified in this base level constructor. This constructor
+   * enables the user to programmatically create and dispatch a [KeyboardEvent],
+   * but it will not contain any particular key content. For programmatically
+   * creating keyboard events with specific key value contents, see the custom
+   * Event [KeyEvent]. 
+   */
   factory $CLASSNAME(String type,
       {Window view, bool canBubble: true, bool cancelable: true,
-      String keyIdentifier: "", int keyLocation: 1, bool ctrlKey: false,
+      int keyLocation: 1, bool ctrlKey: false,
       bool altKey: false, bool shiftKey: false, bool metaKey: false,
       bool altGraphKey: false}) {
     if (view == null) {
       view = window;
     }
-    final e = document.$dom_createEvent("KeyboardEvent");
-    e.$dom_initKeyboardEvent(type, canBubble, cancelable, view, keyIdentifier,
+    final e = document._createEvent("KeyboardEvent");
+    e._initKeyboardEvent(type, canBubble, cancelable, view, "",
         keyLocation, ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
     return e;
   }
 
   @DomName('KeyboardEvent.initKeyboardEvent')
-  void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable,
+  void _initKeyboardEvent(String type, bool canBubble, bool cancelable,
       Window view, String keyIdentifier, int keyLocation, bool ctrlKey,
       bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) {
     if (JS('bool', 'typeof(#.initKeyEvent) == "function"', this)) {
@@ -49,9 +59,9 @@
   }
 
   @DomName('KeyboardEvent.keyCode')
-  int get keyCode => $dom_keyCode;
+  int get keyCode => _keyCode;
 
   @DomName('KeyboardEvent.charCode')
-  int get charCode => $dom_charCode;
+  int get charCode => _charCode;
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
index 51d1c42..d48febb 100644
--- a/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
@@ -14,8 +14,8 @@
     if (view == null) {
       view = window;
     }
-    var event = document.$dom_createEvent('MouseEvent');
-    event.$dom_initMouseEvent(type, canBubble, cancelable, view, detail,
+    var event = document._createEvent('MouseEvent');
+    event._initMouseEvent(type, canBubble, cancelable, view, detail,
         screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
         button, relatedTarget);
     return event;
@@ -41,14 +41,14 @@
 
   @DomName('MouseEvent.clientX')
   @DomName('MouseEvent.clientY')
-  Point get client => new Point($dom_clientX, $dom_clientY);
+  Point get client => new Point(_clientX, _clientY);
 
   @DomName('MouseEvent.movementX')
   @DomName('MouseEvent.movementY')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  Point get movement => new Point($dom_webkitMovementX, $dom_webkitMovementY);
+  Point get movement => new Point(_webkitMovementX, _webkitMovementY);
 
   /**
    * The coordinates of the mouse pointer in target node coordinates.
@@ -75,5 +75,5 @@
 
   @DomName('MouseEvent.screenX')
   @DomName('MouseEvent.screenY')
-  Point get screen => new Point($dom_screenX, $dom_screenY);
+  Point get screen => new Point(_screenX, _screenY);
 }
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index dded4de..8aeace0 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -41,23 +41,26 @@
 part '$AUXILIARY_DIR/Dimension.dart';
 part '$AUXILIARY_DIR/EventListener.dart';
 part '$AUXILIARY_DIR/EventStreamProvider.dart';
+part '$AUXILIARY_DIR/Html5NodeValidator.dart';
 part '$AUXILIARY_DIR/ImmutableListMixin.dart';
-part '$AUXILIARY_DIR/KeyboardEventStream.dart';
+part '$AUXILIARY_DIR/Isolates.dart';
 part '$AUXILIARY_DIR/KeyCode.dart';
 part '$AUXILIARY_DIR/KeyLocation.dart';
 part '$AUXILIARY_DIR/KeyName.dart';
+part '$AUXILIARY_DIR/KeyboardEventStream.dart';
+part '$AUXILIARY_DIR/Microtask.dart';
+part '$AUXILIARY_DIR/NodeValidatorBuilder.dart';
 part '$AUXILIARY_DIR/Point.dart';
 part '$AUXILIARY_DIR/ReadyState.dart';
 part '$AUXILIARY_DIR/Rectangle.dart';
+part '$AUXILIARY_DIR/Serialization.dart';
+part '$AUXILIARY_DIR/Validators.dart';
 part '$AUXILIARY_DIR/WrappedEvent.dart';
 part '$AUXILIARY_DIR/WrappedList.dart';
 part '$AUXILIARY_DIR/_HttpRequestUtils.dart';
+part '$AUXILIARY_DIR/_ListIterators.dart';
 part '$AUXILIARY_DIR/dartium_KeyEvent.dart';
 part '$AUXILIARY_DIR/dartium_Platform.dart';
-part '$AUXILIARY_DIR/Isolates.dart';
-part '$AUXILIARY_DIR/Microtask.dart';
-part '$AUXILIARY_DIR/Serialization.dart';
-part '$AUXILIARY_DIR/_ListIterators.dart';
 
 part '$AUXILIARY_DIR/native_DOMPublic.dart';
 part '$AUXILIARY_DIR/native_DOMImplementation.dart';
diff --git a/tools/dom/templates/html/dartium/impl_KeyboardEvent.darttemplate b/tools/dom/templates/html/dartium/impl_KeyboardEvent.darttemplate
index a603616..6ab8501 100644
--- a/tools/dom/templates/html/dartium/impl_KeyboardEvent.darttemplate
+++ b/tools/dom/templates/html/dartium/impl_KeyboardEvent.darttemplate
@@ -8,22 +8,22 @@
 
   factory $CLASSNAME(String type,
       {Window view, bool canBubble: true, bool cancelable: true,
-      String keyIdentifier: "", int keyLocation: 1, bool ctrlKey: false,
+      int keyLocation: 1, bool ctrlKey: false,
       bool altKey: false, bool shiftKey: false, bool metaKey: false,
       bool altGraphKey: false}) {
     if (view == null) {
       view = window;
     }
-    final e = document.$dom_createEvent("KeyboardEvent");
-    e.$dom_initKeyboardEvent(type, canBubble, cancelable, view, keyIdentifier,
+    final e = document._createEvent("KeyboardEvent");
+    e._initKeyboardEvent(type, canBubble, cancelable, view, "",
         keyLocation, ctrlKey, altKey, shiftKey, metaKey, altGraphKey);
     return e;
   }
 
   @DomName('KeyboardEvent.keyCode')
-  int get keyCode => $dom_keyCode;
+  int get keyCode => _keyCode;
 
   @DomName('KeyboardEvent.charCode')
-  int get charCode => $dom_charCode;
+  int get charCode => _charCode;
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
index 88b3d86..a1a3862 100644
--- a/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
+++ b/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
@@ -16,8 +16,8 @@
     if (view == null) {
       view = window;
     }
-    var event = document.$dom_createEvent('MouseEvent');
-    event.$dom_initMouseEvent(type, canBubble, cancelable, view, detail,
+    var event = document._createEvent('MouseEvent');
+    event._initMouseEvent(type, canBubble, cancelable, view, detail,
         screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey,
         button, relatedTarget);
     return event;
@@ -43,14 +43,14 @@
 
   @DomName('MouseEvent.clientX')
   @DomName('MouseEvent.clientY')
-  Point get client => new Point($dom_clientX, $dom_clientY);
+  Point get client => new Point(_clientX, _clientY);
 
   @DomName('MouseEvent.movementX')
   @DomName('MouseEvent.movementY')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  Point get movement => new Point($dom_webkitMovementX, $dom_webkitMovementY);
+  Point get movement => new Point(_webkitMovementX, _webkitMovementY);
 
   /**
    * The coordinates of the mouse pointer in target node coordinates.
@@ -59,9 +59,9 @@
    * after the event has fired or if the element has CSS transforms affecting
    * it.
    */
-  Point get offset => new Point($dom_offsetX, $dom_offsetY);
+  Point get offset => new Point(_offsetX, _offsetY);
 
   @DomName('MouseEvent.screenX')
   @DomName('MouseEvent.screenY')
-  Point get screen => new Point($dom_screenX, $dom_screenY);
+  Point get screen => new Point(_screenX, _screenY);
 }
diff --git a/tools/dom/templates/html/impl/impl_AudioNode.darttemplate b/tools/dom/templates/html/impl/impl_AudioNode.darttemplate
index ec6ee5d..e61a6f4 100644
--- a/tools/dom/templates/html/impl/impl_AudioNode.darttemplate
+++ b/tools/dom/templates/html/impl/impl_AudioNode.darttemplate
@@ -8,9 +8,9 @@
 $!MEMBERS
   @DomName('AudioNode.connect')
   void connectNode(AudioNode destination, [int output = 0, int input = 0]) =>
-      $dom_connect(destination, output, input);
+      _connect(destination, output, input);
 
   @DomName('AudioNode.connect')
   void connectParam(AudioParam destination, [int output = 0]) =>
-      $dom_connect(destination, output);
+      _connect(destination, output);
 }
diff --git a/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate b/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
index b23f15a..e561dc6 100644
--- a/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
@@ -46,7 +46,7 @@
   @DomName('CanvasRenderingContext2D.arc')
   void arc(num x,  num y,  num radius,  num startAngle, num endAngle,
       [bool anticlockwise = false]) {
-    $dom_arc(x, y, radius, startAngle, endAngle, anticlockwise);
+    _arc(x, y, radius, startAngle, endAngle, anticlockwise);
   }
 
   /**
diff --git a/tools/dom/templates/html/impl/impl_CompositionEvent.darttemplate b/tools/dom/templates/html/impl/impl_CompositionEvent.darttemplate
index 2c61ba0..a6f6e68 100644
--- a/tools/dom/templates/html/impl/impl_CompositionEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CompositionEvent.darttemplate
@@ -13,8 +13,8 @@
     if (view == null) {
       view = window;
     }
-    var e = document.$dom_createEvent("CompositionEvent");
-    e.$dom_initCompositionEvent(type, canBubble, cancelable, view, data);
+    var e = document._createEvent("CompositionEvent");
+    e._initCompositionEvent(type, canBubble, cancelable, view, data);
     return e;
   }
 $!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate b/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate
index a5305e1..79dd406 100644
--- a/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate
@@ -10,12 +10,12 @@
   factory $CLASSNAME(String type,
       {bool canBubble: true, bool cancelable: true, Object detail}) {
 
-    final CustomEvent e = document.$dom_createEvent('CustomEvent');
+    final CustomEvent e = document._createEvent('CustomEvent');
 
 $if DART2JS
     detail = convertDartToNative_SerializedScriptValue(detail);
 $endif
-    e.$dom_initCustomEvent(type, canBubble, cancelable, detail);
+    e._initCustomEvent(type, canBubble, cancelable, detail);
 
     return e;
   }
diff --git a/tools/dom/templates/html/impl/impl_DeviceOrientationEvent.darttemplate b/tools/dom/templates/html/impl/impl_DeviceOrientationEvent.darttemplate
index 9a064feef..821c56f 100644
--- a/tools/dom/templates/html/impl/impl_DeviceOrientationEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DeviceOrientationEvent.darttemplate
@@ -9,8 +9,8 @@
   factory $CLASSNAME(String type,
       {bool canBubble: true, bool cancelable: true, num alpha: 0, num beta: 0,
       num gamma: 0, bool absolute: false}) {
-    var e = document.$dom_createEvent("DeviceOrientationEvent");
-    e.$dom_initDeviceOrientationEvent(type, canBubble, cancelable, alpha, beta,
+    var e = document._createEvent("DeviceOrientationEvent");
+    e._initDeviceOrientationEvent(type, canBubble, cancelable, alpha, beta,
         gamma, absolute);
     return e;
   }
diff --git a/tools/dom/templates/html/impl/impl_Document.darttemplate b/tools/dom/templates/html/impl/impl_Document.darttemplate
index e095026..effda9d 100644
--- a/tools/dom/templates/html/impl/impl_Document.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Document.darttemplate
@@ -33,7 +33,7 @@
    * [CSS selector specification](http://www.w3.org/TR/css3-selectors/).
    */
   ElementList queryAll(String selectors) {
-    return new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
+    return new _FrozenElementList._wrap(_querySelectorAll(selectors));
   }
 
   /// Checks if [register] is supported on the current platform.
diff --git a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
index 8008a93..199b67a 100644
--- a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
@@ -7,21 +7,18 @@
 $(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME() => document.createDocumentFragment();
 
-  factory $CLASSNAME.html(String html) {
-    final fragment = new DocumentFragment();
-    fragment.innerHtml = html;
-    return fragment;
+  factory $CLASSNAME.html(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+
+    return document.body.createFragment(html,
+      validator: validator, treeSanitizer: treeSanitizer);
   }
 
-  factory $CLASSNAME.svg(String svgContent) {
-    final fragment = new DocumentFragment();
-    final e = new svg.SvgSvgElement();
-    e.innerHtml = svgContent;
+  factory $CLASSNAME.svg(String svgContent,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
 
-    // Copy list first since we don't want liveness during iteration.
-    final List nodes = new List.from(e.nodes);
-    fragment.nodes.addAll(nodes);
-    return fragment;
+    return new svg.SvgSvgElement().createFragment(svgContent,
+        validator: validator, treeSanitizer: treeSanitizer);
   }
 
 $if DART2JS
@@ -46,10 +43,10 @@
     children.addAll(copy);
   }
 
-  Element query(String selectors) => $dom_querySelector(selectors);
+  Element query(String selectors) => _querySelector(selectors);
 
   List<Element> queryAll(String selectors) =>
-    new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
+    new _FrozenElementList._wrap(_querySelectorAll(selectors));
 
   String get innerHtml {
     final e = new Element.tag("div");
@@ -57,17 +54,16 @@
     return e.innerHtml;
   }
 
-  // TODO(nweiz): Do we want to support some variant of innerHtml for XML and/or
-  // SVG strings?
   void set innerHtml(String value) {
+    this.setInnerHtml(value);
+  }
+
+  void setInnerHtml(String html,
+    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+
     this.nodes.clear();
-
-    final e = new Element.tag("div");
-    e.innerHtml = value;
-
-    // Copy list first since we don't want liveness during iteration.
-    List nodes = new List.from(e.nodes, growable: false);
-    this.nodes.addAll(nodes);
+    append(document.body.createFragment(
+        html, validator: validator, treeSanitizer: treeSanitizer));
   }
 
   /**
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index acf6abb..74cc8f7 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -10,14 +10,14 @@
   final HtmlCollection _childElements;
 
   _ChildrenElementList._wrap(Element element)
-    : _childElements = element.$dom_children,
+    : _childElements = element._children,
       _element = element;
 
   bool contains(Object element) => _childElements.contains(element);
 
 
   bool get isEmpty {
-    return _element.$dom_firstElementChild == null;
+    return _element._firstElementChild == null;
   }
 
   int get length {
@@ -29,7 +29,7 @@
   }
 
   void operator []=(int index, Element value) {
-    _element.$dom_replaceChild(value, _childElements[index]);
+    _element._replaceChild(value, _childElements[index]);
   }
 
   void set length(int newLength) {
@@ -93,7 +93,7 @@
     if (object is Element) {
       Element element = object;
       if (identical(element.parentNode, _element)) {
-        _element.$dom_removeChild(element);
+        _element._removeChild(element);
         return true;
       }
     }
@@ -123,7 +123,7 @@
   Element removeAt(int index) {
     final result = this[index];
     if (result != null) {
-      _element.$dom_removeChild(result);
+      _element._removeChild(result);
     }
     return result;
   }
@@ -131,20 +131,20 @@
   Element removeLast() {
     final result = this.last;
     if (result != null) {
-      _element.$dom_removeChild(result);
+      _element._removeChild(result);
     }
     return result;
   }
 
   Element get first {
-    Element result = _element.$dom_firstElementChild;
+    Element result = _element._firstElementChild;
     if (result == null) throw new StateError("No elements");
     return result;
   }
 
 
   Element get last {
-    Element result = _element.$dom_lastElementChild;
+    Element result = _element._lastElementChild;
     if (result == null) throw new StateError("No elements");
     return result;
   }
@@ -309,20 +309,31 @@
   /**
    * Creates an HTML element from a valid fragment of HTML.
    *
-   * The [html] fragment must represent valid HTML with a single element root,
-   * which will be parsed and returned.
-   *
-   * Important: the contents of [html] should not contain any user-supplied
-   * data. Without strict data validation it is impossible to prevent script
-   * injection exploits.
-   *
-   * It is instead recommended that elements be constructed via [Element.tag]
-   * and text be added via [text].
-   *
    *     var element = new Element.html('<div class="foo">content</div>');
+   *
+   * The HTML fragment should contain only one single root element, any
+   * leading or trailing text nodes will be removed.
+   *
+   * The HTML fragment is parsed as if it occurred within the context of a
+   * `<body>` tag, this means that special elements such as `<caption>` which
+   * must be parsed within the scope of a `<table>` element will be dropped. Use
+   * [createFragment] to parse contextual HTML fragments.
+   *
+   * Unless a validator is provided this will perform the default validation
+   * and remove all scriptable elements and attributes.
+   *
+   * See also:
+   *
+   * * [NodeValidator]
+   *
    */
-  factory $CLASSNAME.html(String html) =>
-      _$(CLASSNAME)FactoryProvider.createElement_html(html);
+  factory Element.html(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    var fragment = document.body.createFragment(html, validator: validator,
+        treeSanitizer: treeSanitizer);
+
+    return fragment.nodes.where((e) => e is Element).single;
+  }
 
   /**
    * Creates the HTML element specified by the tag name.
@@ -542,7 +553,7 @@
    *     var items = element.query('.itemClassName');
    */
   ElementList queryAll(String selectors) =>
-    new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
+    new _FrozenElementList._wrap(_querySelectorAll(selectors));
 
   /**
    * The set of CSS classes applied to this element.
@@ -627,7 +638,7 @@
       pseudoElement = '';
     }
     // TODO(jacobr): last param should be null, see b/5045788
-    return window.$dom_getComputedStyle(this, pseudoElement);
+    return window._getComputedStyle(this, pseudoElement);
   }
 
   /**
@@ -669,7 +680,7 @@
    * Called by the DOM when this element has been instantiated.
    */
   @Experimental()
-  void onCreated() {}
+  void created() {}
 
   // Hooks to support custom WebComponents.
 
@@ -700,11 +711,11 @@
 
   @DomName('Element.localName')
   @DocsEditable()
-  String get localName => $dom_localName;
+  String get localName => _localName;
 
   @DomName('Element.namespaceUri')
   @DocsEditable()
-  String get namespaceUri => $dom_namespaceUri;
+  String get namespaceUri => _namespaceUri;
 
   String toString() => localName;
 
@@ -732,17 +743,17 @@
         JS('bool', '!!(#.scrollIntoViewIfNeeded)', this);
 $endif
     if (alignment == ScrollAlignment.TOP) {
-      this.$dom_scrollIntoView(true);
+      this._scrollIntoView(true);
     } else if (alignment == ScrollAlignment.BOTTOM) {
-      this.$dom_scrollIntoView(false);
+      this._scrollIntoView(false);
     } else if (hasScrollIntoViewIfNeeded) {
       if (alignment == ScrollAlignment.CENTER) {
-        this.$dom_scrollIntoViewIfNeeded(true);
+        this._scrollIntoViewIfNeeded(true);
       } else {
-        this.$dom_scrollIntoViewIfNeeded();
+        this._scrollIntoViewIfNeeded();
       }
     } else {
-      this.$dom_scrollIntoView();
+      this._scrollIntoView();
     }
   }
 
@@ -1171,135 +1182,134 @@
     return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
   }
 
-$if DART2JS
-  @JSName('innerHTML')
-  @DomName('HTMLElement.innerHTML')
-  String get innerHtml => JS('String', '#.innerHTML', this);
+  static HtmlDocument _parseDocument;
+  static NodeValidatorBuilder _defaultValidator;
+  static _ValidatingTreeSanitizer _defaultSanitizer;
 
-  void set innerHtml(String value) {
-    JS('', '#.innerHTML = #', this, value);
-    // Polyfill relies on mutation observers for upgrading, but we want it
-    // immediate.
-    Platform.upgradeCustomElements(this);
+  /**
+   * Create a DocumentFragment from the HTML fragment and ensure that it follows
+   * the sanitization rules specified by the validator or treeSanitizer.
+   *
+   * If the default validation behavior is too restrictive then a new
+   * NodeValidator should be created, either extending or wrapping a default
+   * validator and overriding the validation APIs.
+   *
+   * The treeSanitizer is used to walk the generated node tree and sanitize it.
+   * A custom treeSanitizer can also be provided to perform special validation
+   * rules but since the API is more complex to implement this is discouraged.
+   *
+   * The returned tree is guaranteed to only contain nodes and attributes which
+   * are allowed by the provided validator.
+   *
+   * See also:
+   *
+   * * [NodeValidator]
+   * * [NodeTreeSanitizer]
+   */
+  DocumentFragment createFragment(String html,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    if (treeSanitizer == null) {
+      if (validator == null) {
+        if (_defaultValidator == null) {
+          _defaultValidator = new NodeValidatorBuilder.common();
+        }
+        validator = _defaultValidator;
+      }
+      if (_defaultSanitizer == null) {
+        _defaultSanitizer = new _ValidatingTreeSanitizer(validator);
+      } else {
+        _defaultSanitizer.validator = validator;
+      }
+      treeSanitizer = _defaultSanitizer;
+    } else if (validator != null) {
+      throw new ArgumentError(
+          'validator can only be passed if treeSanitizer is null');
+    }
+
+    if (_parseDocument == null) {
+      _parseDocument = document.implementation.createHtmlDocument('');
+    }
+    var contextElement;
+    if (this is BodyElement) {
+      contextElement = _parseDocument.body;
+    } else {
+      contextElement = _parseDocument.$dom_createElement(tagName);
+      _parseDocument.body.append(contextElement);
+    }
+    var fragment;
+    if (Range.supportsCreateContextualFragment) {
+      var range = _parseDocument.$dom_createRange();
+      range.selectNodeContents(contextElement);
+      fragment = range.createContextualFragment(html);
+    } else {
+      contextElement._innerHtml = html;
+
+      fragment = _parseDocument.createDocumentFragment();
+      while (contextElement.firstChild != null) {
+        fragment.append(contextElement.firstChild);
+      }
+    }
+    if (contextElement != _parseDocument.body) {
+      contextElement.remove();
+    }
+
+    treeSanitizer.sanitizeTree(fragment);
+    return fragment;
   }
-$endif
+
+  /**
+   * Parses the HTML fragment and sets it as the contents of this element.
+   *
+   * This uses the default sanitization behavior to sanitize the HTML fragment,
+   * use [setInnerHtml] to override the default behavior.
+   */
+  void set innerHtml(String html) {
+    this.setInnerHtml(html);
+  }
+
+  /**
+   * Parses the HTML fragment and sets it as the contents of this element.
+   * This ensures that the generated content follows the sanitization rules
+   * specified by the validator or treeSanitizer.
+   *
+   * If the default validation behavior is too restrictive then a new
+   * NodeValidator should be created, either extending or wrapping a default
+   * validator and overriding the validation APIs.
+   *
+   * The treeSanitizer is used to walk the generated node tree and sanitize it.
+   * A custom treeSanitizer can also be provided to perform special validation
+   * rules but since the API is more complex to implement this is discouraged.
+   *
+   * The resulting tree is guaranteed to only contain nodes and attributes which
+   * are allowed by the provided validator.
+   *
+   * See also:
+   *
+   * * [NodeValidator]
+   * * [NodeTreeSanitizer]
+   */
+  void setInnerHtml(String html,
+    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    text = null;
+    append(createFragment(
+        html, validator: validator, treeSanitizer: treeSanitizer));
+  }
+  String get innerHtml => _innerHtml;
+
+  /**
+   * For use while transitioning to the safe [innerHtml] or [setInnerHtml].
+   * Unsafe because it opens the app to cross-site scripting vulnerabilities.
+   */
+  @deprecated
+  void set unsafeInnerHtml(String html) {
+    _innerHtml = html;
+  }
 
 $!MEMBERS
 }
 
-final _START_TAG_REGEXP = new RegExp('<(\\w+)');
+
 class _ElementFactoryProvider {
-  static const _CUSTOM_PARENT_TAG_MAP = const {
-    'body' : 'html',
-    'head' : 'html',
-    'caption' : 'table',
-    'td': 'tr',
-    'th': 'tr',
-    'colgroup': 'table',
-    'col' : 'colgroup',
-    'tr' : 'tbody',
-    'tbody' : 'table',
-    'tfoot' : 'table',
-    'thead' : 'table',
-    'track' : 'audio',
-  };
-
-  @DomName('Document.createElement')
-  static Element createElement_html(String html) {
-    // TODO(jacobr): this method can be made more robust and performant.
-    // 1) Cache the dummy parent elements required to use innerHTML rather than
-    //    creating them every call.
-    // 2) Verify that the html does not contain leading or trailing text nodes.
-    // 3) Verify that the html does not contain both <head> and <body> tags.
-    // 4) Detatch the created element from its dummy parent.
-    String parentTag = 'div';
-    String tag;
-    final match = _START_TAG_REGEXP.firstMatch(html);
-    if (match != null) {
-      tag = match.group(1).toLowerCase();
-      if (Device.isIE && Element._TABLE_TAGS.containsKey(tag)) {
-        return _createTableForIE(html, tag);
-      }
-      parentTag = _CUSTOM_PARENT_TAG_MAP[tag];
-      if (parentTag == null) parentTag = 'div';
-    }
-
-    final temp = new Element.tag(parentTag);
-    temp.innerHtml = html;
-
-    Element element;
-    if (temp.children.length == 1) {
-      element = temp.children[0];
-    } else if (parentTag == 'html' && temp.children.length == 2) {
-      // In html5 the root <html> tag will always have a <body> and a <head>,
-      // even though the inner html only contains one of them.
-      element = temp.children[tag == 'head' ? 0 : 1];
-    } else {
-      _singleNode(temp.children);
-    }
-    element.remove();
-    return element;
-  }
-
-  /**
-   * IE table elements don't support innerHTML (even in standards mode).
-   * Instead we use a div and inject the table element in the innerHtml string.
-   * This technique works on other browsers too, but it's probably slower,
-   * so we only use it when running on IE.
-   *
-   * See also innerHTML:
-   * <http://msdn.microsoft.com/en-us/library/ie/ms533897(v=vs.85).aspx>
-   * and Building Tables Dynamically:
-   * <http://msdn.microsoft.com/en-us/library/ie/ms532998(v=vs.85).aspx>.
-   */
-  static Element _createTableForIE(String html, String tag) {
-    var div = new Element.tag('div');
-    div.innerHtml = '<table>$html</table>';
-    var table = _singleNode(div.children);
-    Element element;
-    switch (tag) {
-      case 'td':
-      case 'th':
-        TableRowElement row = _singleNode(table.rows);
-        element = _singleNode(row.cells);
-        break;
-      case 'tr':
-        element = _singleNode(table.rows);
-        break;
-      case 'tbody':
-        element = _singleNode(table.tBodies);
-        break;
-      case 'thead':
-        element = table.tHead;
-        break;
-      case 'tfoot':
-        element = table.tFoot;
-        break;
-      case 'caption':
-        element = table.caption;
-        break;
-      case 'colgroup':
-        element = _getColgroup(table);
-        break;
-      case 'col':
-        element = _singleNode(_getColgroup(table).children);
-        break;
-    }
-    element.remove();
-    return element;
-  }
-
-  static TableColElement _getColgroup(TableElement table) {
-    // TODO(jmesserly): is there a better way to do this?
-    return _singleNode(table.children.where((n) => n.tagName == 'COLGROUP')
-        .toList());
-  }
-
-  static Node _singleNode(List<Node> list) {
-    if (list.length == 1) return list[0];
-    throw new ArgumentError('HTML had ${list.length} '
-        'top level elements but 1 expected');
-  }
 
   @DomName('Document.createElement')
 $if DART2JS
diff --git a/tools/dom/templates/html/impl/impl_Event.darttemplate b/tools/dom/templates/html/impl/impl_Event.darttemplate
index cc0a3a6..00ced30 100644
--- a/tools/dom/templates/html/impl/impl_Event.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Event.darttemplate
@@ -29,8 +29,8 @@
    */
   factory Event.eventType(String type, String name, {bool canBubble: true,
       bool cancelable: true}) {
-    final Event e = document.$dom_createEvent(type);
-    e.$dom_initEvent(name, canBubble, cancelable);
+    final Event e = document._createEvent(type);
+    e._initEvent(name, canBubble, cancelable);
     return e;
   }
 $!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_Geolocation.darttemplate b/tools/dom/templates/html/impl/impl_Geolocation.darttemplate
index d0d011a..e15ffa0 100644
--- a/tools/dom/templates/html/impl/impl_Geolocation.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Geolocation.darttemplate
@@ -22,7 +22,7 @@
     }
     var completer = new Completer<Geoposition>();
     try {
-      $dom_getCurrentPosition(
+      _getCurrentPosition(
           (position) {
             completer.complete(_ensurePosition(position));
           },
@@ -56,7 +56,7 @@
     controller = new StreamController<Geoposition>(sync: true,
       onListen: () {
         assert(watchId == null);
-        watchId = $dom_watchPosition(
+        watchId = _watchPosition(
             (position) {
               controller.add(_ensurePosition(position));
             },
@@ -67,7 +67,7 @@
       },
       onCancel: () {
         assert(watchId != null);
-        $dom_clearWatch(watchId);
+        _clearWatch(watchId);
       });
 
     return controller.stream;
diff --git a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
index 0714003..03c6da5 100644
--- a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
@@ -38,6 +38,47 @@
     return context;
   }
 
-  String toDataUrl([String type = 'image/png', num quality]) => 
-      $dom_toDataUrl(type, quality);
+  /**
+   * Returns a data URI containing a representation of the image in the
+   * format specified by type (defaults to 'image/png').
+   *
+   * Data Uri format is as follow
+   * `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
+   *
+   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when
+   * requesting [type] 'image/jpeg' or 'image/webp'. If [quality] is not passed
+   * the default value is used. Note: the default value varies by browser.
+   *
+   * If the height or width of this canvas element is 0, then 'data:' is
+   * returned, representing no data.
+   *
+   * If the type requested is not 'image/png', and the returned value is
+   * 'data:image/png', then the requested type is not supported.
+   *
+   * Example usage:
+   *
+   *     CanvasElement canvas = new CanvasElement();
+   *     var ctx = canvas.context2D
+   *     ..fillStyle = "rgb(200,0,0)"
+   *     ..fillRect(10, 10, 55, 50);
+   *     var dataUrl = canvas.toDataUrl("image/jpeg", 0.95);
+   *     // The Data Uri would look similar to
+   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
+   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
+   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
+   *     //Create a new image element from the data URI.
+   *     var img = new ImageElement();
+   *     img.src = dataUrl;
+   *     document.body.children.add(img);
+   *
+   * See also:
+   *
+   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
+   *
+   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
+   *
+   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
+   */
+  String toDataUrl([String type = 'image/png', num quality]) =>
+      _toDataUrl(type, quality);
 }
diff --git a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
index 8f1a4ca..6887091 100644
--- a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
@@ -14,22 +14,22 @@
   BodyElement body;
 $else
   @DomName('Document.body')
-  BodyElement get body => $dom_body;
+  BodyElement get body => _body;
 
   @DomName('Document.body')
   void set body(BodyElement value) {
-    $dom_body = value;
+    _body = value;
   }
 $endif
 
   @DomName('Document.caretRangeFromPoint')
   Range caretRangeFromPoint(int x, int y) {
-    return $dom_caretRangeFromPoint(x, y);
+    return _caretRangeFromPoint(x, y);
   }
 
   @DomName('Document.elementFromPoint')
   Element elementFromPoint(int x, int y) {
-    return $dom_elementFromPoint(x, y);
+    return _elementFromPoint(x, y);
   }
 
   /**
@@ -73,36 +73,36 @@
   @DomName('Document.getCSSCanvasContext')
   CanvasRenderingContext getCssCanvasContext(String contextId, String name,
       int width, int height) {
-    return $dom_getCssCanvasContext(contextId, name, width, height);
+    return _getCssCanvasContext(contextId, name, width, height);
   }
 
   @DomName('Document.head')
-  HeadElement get head => $dom_head;
+  HeadElement get head => _head;
 
   @DomName('Document.lastModified')
-  String get lastModified => $dom_lastModified;
+  String get lastModified => _lastModified;
 
   @DomName('Document.preferredStylesheetSet')
-  String get preferredStylesheetSet => $dom_preferredStylesheetSet;
+  String get preferredStylesheetSet => _preferredStylesheetSet;
 
   @DomName('Document.referrer')
-  String get referrer => $dom_referrer;
+  String get referrer => _referrer;
 
   @DomName('Document.selectedStylesheetSet')
-  String get selectedStylesheetSet => $dom_selectedStylesheetSet;
+  String get selectedStylesheetSet => _selectedStylesheetSet;
   void set selectedStylesheetSet(String value) {
-    $dom_selectedStylesheetSet = value;
+    _selectedStylesheetSet = value;
   }
 
   @DomName('Document.styleSheets')
-  List<StyleSheet> get styleSheets => $dom_styleSheets;
+  List<StyleSheet> get styleSheets => _styleSheets;
 
   @DomName('Document.title')
-  String get title => $dom_title;
+  String get title => _title;
 
   @DomName('Document.title')
   void set title(String value) {
-    $dom_title = value;
+    _title = value;
   }
 
   @DomName('Document.webkitCancelFullScreen')
@@ -110,7 +110,7 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   void cancelFullScreen() {
-    $dom_webkitCancelFullScreen();
+    _webkitCancelFullScreen();
   }
 
   @DomName('Document.webkitExitFullscreen')
@@ -118,7 +118,7 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   void exitFullscreen() {
-    $dom_webkitExitFullscreen();
+    _webkitExitFullscreen();
   }
 
   @DomName('Document.webkitExitPointerLock')
@@ -126,45 +126,45 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   void exitPointerLock() {
-    $dom_webkitExitPointerLock();
+    _webkitExitPointerLock();
   }
 
   @DomName('Document.webkitFullscreenElement')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  Element get fullscreenElement => $dom_webkitFullscreenElement;
+  Element get fullscreenElement => _webkitFullscreenElement;
 
   @DomName('Document.webkitFullscreenEnabled')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  bool get fullscreenEnabled => $dom_webkitFullscreenEnabled;
+  bool get fullscreenEnabled => _webkitFullscreenEnabled;
 
   @DomName('Document.webkitHidden')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  bool get hidden => $dom_webkitHidden;
+  bool get hidden => _webkitHidden;
 
   @DomName('Document.webkitIsFullScreen')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  bool get isFullScreen => $dom_webkitIsFullScreen;
+  bool get isFullScreen => _webkitIsFullScreen;
 
   @DomName('Document.webkitPointerLockElement')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   Element get pointerLockElement =>
-      $dom_webkitPointerLockElement;
+      _webkitPointerLockElement;
 
   @DomName('Document.webkitVisibilityState')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
-  String get visibilityState => $dom_webkitVisibilityState;
+  String get visibilityState => _webkitVisibilityState;
 
   @Experimental
 $if DART2JS
diff --git a/tools/dom/templates/html/impl/impl_HTMLTableElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTableElement.darttemplate
index 06f540d..8548c59 100644
--- a/tools/dom/templates/html/impl/impl_HTMLTableElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLTableElement.darttemplate
@@ -9,26 +9,26 @@
 
   @DomName('HTMLTableElement.tBodies')
   List<TableSectionElement> get tBodies =>
-  new _WrappedList<TableSectionElement>($dom_tBodies);
+  new _WrappedList<TableSectionElement>(_tBodies);
 
   @DomName('HTMLTableElement.rows')
   List<TableRowElement> get rows =>
-      new _WrappedList<TableRowElement>($dom_rows);
+      new _WrappedList<TableRowElement>(_rows);
 
   TableRowElement addRow() {
     return insertRow(-1);
   }
 
-  TableCaptionElement createCaption() => $dom_createCaption();
-  TableSectionElement createTBody() => $dom_createTBody();
-  TableSectionElement createTFoot() => $dom_createTFoot();
-  TableSectionElement createTHead() => $dom_createTHead();
-  TableRowElement insertRow(int index) => $dom_insertRow(index);
+  TableCaptionElement createCaption() => _createCaption();
+  TableSectionElement createTBody() => _createTBody();
+  TableSectionElement createTFoot() => _createTFoot();
+  TableSectionElement createTHead() => _createTHead();
+  TableRowElement insertRow(int index) => _insertRow(index);
 
 $if DART2JS
-  TableSectionElement $dom_createTBody() {
+  TableSectionElement _createTBody() {
     if (JS('bool', '!!#.createTBody', this)) {
-      return this._createTBody();
+      return this._nativeCreateTBody();
     }
     var tbody = new Element.tag('tbody');
     this.children.add(tbody);
@@ -36,7 +36,7 @@
   }
 
   @JSName('createTBody')
-  TableSectionElement _createTBody() native;
+  TableSectionElement _nativeCreateTBody() native;
 $endif
 
 $!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_HTMLTableRowElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTableRowElement.darttemplate
index 431e15f..7716e37 100644
--- a/tools/dom/templates/html/impl/impl_HTMLTableRowElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLTableRowElement.darttemplate
@@ -9,12 +9,12 @@
 
   @DomName('HTMLTableRowElement.cells')
   List<TableCellElement> get cells =>
-      new _WrappedList<TableCellElement>($dom_cells);
+      new _WrappedList<TableCellElement>(_cells);
 
   TableCellElement addCell() {
     return insertCell(-1);
   }
 
-  TableCellElement insertCell(int index) => $dom_insertCell(index);
+  TableCellElement insertCell(int index) => _insertCell(index);
 
 $!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_HTMLTableSectionElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTableSectionElement.darttemplate
index 93eecde6..5f47932 100644
--- a/tools/dom/templates/html/impl/impl_HTMLTableSectionElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLTableSectionElement.darttemplate
@@ -9,12 +9,12 @@
 
   @DomName('HTMLTableSectionElement.rows')
   List<TableRowElement> get rows =>
-    new _WrappedList<TableRowElement>($dom_rows);
+    new _WrappedList<TableRowElement>(_rows);
 
   TableRowElement addRow() {
     return insertRow(-1);
   }
 
-  TableRowElement insertRow(int index) => $dom_insertRow(index);
+  TableRowElement insertRow(int index) => _insertRow(index);
 
 $!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
index 696127b..f54aef7 100644
--- a/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLTemplateElement.darttemplate
@@ -95,7 +95,7 @@
   // For real TemplateElement use the actual DOM .content field instead of
   // our polyfilled expando.
   @Experimental()
-  DocumentFragment get content => $dom_content;
+  DocumentFragment get content => _content;
 
 
   /**
@@ -289,4 +289,20 @@
 }''';
     document.head.append(style);
   }
+
+  /**
+   * An override to place the contents into content rather than as child nodes.
+   *
+   * See also:
+   *
+   * * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#innerhtml-on-templates>
+   */
+  void setInnerHtml(String html,
+    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+    text = null;
+    var fragment = createFragment(
+        html, validator: validator, treeSanitizer: treeSanitizer);
+
+    content.append(fragment);
+  }
 }
diff --git a/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate b/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
index ee18868..133ccd2 100644
--- a/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
@@ -9,8 +9,8 @@
   factory $CLASSNAME(String type,
       {bool canBubble: true, bool cancelable: true, String oldUrl,
       String newUrl}) {
-    var event = document.$dom_createEvent("HashChangeEvent");
-    event.$dom_initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
+    var event = document._createEvent("HashChangeEvent");
+    event._initHashChangeEvent(type, canBubble, cancelable, oldUrl, newUrl);
     return event;
   }
 $!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_IDBCursor.darttemplate b/tools/dom/templates/html/impl/impl_IDBCursor.darttemplate
index eeb3aa3..35ae804 100644
--- a/tools/dom/templates/html/impl/impl_IDBCursor.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBCursor.darttemplate
@@ -8,7 +8,7 @@
   @DomName('IDBCursor.delete')
   Future delete() {
    try {
-      return _completeRequest($dom_delete());
+      return _completeRequest(_delete());
     } catch (e, stacktrace) {
       return new Future.error(e, stacktrace);
     }
@@ -17,7 +17,7 @@
   @DomName('IDBCursor.value')
   Future update(value) {
    try {
-      return _completeRequest($dom_update(value));
+      return _completeRequest(_update(value));
     } catch (e, stacktrace) {
       return new Future.error(e, stacktrace);
     }
diff --git a/tools/dom/templates/html/impl/impl_IDBDatabase.darttemplate b/tools/dom/templates/html/impl/impl_IDBDatabase.darttemplate
index 65872f4..31d47ec 100644
--- a/tools/dom/templates/html/impl/impl_IDBDatabase.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBDatabase.darttemplate
@@ -18,7 +18,7 @@
       options['autoIncrement'] = autoIncrement;
     }
 
-    return $dom_createObjectStore(name, options);
+    return _createObjectStore(name, options);
   }
 
 $if DART2JS
diff --git a/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate b/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate
index d811f9a..e676f0c 100644
--- a/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate
@@ -30,9 +30,9 @@
     try {
       var request;
       if (version != null) {
-        request = $dom_open(name, version);
+        request = _open(name, version);
       } else {
-        request = $dom_open(name);
+        request = _open(name);
       }
 
       if (onUpgradeNeeded != null) {
@@ -51,7 +51,7 @@
   Future<IdbFactory> deleteDatabase(String name,
       {void onBlocked(Event)}) {
     try {
-      var request = $dom_deleteDatabase(name);
+      var request = _deleteDatabase(name);
 
       if (onBlocked != null) {
         request.onBlocked.listen(onBlocked);
@@ -74,7 +74,7 @@
   @Experimental()
   Future<List<String>> getDatabaseNames() {
     try {
-      var request = $dom_webkitGetDatabaseNames();
+      var request = _webkitGetDatabaseNames();
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
diff --git a/tools/dom/templates/html/impl/impl_IDBIndex.darttemplate b/tools/dom/templates/html/impl/impl_IDBIndex.darttemplate
index e94dffa..afba24e 100644
--- a/tools/dom/templates/html/impl/impl_IDBIndex.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBIndex.darttemplate
@@ -10,9 +10,9 @@
    try {
       var request;
       if (key_OR_range != null) {
-        request = $dom_count(key_OR_range);
+        request = _count(key_OR_range);
       } else {
-        request = $dom_count();
+        request = _count();
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -23,7 +23,7 @@
   @DomName('IDBIndex.get')
   Future get(key) {
     try {
-      var request = $dom_get(key);
+      var request = _get(key);
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -34,7 +34,7 @@
   @DomName('IDBIndex.getKey')
   Future getKey(key) {
     try {
-      var request = $dom_getKey(key);
+      var request = _getKey(key);
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -62,9 +62,9 @@
     }
     var request;
     if (direction == null) {
-      request = $dom_openCursor(key_OR_range);
+      request = _openCursor(key_OR_range);
     } else {
-      request = $dom_openCursor(key_OR_range, direction);
+      request = _openCursor(key_OR_range, direction);
     }
     return ObjectStore._cursorStreamFromResult(request, autoAdvance);
   }
@@ -89,9 +89,9 @@
     }
     var request;
     if (direction == null) {
-      request = $dom_openKeyCursor(key_OR_range);
+      request = _openKeyCursor(key_OR_range);
     } else {
-      request = $dom_openKeyCursor(key_OR_range, direction);
+      request = _openKeyCursor(key_OR_range, direction);
     }
     return ObjectStore._cursorStreamFromResult(request, autoAdvance);
   }
diff --git a/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate b/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
index 86fd006..bc55c61 100644
--- a/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
@@ -11,9 +11,9 @@
     try {
       var request;
       if (key != null) {
-        request = $dom_add(value, key);
+        request = _add(value, key);
       } else {
-        request = $dom_add(value);
+        request = _add(value);
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -24,7 +24,7 @@
   @DomName('IDBObjectStore.clear')
   Future clear() {
     try {
-      return _completeRequest($dom_clear());
+      return _completeRequest(_clear());
     } catch (e, stacktrace) {
       return new Future.error(e, stacktrace);
     }
@@ -33,7 +33,7 @@
   @DomName('IDBObjectStore.delete')
   Future delete(key_OR_keyRange){
     try {
-      return _completeRequest($dom_delete(key_OR_keyRange));
+      return _completeRequest(_delete(key_OR_keyRange));
     } catch (e, stacktrace) {
       return new Future.error(e, stacktrace);
     }
@@ -44,9 +44,9 @@
    try {
       var request;
       if (key_OR_range != null) {
-        request = $dom_count(key_OR_range);
+        request = _count(key_OR_range);
       } else {
-        request = $dom_count();
+        request = _count();
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -59,9 +59,9 @@
     try {
       var request;
       if (key != null) {
-        request = $dom_put(value, key);
+        request = _put(value, key);
       } else {
-        request = $dom_put(value);
+        request = _put(value);
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -72,7 +72,7 @@
   @DomName('IDBObjectStore.get')
   Future getObject(key) {
     try {
-      var request = $dom_get(key);
+      var request = _get(key);
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
@@ -117,9 +117,9 @@
     // TODO: try/catch this and return a stream with an immediate error.
     var request;
     if (direction == null) {
-      request = $dom_openCursor(key_OR_range);
+      request = _openCursor(key_OR_range);
     } else {
-      request = $dom_openCursor(key_OR_range, direction);
+      request = _openCursor(key_OR_range, direction);
     }
     return _cursorStreamFromResult(request, autoAdvance);
   }
@@ -134,7 +134,7 @@
       options['multiEntry'] = multiEntry;
     }
 
-    return $dom_createIndex(name, keyPath, options);
+    return _createIndex(name, keyPath, options);
   }
 
 $!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_MessageEvent.darttemplate b/tools/dom/templates/html/impl/impl_MessageEvent.darttemplate
index 41f66b3..8a16f106 100644
--- a/tools/dom/templates/html/impl/impl_MessageEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_MessageEvent.darttemplate
@@ -14,8 +14,8 @@
     if (source == null) {
       source = window;
     }
-    var event = document.$dom_createEvent("MessageEvent");
-    event.$dom_initMessageEvent(type, canBubble, cancelable, data, origin,
+    var event = document._createEvent("MessageEvent");
+    event._initMessageEvent(type, canBubble, cancelable, data, origin,
         lastEventId, source, messagePorts);
     return event;
   }
diff --git a/tools/dom/templates/html/impl/impl_MutationEvent.darttemplate b/tools/dom/templates/html/impl/impl_MutationEvent.darttemplate
index dcd6967..5460640 100644
--- a/tools/dom/templates/html/impl/impl_MutationEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_MutationEvent.darttemplate
@@ -9,8 +9,8 @@
       {bool canBubble: false, bool cancelable: false, Node relatedNode,
       String prevValue, String newValue, String attrName, int attrChange: 0}) {
 
-    var event = document.$dom_createEvent('MutationEvent');
-    event.$dom_initMutationEvent(type, canBubble, cancelable, relatedNode,
+    var event = document._createEvent('MutationEvent');
+    event._initMutationEvent(type, canBubble, cancelable, relatedNode,
         prevValue, newValue, attrName, attrChange);
     return event;
   }
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index 1eb46fa..f48bb03 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -94,7 +94,7 @@
   Node removeLast() {
     final result = last;
     if (result != null) {
-      _this.$dom_removeChild(result);
+      _this._removeChild(result);
     }
     return result;
   }
@@ -102,7 +102,7 @@
   Node removeAt(int index) {
     var result = this[index];
     if (result != null) {
-      _this.$dom_removeChild(result);
+      _this._removeChild(result);
     }
     return result;
   }
@@ -111,7 +111,7 @@
     if (object is! Node) return false;
     Node node = object;
     if (!identical(_this, node.parentNode)) return false;
-    _this.$dom_removeChild(node);
+    _this._removeChild(node);
     return true;
   }
 
@@ -123,7 +123,7 @@
     while (child != null) {
       Node nextChild = child.nextNode;
       if (test(child) == removeMatching) {
-        _this.$dom_removeChild(child);
+        _this._removeChild(child);
       }
       child = nextChild;
     }
@@ -142,7 +142,7 @@
   }
 
   void operator []=(int index, Node value) {
-    _this.$dom_replaceChild(value, this[index]);
+    _this._replaceChild(value, this[index]);
   }
 
   Iterator<Node> get iterator => _this.$dom_childNodes.iterator;
@@ -224,7 +224,7 @@
     // TODO(vsm): Use the native remove when available.
     if (this.parentNode != null) {
       final Node parent = this.parentNode;
-      parentNode.$dom_removeChild(this);
+      parentNode._removeChild(this);
     }
   }
 
@@ -235,7 +235,7 @@
   Node replaceWith(Node otherNode) {
     try {
       final Node parent = this.parentNode;
-      parent.$dom_replaceChild(otherNode, this);
+      parent._replaceChild(otherNode, this);
     } catch (e) {
 
     };
diff --git a/tools/dom/templates/html/impl/impl_NodeIterator.darttemplate b/tools/dom/templates/html/impl/impl_NodeIterator.darttemplate
index 1aba0c8..4322a1b 100644
--- a/tools/dom/templates/html/impl/impl_NodeIterator.darttemplate
+++ b/tools/dom/templates/html/impl/impl_NodeIterator.darttemplate
@@ -6,7 +6,7 @@
 
 $(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory NodeIterator(Node root, int whatToShow) {
-    return document.$dom_createNodeIterator(root, whatToShow, null, false);
+    return document._createNodeIterator(root, whatToShow, null, false);
   }
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/impl/impl_Range.darttemplate b/tools/dom/templates/html/impl/impl_Range.darttemplate
index f023343..1f3013a 100644
--- a/tools/dom/templates/html/impl/impl_Range.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Range.darttemplate
@@ -10,7 +10,7 @@
   factory $CLASSNAME() => document.$dom_createRange();
 
   factory $CLASSNAME.fromPoint(Point point) =>
-      document.$dom_caretRangeFromPoint(point.x, point.y);
+      document._caretRangeFromPoint(point.x, point.y);
 $!MEMBERS
 
   /**
diff --git a/tools/dom/templates/html/impl/impl_SVGElement.darttemplate b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
index 02963d7..576854b 100644
--- a/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
@@ -31,10 +31,28 @@
 }
 
 $(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+  static final _START_TAG_REGEXP = new RegExp('<(\\w+)');
+
   factory $CLASSNAME.tag(String tag) =>
-      _$(CLASSNAME)FactoryProvider.create$(CLASSNAME)_tag(tag);
-  factory $CLASSNAME.svg(String svg) =>
-      _$(CLASSNAME)FactoryProvider.create$(CLASSNAME)_svg(svg);
+      document.$dom_createElementNS("http://www.w3.org/2000/svg", tag);
+  factory $CLASSNAME.svg(String svg,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+
+    if (validator == null && treeSanitizer == null) {
+      validator = new NodeValidatorBuilder.common()..allowSvg();
+    }
+
+    final match = _START_TAG_REGEXP.firstMatch(svg);
+    var parentElement;
+    if (match != null && match.group(1).toLowerCase() == 'svg') {
+      parentElement = document.body;
+    } else {
+      parentElement = new SvgSvgElement();
+    }
+    var fragment = parentElement.createFragment(svg, validator: validator,
+        treeSanitizer: treeSanitizer);
+    return fragment.nodes.where((e) => e is SvgElement).single;
+  }
 
   _AttributeClassSet _cssClassSet;
   CssClassSet get classes {
@@ -66,12 +84,33 @@
     return container.innerHtml;
   }
 
-  void set innerHtml(String svg) {
-    final container = new Element.tag("div");
-    // Wrap the SVG string in <svg> so that SvgElements are created, rather than
-    // HTMLElements.
-    container.innerHtml = '<svg version="1.1">$svg</svg>';
-    this.children = container.children[0].children;
+  void set innerHtml(String value) {
+    this.setInnerHtml(value);
+  }
+
+  DocumentFragment createFragment(String svg,
+      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
+
+    if (treeSanitizer == null) {
+      if (validator == null) {
+        validator = new NodeValidatorBuilder.common()
+          ..allowSvg();
+      }
+      treeSanitizer = new NodeTreeSanitizer(validator);
+    }
+
+    // We create a fragment which will parse in the HTML parser
+    var html = '<svg version="1.1">$svg</svg>';
+    var fragment = document.body.createFragment(html,
+        treeSanitizer: treeSanitizer);
+
+    var svgFragment = new DocumentFragment();
+    // The root is the <svg/> element, need to pull out the contents.
+    var root = fragment.nodes.single;
+    while (root.firstChild != null) {
+      svgFragment.append(root.firstChild);
+    }
+    return svgFragment;
   }
 
   // Unsupported methods inherited from Element.
@@ -91,8 +130,8 @@
     throw new UnsupportedError("Cannot invoke insertAdjacentElement on SVG.");
   }
 
-  HtmlCollection get $dom_children {
-    throw new UnsupportedError("Cannot get dom_children on SVG.");
+  HtmlCollection get _children {
+    throw new UnsupportedError("Cannot get _children on SVG.");
   }
 
   bool get isContentEditable => false;
diff --git a/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate b/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate
index 9f07087..13eabab 100644
--- a/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate
@@ -5,7 +5,12 @@
 part of $LIBRARYNAME;
 
 $(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
-  factory $CLASSNAME() => _$(CLASSNAME)FactoryProvider.createSvgSvgElement();
+  factory $CLASSNAME() {
+    final el = new SvgElement.tag("svg");
+    // The SVG spec requires the version attribute to match the spec version
+    el.attributes['version'] = "1.1";
+    return el;
+  }
 
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/impl/impl_Screen.darttemplate b/tools/dom/templates/html/impl/impl_Screen.darttemplate
index 227c0d7..601f160 100644
--- a/tools/dom/templates/html/impl/impl_Screen.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Screen.darttemplate
@@ -11,6 +11,6 @@
   @DomName('Screen.availLeft')
   @DomName('Screen.availTop')
   @DomName('Screen.availWidth')
-  Rect get available => new Rect($dom_availLeft, $dom_availTop, $dom_availWidth,
-      $dom_availHeight);
+  Rect get available => new Rect(_availLeft, _availTop, _availWidth,
+      _availHeight);
 $!MEMBERS}
diff --git a/tools/dom/templates/html/impl/impl_Storage.darttemplate b/tools/dom/templates/html/impl/impl_Storage.darttemplate
index 9e48ff9..d9b0e1a 100644
--- a/tools/dom/templates/html/impl/impl_Storage.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Storage.darttemplate
@@ -35,11 +35,11 @@
   // TODO(nweiz): update this when maps support lazy iteration
   bool containsValue(String value) => values.any((e) => e == value);
 
-  bool containsKey(String key) => $dom_getItem(key) != null;
+  bool containsKey(String key) => _getItem(key) != null;
 
-  String operator [](String key) => $dom_getItem(key);
+  String operator [](String key) => _getItem(key);
 
-  void operator []=(String key, String value) { $dom_setItem(key, value); }
+  void operator []=(String key, String value) { _setItem(key, value); }
 
   String putIfAbsent(String key, String ifAbsent()) {
     if (!containsKey(key)) this[key] = ifAbsent();
@@ -48,15 +48,15 @@
 
   String remove(String key) {
     final value = this[key];
-    $dom_removeItem(key);
+    _removeItem(key);
     return value;
   }
 
-  void clear() => $dom_clear();
+  void clear() => _clear();
 
   void forEach(void f(String key, String value)) {
     for (var i = 0; true; i++) {
-      final key = $dom_key(i);
+      final key = _key(i);
       if (key == null) return;
 
       f(key, this[key]);
@@ -75,9 +75,9 @@
     return values;
   }
 
-  int get length => $dom_length;
+  int get length => _length;
 
-  bool get isEmpty => $dom_key(0) == null;
+  bool get isEmpty => _key(0) == null;
 
   bool get isNotEmpty => !isEmpty;
 $!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_StorageEvent.darttemplate b/tools/dom/templates/html/impl/impl_StorageEvent.darttemplate
index acd8d88..df91c56 100644
--- a/tools/dom/templates/html/impl/impl_StorageEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_StorageEvent.darttemplate
@@ -11,8 +11,8 @@
     {bool canBubble: false, bool cancelable: false, String key, String oldValue,
     String newValue, String url, Storage storageArea}) {
 
-    var e = document.$dom_createEvent("StorageEvent");
-    e.$dom_initStorageEvent(type, canBubble, cancelable, key, oldValue,
+    var e = document._createEvent("StorageEvent");
+    e._initStorageEvent(type, canBubble, cancelable, key, oldValue,
         newValue, url, storageArea);
     return e;
   }
diff --git a/tools/dom/templates/html/impl/impl_Text.darttemplate b/tools/dom/templates/html/impl/impl_Text.darttemplate
index cf455bb..7540799 100644
--- a/tools/dom/templates/html/impl/impl_Text.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Text.darttemplate
@@ -7,6 +7,6 @@
 part of $LIBRARYNAME;
 
 $(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
-  factory $CLASSNAME(String data) => document.$dom_createTextNode(data);
+  factory $CLASSNAME(String data) => document._createTextNode(data);
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/impl/impl_TextEvent.darttemplate b/tools/dom/templates/html/impl/impl_TextEvent.darttemplate
index 81332b6..765a280 100644
--- a/tools/dom/templates/html/impl/impl_TextEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_TextEvent.darttemplate
@@ -12,8 +12,8 @@
     if (view == null) {
       view = window;
     }
-    var e = document.$dom_createEvent("TextEvent");
-    e.$dom_initTextEvent(type, canBubble, cancelable, view, data);
+    var e = document._createEvent("TextEvent");
+    e._initTextEvent(type, canBubble, cancelable, view, data);
     return e;
   }
 $!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_Touch.darttemplate b/tools/dom/templates/html/impl/impl_Touch.darttemplate
index ed6690a..1c14ff7 100644
--- a/tools/dom/templates/html/impl/impl_Touch.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Touch.darttemplate
@@ -10,13 +10,13 @@
 
   @DomName('Touch.clientX')
   @DomName('Touch.clientY')
-  Point get client => new Point($dom_clientX, $dom_clientY);
+  Point get client => new Point(_clientX, _clientY);
 
   @DomName('Touch.pageX')
   @DomName('Touch.pageY')
-  Point get page => new Point($dom_pageX, $dom_pageY);
+  Point get page => new Point(_pageX, _pageY);
 
   @DomName('Touch.screenX')
   @DomName('Touch.screenY')
-  Point get screen => new Point($dom_screenX, $dom_screenY);
+  Point get screen => new Point(_screenX, _screenY);
 }
diff --git a/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate b/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
index 0a6816b..af426b5 100644
--- a/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
@@ -15,8 +15,8 @@
     if (view == null) {
       view = window;
     }
-    var e = document.$dom_createEvent("TouchEvent");
-    e.$dom_initTouchEvent(touches, targetTouches, changedTouches, type, view,
+    var e = document._createEvent("TouchEvent");
+    e._initTouchEvent(touches, targetTouches, changedTouches, type, view,
         screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey);
     return e;
   }
diff --git a/tools/dom/templates/html/impl/impl_TouchList.darttemplate b/tools/dom/templates/html/impl/impl_TouchList.darttemplate
index 5bb4530..d984852 100644
--- a/tools/dom/templates/html/impl/impl_TouchList.darttemplate
+++ b/tools/dom/templates/html/impl/impl_TouchList.darttemplate
@@ -10,6 +10,6 @@
   /// NB: This constructor likely does not work as you might expect it to! This
   /// constructor will simply fail (returning null) if you are not on a device
   /// with touch enabled. See dartbug.com/8314.
-  factory $CLASSNAME() => document.$dom_createTouchList();
+  factory $CLASSNAME() => document._createTouchList();
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/impl/impl_TreeWalker.darttemplate b/tools/dom/templates/html/impl/impl_TreeWalker.darttemplate
index 6fd1eab..6861cd1 100644
--- a/tools/dom/templates/html/impl/impl_TreeWalker.darttemplate
+++ b/tools/dom/templates/html/impl/impl_TreeWalker.darttemplate
@@ -6,7 +6,7 @@
 
 $(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory TreeWalker(Node root, int whatToShow) {
-    return document.$dom_createTreeWalker(root, whatToShow, null, false);
+    return document._createTreeWalker(root, whatToShow, null, false);
   }
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/impl/impl_UIEvent.darttemplate b/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
index 9714716..034a510 100644
--- a/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
@@ -19,8 +19,8 @@
     if (view == null) {
       view = window;
     }
-    final e = document.$dom_createEvent("UIEvent");
-    e.$dom_initUIEvent(type, canBubble, cancelable, view, detail);
+    final e = document._createEvent("UIEvent");
+    e._initUIEvent(type, canBubble, cancelable, view, detail);
     return e;
   }
 $!MEMBERS
@@ -37,9 +37,9 @@
 
   @DomName('UIEvent.layerX')
   @DomName('UIEvent.layerY')
-  Point get layer => new Point($dom_layerX, $dom_layerY);
+  Point get layer => new Point(_layerX, _layerY);
 
   @DomName('UIEvent.pageX')
   @DomName('UIEvent.pageY')
-  Point get page => new Point($dom_pageX, $dom_pageY);
+  Point get page => new Point(_pageX, _pageY);
 }
diff --git a/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate b/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
index ae34ac7..a11cb22 100644
--- a/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
@@ -20,7 +20,7 @@
     if (Device.isFirefox) {
       eventType = 'MouseScrollEvents';
     }
-    final event = document.$dom_createEvent(eventType);
+    final event = document._createEvent(eventType);
 $if DART2JS
     // If polyfilling, then flip these because we'll flip them back to match
     // the W3C standard:
@@ -71,10 +71,10 @@
     deltaY = -deltaY;
 $endif
       // Fallthrough for Dartium.
-      event.$dom_initMouseEvent(type, canBubble, cancelable, view, detail,
+      event._initMouseEvent(type, canBubble, cancelable, view, detail,
           screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
           metaKey, button, relatedTarget);
-      event.$dom_initWebKitWheelEvent(deltaX,
+      event._initWebKitWheelEvent(deltaX,
           deltaY ~/ 120, // Chrome does an auto-convert to pixels.
           view, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
           metaKey);
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index 4c78373..a4e2195 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -48,6 +48,15 @@
   }
 
   /**
+   * Deregister 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 deregisterPort(String name) {
+    document.documentElement.attributes.remove('dart-port:$name');
+  }
+
+  /**
    * Returns a Future that completes just before the window is about to
    * repaint so the user can draw an animation frame.
    *
@@ -279,13 +288,13 @@
   Stream<Event> get onBeforeUnload => beforeUnloadEvent.forTarget(this);
 
   void moveTo(Point p) {
-    $dom_moveTo(p.x, p.y);
+    _moveTo(p.x, p.y);
   }
 
 $if DART2JS
-  int get scrollX => JS('bool', '("scrollX" in #)', this) ? JS('int', 
+  int get scrollX => JS('bool', '("scrollX" in #)', this) ? JS('int',
       '#.scrollX', this) : document.documentElement.scrollLeft;
-  int get scrollY => JS('bool', '("scrollY" in #)', this) ? JS('int', 
+  int get scrollY => JS('bool', '("scrollY" in #)', this) ? JS('int',
       '#.scrollY', this) : document.documentElement.scrollTop;
 $endif
 }
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index 4a6a45e..aa47fc8 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -221,5 +221,44 @@
 $endif
   }
 
+  /**
+   * Makes a cross-origin request to the specified URL.
+   *
+   * This API provides a subset of [request] which works on IE9. If IE9
+   * cross-origin support is not required then [request] should be used instead.
+   */
+  @Experimental()
+  static Future<String> requestCrossOrigin(String url,
+      {String method, String sendData}) {
+    if (supportsCrossOrigin) {
+      return request(url, method: method, sendData: sendData).then((xhr) {
+        return xhr.responseText;
+      });
+    }
+$if DART2JS
+    var completer = new Completer<String>();
+    if (method == null) {
+      method = 'GET';
+    }
+    var xhr = JS('var', 'new XDomainRequest()');
+    JS('', '#.open(#, #)', xhr, method, url);
+    JS('', '#.onload = #', xhr, convertDartClosureToJS((e) {
+      var response = JS('String', '#.responseText', xhr);
+      completer.complete(response);
+    }, 1));
+    JS('', '#.onerror = #', xhr, convertDartClosureToJS((e) {
+      completer.completeError(e);
+    }, 1));
+
+    if (sendData != null) {
+      JS('', '#.send(#)', xhr, sendData);
+    } else {
+      JS('', '#.send()', xhr);
+    }
+
+    return completer.future;
+$endif
+  }
+
 $!MEMBERS
 }
diff --git a/tools/publish_all_pkgs.py b/tools/publish_all_pkgs.py
index 81aab97..a43f57b 100644
--- a/tools/publish_all_pkgs.py
+++ b/tools/publish_all_pkgs.py
@@ -17,11 +17,13 @@
 import subprocess
 import sys
 
+BLACK_LISTED_DIRECTORIES = ['.svn', 'async_helper', 'expect', 'third_party'];
+
 def Main(argv):
   for pkgdir in ['pkg', 'pkg/third_party']:
     for name in os.listdir(pkgdir):
       if os.path.isdir(os.path.join(pkgdir, name)):
-        if (name != '.svn' and name != 'expect' and name != 'third_party'):
+        if name not in BLACK_LISTED_DIRECTORIES:
           pkgs_to_publish.append(os.path.join(pkgdir, name))
 
   for pkg in pkgs_to_publish:
diff --git a/tools/test.dart b/tools/test.dart
index 154d0ee..24da3d2 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -267,7 +267,7 @@
       var dir = new Directory('').createTempSync();
       var path = new Path(dir.path).directoryPath;
       dir.deleteSync();
-      return new Directory.fromPath(path);
+      return new Directory(path.toNativePath());
     }
 
     // These are the patterns of temporary directory names created by
diff --git a/tools/testing/dart/android.dart b/tools/testing/dart/android.dart
index 8f79ab4..60dcc48 100644
--- a/tools/testing/dart/android.dart
+++ b/tools/testing/dart/android.dart
@@ -4,10 +4,10 @@
 
 library android;
 
-import "dart:io";
 import "dart:async";
+import "dart:convert" show LineSplitter, UTF8;
 import "dart:core";
-import "dart:utf";
+import "dart:io";
 
 import "utils.dart";
 
@@ -35,7 +35,7 @@
                           List<String> args,
                           [String stdin = ""]) {
   Future<String> getOutput(Stream<List<int>> stream) {
-    return stream.transform(new StringDecoder()).toList()
+    return stream.transform(UTF8.decoder).toList()
         .then((data) => data.join(""));
   }
 
@@ -112,7 +112,7 @@
 
   AndroidEmulator._private(this._port, this._adbDevice, this._emulatorProcess) {
     Stream<String> getLines(Stream s) {
-      return s.transform(new StringDecoder()).transform(new LineTransformer());
+      return s.transform(UTF8.decoder).transform(new LineSplitter());
     }
 
     getLines(_emulatorProcess.stdout).listen((line) {
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index 214a765..26569fb 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -4,6 +4,7 @@
 library browser;
 
 import "dart:async";
+import "dart:convert" show LineSplitter, UTF8;
 import "dart:core";
 import "dart:io";
 
@@ -119,7 +120,7 @@
       Completer stdoutDone = new Completer();
       Completer stderrDone = new Completer();
 
-      process.stdout.transform(new StringDecoder()).listen((data) {
+      process.stdout.transform(UTF8.decoder).listen((data) {
         _addStdout(data);
       }, onError: (error) {
         // This should _never_ happen, but we really want this in the log
@@ -129,7 +130,7 @@
         stdoutDone.complete(true);
       });
 
-      process.stderr.transform(new StringDecoder()).listen((data) {
+      process.stderr.transform(UTF8.decoder).listen((data) {
         _addStderr(data);
       }, onError: (error) {
         // This should _never_ happen, but we really want this in the log
@@ -410,7 +411,7 @@
 
     var testing_resources_dir =
         new Path('third_party/android_testing_resources');
-    if (!new Directory.fromPath(testing_resources_dir).existsSync()) {
+    if (!new Directory(testing_resources_dir.toNativePath()).existsSync()) {
       DebugLogger.error("$testing_resources_dir doesn't exist. Exiting now.");
       exit(1);
     }
@@ -881,7 +882,7 @@
         errorReportingServer = createdReportServer;
         void errorReportingHandler(HttpRequest request) {
           StringBuffer buffer = new StringBuffer();
-          request.transform(new StringDecoder()).listen((data) {
+          request.transform(UTF8.decoder).listen((data) {
             buffer.write(data);
           }, onDone: () {
               String back = buffer.toString();
@@ -904,7 +905,7 @@
 
   void handleReport(HttpRequest request, String browserId, var testId) {
     StringBuffer buffer = new StringBuffer();
-    request.transform(new StringDecoder()).listen((data) {
+    request.transform(UTF8.decoder).listen((data) {
       buffer.write(data);
       }, onDone: () {
         String back = buffer.toString();
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index 547e4d0..994d0f2 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -17,10 +17,12 @@
 library co19_test;
 
 import "dart:io";
-import "test_runner.dart";
+
 import "test_options.dart";
-import "test_suite.dart";
 import "test_progress.dart";
+import "test_runner.dart";
+import "test_suite.dart";
+import "utils.dart" show Path;
 import "../../test.dart" as test_dart;
 
 import "../../../tests/co19/test_config.dart";
diff --git a/tools/testing/dart/drt_updater.dart b/tools/testing/dart/drt_updater.dart
index ea86b4a..73af52d 100644
--- a/tools/testing/dart/drt_updater.dart
+++ b/tools/testing/dart/drt_updater.dart
@@ -10,6 +10,7 @@
 import "dart:io";
 
 import "test_suite.dart";
+import "utils.dart" show Path;
 
 class _DartiumUpdater {
   String name;
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index 720350e..9348763 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -172,12 +172,12 @@
                          "max-age=$_CACHE_EXPIRATION_IN_SECONDS");
     var path = _getFilePathFromRequestPath(request.uri.path);
     if (path != null) {
-      var file = new File.fromPath(path);
+      var file = new File(path.toNativePath());
       file.exists().then((exists) {
         if (exists) {
           _sendFileContent(request, response, allowedPort, path, file);
         } else {
-          var directory = new Directory.fromPath(path);
+          var directory = new Directory(path.toNativePath());
           directory.exists().then((exists) {
             if (exists) {
               _listDirectory(directory).then((entries) {
diff --git a/tools/testing/dart/legacy_path.dart b/tools/testing/dart/legacy_path.dart
new file mode 100644
index 0000000..73ad68c
--- /dev/null
+++ b/tools/testing/dart/legacy_path.dart
@@ -0,0 +1,309 @@
+// Copyright (c) 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 utils;
+
+class Path {
+  final String _path;
+  final bool isWindowsShare;
+
+  Path(String source)
+      : _path = _clean(source), isWindowsShare = _isWindowsShare(source);
+
+  Path.raw(String source) : _path = source, isWindowsShare = false;
+
+  Path._internal(String this._path, bool this.isWindowsShare);
+
+  static String _clean(String source) {
+    if (Platform.operatingSystem == 'windows') return _cleanWindows(source);
+    return source;
+  }
+
+  static String _cleanWindows(String source) {
+    // Change \ to /.
+    var clean = source.replaceAll('\\', '/');
+    // Add / before intial [Drive letter]:
+    if (clean.length >= 2 && clean[1] == ':') {
+      clean = '/$clean';
+    }
+    if (_isWindowsShare(source)) {
+      return clean.substring(1, clean.length);
+    }
+    return clean;
+  }
+
+  static bool _isWindowsShare(String source) {
+    return Platform.operatingSystem == 'windows' && source.startsWith('\\\\');
+  }
+
+  int get hashCode => _path.hashCode;
+  bool get isEmpty => _path.isEmpty;
+  bool get isAbsolute => _path.startsWith('/');
+  bool get hasTrailingSeparator => _path.endsWith('/');
+
+  String toString() => _path;
+
+  Path relativeTo(Path base) {
+    // Returns a path "relative" such that
+    // base.join(relative) == this.canonicalize.
+    // Throws exception if an impossible case is reached.
+    if (base.isAbsolute != isAbsolute ||
+        base.isWindowsShare != isWindowsShare) {
+      throw new ArgumentError(
+          "Invalid case of Path.relativeTo(base):\n"
+          "  Path and base must both be relative, or both absolute.\n"
+          "  Arguments: $_path.relativeTo($base)");
+    }
+
+    var basePath = base.toString();
+    // Handle drive letters specially on Windows.
+    if (base.isAbsolute && Platform.operatingSystem == 'windows') {
+      bool baseHasDrive =
+          basePath.length >= 4 && basePath[2] == ':' && basePath[3] == '/';
+      bool pathHasDrive =
+          _path.length >= 4 && _path[2] == ':' && _path[3] == '/';
+      if (baseHasDrive && pathHasDrive) {
+        int baseDrive = basePath.codeUnitAt(1) | 32;  // Convert to uppercase.
+        if (baseDrive >= 'a'.codeUnitAt(0) &&
+            baseDrive <= 'z'.codeUnitAt(0) &&
+            baseDrive == (_path.codeUnitAt(1) | 32)) {
+          if(basePath[1] != _path[1]) {
+            // Replace the drive letter in basePath with that from _path.
+            basePath = '/${_path[1]}:/${basePath.substring(4)}';
+            base = new Path(basePath);
+          }
+        } else {
+          throw new ArgumentError(
+              "Invalid case of Path.relativeTo(base):\n"
+              "  Base path and target path are on different Windows drives.\n"
+              "  Arguments: $_path.relativeTo($base)");
+        }
+      } else if (baseHasDrive != pathHasDrive) {
+        throw new ArgumentError(
+            "Invalid case of Path.relativeTo(base):\n"
+            "  Base path must start with a drive letter if and "
+            "only if target path does.\n"
+            "  Arguments: $_path.relativeTo($base)");
+      }
+
+    }
+    if (_path.startsWith(basePath)) {
+      if (_path == basePath) return new Path('.');
+      // There must be a '/' at the end of the match, or immediately after.
+      int matchEnd = basePath.length;
+      if (_path[matchEnd - 1] == '/' || _path[matchEnd] == '/') {
+        // Drop any extra '/' characters at matchEnd
+        while (matchEnd < _path.length && _path[matchEnd] == '/') {
+          matchEnd++;
+        }
+        return new Path(_path.substring(matchEnd)).canonicalize();
+      }
+    }
+
+    List<String> baseSegments = base.canonicalize().segments();
+    List<String> pathSegments = canonicalize().segments();
+    if (baseSegments.length == 1 && baseSegments[0] == '.') {
+      baseSegments = [];
+    }
+    if (pathSegments.length == 1 && pathSegments[0] == '.') {
+      pathSegments = [];
+    }
+    int common = 0;
+    int length = min(pathSegments.length, baseSegments.length);
+    while (common < length && pathSegments[common] == baseSegments[common]) {
+      common++;
+    }
+    final segments = new List<String>();
+
+    if (common < baseSegments.length && baseSegments[common] == '..') {
+      throw new ArgumentError(
+          "Invalid case of Path.relativeTo(base):\n"
+          "  Base path has more '..'s than path does.\n"
+          "  Arguments: $_path.relativeTo($base)");
+    }
+    for (int i = common; i < baseSegments.length; i++) {
+      segments.add('..');
+    }
+    for (int i = common; i < pathSegments.length; i++) {
+      segments.add('${pathSegments[i]}');
+    }
+    if (segments.isEmpty) {
+      segments.add('.');
+    }
+    if (hasTrailingSeparator) {
+        segments.add('');
+    }
+    return new Path(segments.join('/'));
+  }
+
+
+  Path join(Path further) {
+    if (further.isAbsolute) {
+      throw new ArgumentError(
+          "Path.join called with absolute Path as argument.");
+    }
+    if (isEmpty) {
+      return further.canonicalize();
+    }
+    if (hasTrailingSeparator) {
+      var joined = new Path._internal('$_path${further}', isWindowsShare);
+      return joined.canonicalize();
+    }
+    var joined = new Path._internal('$_path/${further}', isWindowsShare);
+    return joined.canonicalize();
+  }
+
+  // Note: The URI RFC names for canonicalize, join, and relativeTo
+  // are normalize, resolve, and relativize.  But resolve and relativize
+  // drop the last segment of the base path (the filename), on URIs.
+  Path canonicalize() {
+    if (isCanonical) return this;
+    return makeCanonical();
+  }
+
+  bool get isCanonical {
+    // Contains no consecutive path separators.
+    // Contains no segments that are '.'.
+    // Absolute paths have no segments that are '..'.
+    // All '..' segments of a relative path are at the beginning.
+    if (isEmpty) return false;  // The canonical form of '' is '.'.
+    if (_path == '.') return true;
+    List segs = _path.split('/');  // Don't mask the getter 'segments'.
+    if (segs[0] == '') {  // Absolute path
+      segs[0] = null;  // Faster than removeRange().
+    } else {  // A canonical relative path may start with .. segments.
+      for (int pos = 0;
+           pos < segs.length && segs[pos] == '..';
+           ++pos) {
+        segs[pos] = null;
+      }
+    }
+    if (segs.last == '') segs.removeLast();  // Path ends with /.
+    // No remaining segments can be ., .., or empty.
+    return !segs.any((s) => s == '' || s == '.' || s == '..');
+  }
+
+  Path makeCanonical() {
+    bool isAbs = isAbsolute;
+    List segs = segments();
+    String drive;
+    if (isAbs &&
+        !segs.isEmpty &&
+        segs[0].length == 2 &&
+        segs[0][1] == ':') {
+      drive = segs[0];
+      segs.removeRange(0, 1);
+    }
+    List newSegs = [];
+    for (String segment in segs) {
+      switch (segment) {
+        case '..':
+          // Absolute paths drop leading .. markers, including after a drive.
+          if (newSegs.isEmpty) {
+            if (isAbs) {
+              // Do nothing: drop the segment.
+            } else {
+              newSegs.add('..');
+            }
+          } else if (newSegs.last == '..') {
+            newSegs.add('..');
+          } else {
+            newSegs.removeLast();
+          }
+          break;
+        case '.':
+        case '':
+          // Do nothing - drop the segment.
+          break;
+        default:
+          newSegs.add(segment);
+          break;
+      }
+    }
+
+    List segmentsToJoin = [];
+    if (isAbs) {
+      segmentsToJoin.add('');
+      if (drive != null) {
+        segmentsToJoin.add(drive);
+      }
+    }
+
+    if (newSegs.isEmpty) {
+      if (isAbs) {
+        segmentsToJoin.add('');
+      } else {
+        segmentsToJoin.add('.');
+      }
+    } else {
+      segmentsToJoin.addAll(newSegs);
+      if (hasTrailingSeparator) {
+        segmentsToJoin.add('');
+      }
+    }
+    return new Path._internal(segmentsToJoin.join('/'), isWindowsShare);
+  }
+
+  String toNativePath() {
+    if (isEmpty) return '.';
+    if (Platform.operatingSystem == 'windows') {
+      String nativePath = _path;
+      // Drop '/' before a drive letter.
+      if (nativePath.length >= 3 &&
+          nativePath.startsWith('/') &&
+          nativePath[2] == ':') {
+        nativePath = nativePath.substring(1);
+      }
+      nativePath = nativePath.replaceAll('/', '\\');
+      if (isWindowsShare) {
+        return '\\$nativePath';
+      }
+      return nativePath;
+    }
+    return _path;
+  }
+
+  List<String> segments() {
+    List result = _path.split('/');
+    if (isAbsolute) result.removeRange(0, 1);
+    if (hasTrailingSeparator) result.removeLast();
+    return result;
+  }
+
+  Path append(String finalSegment) {
+    if (isEmpty) {
+      return new Path._internal(finalSegment, isWindowsShare);
+    } else if (hasTrailingSeparator) {
+      return new Path._internal('$_path$finalSegment', isWindowsShare);
+    } else {
+      return new Path._internal('$_path/$finalSegment', isWindowsShare);
+    }
+  }
+
+  String get filenameWithoutExtension {
+    var name = filename;
+    if (name == '.' || name == '..') return name;
+    int pos = name.lastIndexOf('.');
+    return (pos < 0) ? name : name.substring(0, pos);
+  }
+
+  String get extension {
+    var name = filename;
+    int pos = name.lastIndexOf('.');
+    return (pos < 0) ? '' : name.substring(pos + 1);
+  }
+
+  Path get directoryPath {
+    int pos = _path.lastIndexOf('/');
+    if (pos < 0) return new Path('');
+    while (pos > 0 && _path[pos - 1] == '/') --pos;
+    var dirPath = (pos > 0) ? _path.substring(0, pos) : '/';
+    return new Path._internal(dirPath, isWindowsShare);
+  }
+
+  String get filename {
+    int pos = _path.lastIndexOf('/');
+    return _path.substring(pos + 1);
+  }
+}
diff --git a/tools/testing/dart/multitest.dart b/tools/testing/dart/multitest.dart
index da61f9d..fc85e79 100644
--- a/tools/testing/dart/multitest.dart
+++ b/tools/testing/dart/multitest.dart
@@ -65,7 +65,7 @@
   // Read the entire file into a byte buffer and transform it to a
   // String. This will treat the file as ascii but the only parts
   // we are interested in will be ascii in any case.
-  List bytes = new File.fromPath(filePath).readAsBytesSync();
+  List bytes = new File(filePath.toNativePath()).readAsBytesSync();
   String contents = decodeUtf8(bytes);
   int first_newline = contents.indexOf('\n');
   final String line_separator =
@@ -166,7 +166,7 @@
     var thisPass = toSearch;
     toSearch = new Set<Path>();
     for (Path filename in thisPass) {
-      File f = new File.fromPath(filename);
+      File f = new File(filename.toNativePath());
       for (String line in f.readAsLinesSync()) {
         Match match = relativeImportRegExp.firstMatch(line);
         if (match != null) {
@@ -222,7 +222,7 @@
     for (String key in tests.keys) {
       final Path multitestFilename =
           targetDir.append('${baseFilename}_$key.dart');
-      final File file = new File.fromPath(multitestFilename);
+      final File file = new File(multitestFilename.toNativePath());
 
       file.createSync();
       RandomAccessFile openedFile = file.openSync(mode: FileMode.WRITE);
diff --git a/tools/testing/dart/record_and_replay.dart b/tools/testing/dart/record_and_replay.dart
index 60fbedb..7cfc400 100644
--- a/tools/testing/dart/record_and_replay.dart
+++ b/tools/testing/dart/record_and_replay.dart
@@ -9,6 +9,7 @@
 import 'dart:utf';
 
 import 'test_runner.dart';
+import 'utils.dart' show Path;
 
 /*
  * Json files look like this:
@@ -74,7 +75,7 @@
   }
 
   void finish() {
-    var file = new File.fromPath(_outputPath);
+    var file = new File(_outputPath.toNativePath());
     var jsonString = json.stringify(_recordedCommandInvocations);
     file.writeAsStringSync(jsonString);
     print("TestCaseRecorder: written all TestCases to ${_outputPath}");
@@ -90,7 +91,7 @@
   }
 
   void loadFromPath(Path recordingPath) {
-    var file = new File.fromPath(recordingPath);
+    var file = new File(recordingPath.toNativePath());
     var commandRecordings = json.parse(file.readAsStringSync());
     _commandOutputRecordings = {};
     for (var commandRecording in commandRecordings) {
diff --git a/tools/testing/dart/status_file_parser.dart b/tools/testing/dart/status_file_parser.dart
index 3c07ff4..b505799 100644
--- a/tools/testing/dart/status_file_parser.dart
+++ b/tools/testing/dart/status_file_parser.dart
@@ -5,6 +5,7 @@
 library status_file_parser;
 
 import "dart:async";
+import "dart:convert" show LineSplitter, UTF8;
 import "dart:io";
 import "status_expression.dart";
 
@@ -75,8 +76,8 @@
   }
   Stream<String> lines =
       file.openRead()
-          .transform(new StringDecoder())
-          .transform(new LineTransformer());
+          .transform(UTF8.decoder)
+          .transform(new LineSplitter());
 
   Section current = new Section.always();
   sections.add(current);
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index d0b5aef..104f88c 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -338,7 +338,7 @@
   void allDone() {
     var count = 0;
     var systemTempDir = _tempDir();
-    var lister = new Directory.fromPath(systemTempDir).list().listen(
+    var lister = new Directory(systemTempDir.toNativePath()).list().listen(
         (FileSystemEntity fse) {
           if (fse is Directory) count++;
         },
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index edc65e8..d7bda75 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -13,6 +13,7 @@
 
 import "dart:async";
 import "dart:collection" show Queue;
+import "dart:convert" show LineSplitter, UTF8;
 // We need to use the 'io' prefix here, otherwise io.exitCode will shadow
 // CommandOutput.exitCode in subclasses of CommandOutput.
 import "dart:io" as io;
@@ -156,7 +157,7 @@
   String toString() => commandLine;
 
   Future<bool> get outputIsUpToDate => new Future.value(false);
-  io.Path get expectedOutputFile => null;
+  Path get expectedOutputFile => null;
   bool get isPixelTest => false;
 }
 
@@ -182,7 +183,7 @@
     if (_neverSkipCompilation) return new Future.value(false);
 
     Future<List<Uri>> readDepsFile(String path) {
-      var file = new io.File(new io.Path(path).toNativePath());
+      var file = new io.File(new Path(path).toNativePath());
       if (!file.existsSync()) {
         return new Future.value(null);
       }
@@ -250,13 +251,13 @@
    * This is used for example for pixel tests, where [expectedOutputPath] points
    * to a *png file.
    */
-  io.Path expectedOutputPath;
+  Path expectedOutputPath;
 
   ContentShellCommand._(String executable,
                         String htmlFile,
                         List<String> options,
                         List<String> dartFlags,
-                        io.Path this.expectedOutputPath,
+                        Path this.expectedOutputPath,
                         String configurationDir)
       : super._("content_shell",
                executable,
@@ -282,7 +283,7 @@
     return arguments;
   }
 
-  io.Path get expectedOutputFile => expectedOutputPath;
+  Path get expectedOutputFile => expectedOutputPath;
   bool get isPixelTest => (expectedOutputFile != null &&
                            expectedOutputFile.filename.endsWith(".png"));
 
@@ -389,7 +390,7 @@
                                              String htmlFile,
                                              List<String> options,
                                              List<String> dartFlags,
-                                             io.Path expectedOutputPath,
+                                             Path expectedOutputPath,
                                              String configurationDir) {
     ContentShellCommand command = new ContentShellCommand._(
         executable, htmlFile, options, dartFlags, expectedOutputPath,
@@ -778,7 +779,7 @@
      * On a layout tests, the DRT output is directly compared with the
      * content of the expected output.
      */
-    var file = new io.File.fromPath(command.expectedOutputFile);
+    var file = new io.File(command.expectedOutputFile.toNativePath());
     if (file.existsSync()) {
       var bytesContentLength = "Content-Length:".codeUnits;
       var bytesNewLine = "\n".codeUnits;
@@ -1380,8 +1381,8 @@
 
       var _stdoutStream =
           _process.stdout
-              .transform(new io.StringDecoder())
-              .transform(new io.LineTransformer());
+              .transform(UTF8.decoder)
+              .transform(new LineSplitter());
       _stdoutSubscription = _stdoutStream.listen((String line) {
         if (line.startsWith('>>> TEST')) {
           _status = line;
@@ -1403,8 +1404,8 @@
 
       var _stderrStream =
           _process.stderr
-              .transform(new io.StringDecoder())
-              .transform(new io.LineTransformer());
+              .transform(UTF8.decoder)
+              .transform(new LineSplitter());
       _stderrSubscription = _stderrStream.listen((String line) {
         if (line.startsWith('>>> EOF STDERR')) {
           _stderrSubscription.pause();
@@ -1867,7 +1868,7 @@
 class RecordingCommandExecutor implements CommandExecutor {
   TestCaseRecorder _recorder;
 
-  RecordingCommandExecutor(io.Path path)
+  RecordingCommandExecutor(Path path)
       : _recorder = new TestCaseRecorder(path);
 
   Future<CommandOutput> runCommand(node, Command command, int timeout) {
@@ -1898,7 +1899,7 @@
 class ReplayingCommandExecutor implements CommandExecutor {
   TestCaseOutputArchive _archive = new TestCaseOutputArchive();
 
-  ReplayingCommandExecutor(io.Path path) {
+  ReplayingCommandExecutor(Path path) {
     _archive.loadFromPath(path);
   }
 
@@ -2091,9 +2092,9 @@
     // CommandExecutor will execute commands
     var executor;
     if (recording) {
-      executor = new RecordingCommandExecutor(new io.Path(recordingOutputFile));
+      executor = new RecordingCommandExecutor(new Path(recordingOutputFile));
     } else if (replaying) {
-      executor = new ReplayingCommandExecutor(new io.Path(recordedInputFile));
+      executor = new ReplayingCommandExecutor(new Path(recordedInputFile));
     } else {
       executor = new CommandExecutorImpl(
           _globalConfiguration, maxProcesses, maxBrowserProcesses);
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 5f5e4ef..dc7289f 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -15,6 +15,7 @@
 library test_suite;
 
 import "dart:async";
+import "dart:convert" show LineSplitter, UTF8;
 import "dart:io";
 import "dart:isolate";
 import "drt_updater.dart";
@@ -260,8 +261,8 @@
       // Drain stderr to not leak resources.
       p.stderr.listen((_) { });
       Stream<String> stdoutStream =
-          p.stdout.transform(new StringDecoder())
-                  .transform(new LineTransformer());
+          p.stdout.transform(UTF8.decoder)
+                  .transform(new LineSplitter());
       var streamDone = false;
       var processExited = false;
       checkDone() {
@@ -573,7 +574,7 @@
       if (statusFilePath.endsWith('_dart2js.status') ||
           statusFilePath.endsWith('_analyzer.status') ||
           statusFilePath.endsWith('_analyzer2.status')) {
-        var file = new File.fromPath(dartDir.append(statusFilePath));
+        var file = new File(dartDir.append(statusFilePath).toNativePath());
         if (!file.existsSync()) {
           filesRead++;
           continue;
@@ -589,7 +590,7 @@
   }
 
   Future enqueueTests() {
-    Directory dir = new Directory.fromPath(suiteDir);
+    Directory dir = new Directory(suiteDir.toNativePath());
     return dir.exists().then((exists) {
       if (!exists) {
         print('Directory containing tests missing: ${suiteDir.toNativePath()}');
@@ -636,18 +637,12 @@
   void enqueueTestCaseFromTestInformation(TestInformation info) {
     var filePath = info.filePath;
     var optionsFromFile = info.optionsFromFile;
-    var isNegative = info.hasCompileError;
-    if (info.hasRuntimeError && hasRuntime) {
-      isNegative = true;
-    }
 
     // Look up expectations in status files using a test name generated
     // from the test file's path.
     String testName;
 
     if (optionsFromFile['isMultitest']) {
-      // Multitests do not run on browsers.
-      if (TestUtils.isBrowserRuntime(configuration['runtime'])) return;
       // Multitests are in [build directory]/generated_tests/... .
       // The test name will be '[test filename (no extension)]/[multitest key].
       String name = filePath.filenameWithoutExtension;
@@ -676,7 +671,8 @@
     Set<String> expectations = testExpectations.expectations(testName);
     if (info.hasCompileError &&
         TestUtils.isBrowserRuntime(configuration['runtime']) &&
-        configuration['report']) {
+        configuration['report'] &&
+        configuration['compiler'] != 'none') {
       SummaryReport.addCompileErrorSkipTest();
       return;
     }
@@ -721,20 +717,6 @@
   void enqueueStandardTest(TestInformation info,
                            String testName,
                            Set<String> expectations) {
-    bool isNegative = info.hasCompileError ||
-        (configuration['checked'] && info.isNegativeIfChecked);
-    if (info.hasRuntimeError && hasRuntime) {
-      isNegative = true;
-    }
-
-    if (configuration['analyzer']) {
-      // An analyzer can detect static type warnings by the
-      // format of the error line
-      if (info.hasFatalTypeErrors) {
-        isNegative = true;
-      }
-    }
-
     var commonArguments = commonArgumentsFromFile(info.filePath,
                                                   info.optionsFromFile);
 
@@ -751,11 +733,27 @@
                           makeCommands(info, allVmOptions, commonArguments),
                           configuration,
                           expectations,
-                          isNegative: isNegative,
+                          isNegative: isNegative(info),
                           info: info));
     }
   }
 
+  bool isNegative(TestInformation info) {
+    bool negative = info.hasCompileError ||
+        (configuration['checked'] && info.isNegativeIfChecked);
+    if (info.hasRuntimeError && hasRuntime) {
+      negative = true;
+    }
+    if (configuration['analyzer']) {
+      // An analyzer can detect static type warnings by the
+      // format of the error line
+      if (info.hasFatalTypeErrors) {
+        negative = true;
+      }
+    }
+    return negative;
+  }
+
   List<Command> makeCommands(TestInformation info, var vmOptions, var args) {
     var compiler = configuration['compiler'];
     switch (compiler) {
@@ -970,10 +968,10 @@
       Path pngPath = dir.append('$nameNoExt.png');
       Path txtPath = dir.append('$nameNoExt.txt');
       Path expectedOutput = null;
-      if (new File.fromPath(pngPath).existsSync()) {
+      if (new File(pngPath.toNativePath()).existsSync()) {
         expectedOutput = pngPath;
         content = getHtmlLayoutContents(scriptType, new Path("$scriptPath"));
-      } else if (new File.fromPath(txtPath).existsSync()) {
+      } else if (new File(txtPath.toNativePath()).existsSync()) {
         expectedOutput = txtPath;
         content = getHtmlLayoutContents(scriptType, new Path("$scriptPath"));
       } else {
@@ -1008,7 +1006,7 @@
           // For the tests that require multiple input scripts but are not
           // compiled, move the input scripts over with the script so they can
           // be accessed.
-          String result = new File.fromPath(fromPath).readAsStringSync();
+          String result = new File(fromPath.toNativePath()).readAsStringSync();
           new File('$tempDir/$baseName.dart').writeAsStringSync(result);
         }
       }
@@ -1089,11 +1087,11 @@
           testCase = new BrowserTestCase(testDisplayName,
               commandSet, configuration,
               expectations['$testName/${subtestNames[subtestIndex]}'],
-              info, info.hasCompileError || info.hasRuntimeError, fullHtmlPath);
+              info, isNegative(info), fullHtmlPath);
         } else {
           testCase = new BrowserTestCase(testDisplayName,
               commandSet, configuration, expectations,
-              info, info.hasCompileError || info.hasRuntimeError, fullHtmlPath);
+              info, isNegative(info), fullHtmlPath);
         }
 
         doTest(testCase);
@@ -1161,7 +1159,7 @@
         .append(testUniqueName);
 
     TestUtils.mkdirRecursive(new Path('.'), generatedTestPath);
-    return new File.fromPath(generatedTestPath).fullPathSync()
+    return new File(generatedTestPath.toNativePath()).fullPathSync()
         .replaceAll('\\', '/');
   }
 
@@ -1347,7 +1345,7 @@
         new RegExp(r"^[#]?import.*dart:(html|web_audio|indexed_db|svg|web_sql)",
         multiLine: true);
 
-    var bytes = new File.fromPath(filePath).readAsBytesSync();
+    var bytes = new File(filePath.toNativePath()).readAsBytesSync();
     String contents = decodeUtf8(bytes);
     bytes = null;
 
@@ -1473,7 +1471,8 @@
    * environment variables, configuration files, etc.
    */
   Map readOptionsFromCo19File(Path filePath) {
-    String contents = decodeUtf8(new File.fromPath(filePath).readAsBytesSync());
+    String contents = decodeUtf8(new File(filePath.toNativePath())
+        .readAsBytesSync());
 
     bool hasCompileError = contents.contains("@compile-error");
     bool hasRuntimeError = contents.contains("@runtime-error");
@@ -1546,7 +1545,7 @@
     var group = new FutureGroup();
 
     for (String testDir in _testDirs) {
-      Directory dir = new Directory.fromPath(suiteDir.append(testDir));
+      Directory dir = new Directory(suiteDir.append(testDir).toNativePath());
       if (dir.existsSync()) {
         enqueueDirectory(dir, group);
       }
@@ -1720,7 +1719,7 @@
     if (relativePath.isAbsolute) {
       base = new Path('/');
     }
-    Directory dir = new Directory.fromPath(base);
+    Directory dir = new Directory(base.toNativePath());
     assert(dir.existsSync());
     var segments = relativePath.segments();
     for (String segment in segments) {
@@ -1731,7 +1730,7 @@
         // Skip the directory creation for a path like "/E:".
         continue;
       }
-      dir = new Directory.fromPath(base);
+      dir = new Directory(base.toNativePath());
       if (!dir.existsSync()) {
         dir.createSync();
       }
@@ -1745,8 +1744,8 @@
    * Assumes that the directory for [dest] already exists.
    */
   static Future copyFile(Path source, Path dest) {
-    return new File.fromPath(source).openRead()
-        .pipe(new File.fromPath(dest).openWrite());
+    return new File(source.toNativePath()).openRead()
+        .pipe(new File(dest.toNativePath()).openWrite());
   }
 
   static Path debugLogfile() {
@@ -1895,7 +1894,7 @@
     return new Path(path);
   }
 
-  /** 
+  /**
    * Gets extra vm options passed to the testing script.
    */
   static List<String> getExtraVmOptions(Map configuration) {
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart
index 888f8cf..51109e5 100644
--- a/tools/testing/dart/utils.dart
+++ b/tools/testing/dart/utils.dart
@@ -4,10 +4,13 @@
 
 library utils;
 
-import 'dart:io';
 import 'dart:async';
+import 'dart:io';
+import 'dart:math' show min;
 import 'dart:utf' as utf;
 
+part 'legacy_path.dart';
+
 class DebugLogger {
   static IOSink _sink;
 
@@ -17,7 +20,7 @@
   static init(Path path, {append: false}) {
     if (path != null) {
       var mode = append ? FileMode.APPEND : FileMode.WRITE;
-      _sink = new File.fromPath(path).openWrite(mode: mode);
+      _sink = new File(path.toNativePath()).openWrite(mode: mode);
     }
   }
 
@@ -151,4 +154,4 @@
   operator==(other) => other is UniqueObject && _hashCode == other._hashCode;
 
   UniqueObject() : _hashCode = ++_nextId;
-}
\ No newline at end of file
+}
diff --git a/tools/testing/webdriver_test_setup.py b/tools/testing/webdriver_test_setup.py
index b1bfe0f..7988bab5 100755
--- a/tools/testing/webdriver_test_setup.py
+++ b/tools/testing/webdriver_test_setup.py
@@ -124,15 +124,15 @@
         name = name[:name.rfind('.')]
         version_str = line[line.find(name) + len(name) : suffix_index]
         orig_version_str = version_str
-	if version_str.count('.') == 0:
+        if version_str.count('.') == 0:
           version_str = version_str.replace('_', '.')
-	  version_str = re.compile(r'[^\d.]+').sub('', version_str)
+          version_str = re.compile(r'[^\d.]+').sub('', version_str)
         if latest == '':
           latest = '0.' * version_str.count('.')
           latest += '0'
-	  orig_latest_str = latest
-	else:
-	  orig_latest_str = latest
+          orig_latest_str = latest
+        else:
+          orig_latest_str = latest
           latest = latest.replace('_', '.')
 	  latest = re.compile(r'[^\d.]+').sub('', latest)
         nums = version_str.split('.')
@@ -191,6 +191,9 @@
       os_str = 'linux32'
       if '64bit' in platform.architecture()[0]:
         os_str = 'linux64'
+    if self.project_name == 'chromedriver' and (
+        os_str == 'mac' or os_str == 'win'):
+      os_str = os_str + '32'
     return os_str
 
 
@@ -250,7 +253,7 @@
   def __init__(self, is_buildbot):
     self.is_buildbot = is_buildbot
 
-  def run(self): 
+  def run(self):
     print 'Installing Selenium Python Bindings'
     admin_keyword = ''
     python_cmd = 'python'
@@ -286,7 +289,7 @@
     Arguments:
     rejection_func: A function that accepts the value of the URL and determines
       if it is of the type we are looking for.
-    accept_func: A function that takes the URL and the "current best" URL and 
+    accept_func: A function that takes the URL and the "current best" URL and
       determines if it is better than our current download url."""
     self.latest = 0
     self.rejection_func = rejection_func
@@ -307,7 +310,7 @@
     download_page: The initial page that lists all the download options.
     rejection_func: A function that accepts the value of the URL and determines
       if it is of the type we are looking for.
-    accept_func: A function that takes the URL and the "current best" URL and 
+    accept_func: A function that takes the URL and the "current best" URL and
       determines if it is better than our current download url."""
     f = urllib2.urlopen(download_page)
     parser = OperaHtmlParser()
@@ -332,7 +335,7 @@
         lambda x: x[0] in string.digits and 'b' not in x and 'rc' not in x,
         higher_revision)
     download_name += version
-    if ('linux' in sys.platform and 
+    if ('linux' in sys.platform and
         platform.linux_distribution()[0] == 'Ubuntu'):
       # Last time I tried, the .deb file you download directly from opera was
       # not installing correctly on Ubuntu. This installs Opera more nicely.
diff --git a/utils/apidoc/apidoc.gyp b/utils/apidoc/apidoc.gyp
index fad6410..e19f080 100644
--- a/utils/apidoc/apidoc.gyp
+++ b/utils/apidoc/apidoc.gyp
@@ -85,6 +85,7 @@
             '--package-root=<(PRODUCT_DIR)/packages',
             '--mode=static',
             '--exclude-lib=analyzer_experimental',
+            '--exclude-lib=async_helper',
             '--exclude-lib=barback',
             '--exclude-lib=browser',
             '--exclude-lib=dartdoc',
diff --git a/utils/lib/file_system_vm.dart b/utils/lib/file_system_vm.dart
index d84d081..99b936f 100644
--- a/utils/lib/file_system_vm.dart
+++ b/utils/lib/file_system_vm.dart
@@ -5,9 +5,9 @@
 // TODO(terry): Investigate common library for file I/O shared between frog and tools.
 
 library file_system_vm;
+import 'dart:convert';
 import 'dart:io';
 import 'file_system.dart';
-import 'dart:utf';
 
 /** File system implementation using the vm api's. */
 class VMFileSystem implements FileSystem {
@@ -23,7 +23,7 @@
     var buffer = new List<int>(length);
     var bytes = file.readIntoSync(buffer, 0, length);
     file.closeSync();
-    return new String.fromCharCodes(new Utf8Decoder(buffer).decodeRest());
+    return UTF8.decode(bytes);
   }
 
   bool fileExists(String filename) {
diff --git a/utils/template/htmltree.dart b/utils/template/htmltree.dart
index 85453fe..e4618db 100644
--- a/utils/template/htmltree.dart
+++ b/utils/template/htmltree.dart
@@ -287,7 +287,7 @@
   String toString() => "\$\{#${toCall}${params}}";
 }
 
-interface TreeVisitor {
+abstract class TreeVisitor {
   void visitIdentifier(Identifier node);
   void visitStringValue(StringValue node);
   void visitCommentDefinition(CommentDefinition node);