svn merge -r 26292:26492 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@26504 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 9206a32..f850b03 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -14,6 +14,5 @@
       input_api,
       output_api,
       json_url='http://dart-status.appspot.com/current?format=json')
-  # TODO(ricow): reenable when status page is back in shape
-  # results.extend(status_check)
+  results.extend(status_check)
   return results
diff --git a/README.dart-sdk b/README.dart-sdk
index c0c4b0d..04e9d4b 100644
--- a/README.dart-sdk
+++ b/README.dart-sdk
@@ -1,4 +1,4 @@
-The Dark SDK is a set of tools and libraries for the Dart programming language.
+The Dart SDK is a set of tools and libraries for the Dart programming language.
 
 You can find information about Dart online at dartlang.org.
 
diff --git a/pkg/analyzer_experimental/bin/analyzer.dart b/pkg/analyzer_experimental/bin/analyzer.dart
index 5fed0a8..119376f 100644
--- a/pkg/analyzer_experimental/bin/analyzer.dart
+++ b/pkg/analyzer_experimental/bin/analyzer.dart
@@ -8,6 +8,7 @@
 library analyzer;
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
 
 import 'package:analyzer_experimental/src/generated/engine.dart';
@@ -80,7 +81,7 @@
     // read line from stdin
     Stream cmdLine = stdin
         .transform(new StringDecoder())
-        .transform(new LineTransformer());
+        .transform(new LineSplitter());
     var subscription = cmdLine.listen((String line) {
       // may be finish
       if (line.isEmpty) {
diff --git a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
index 22e0d2a..a3745ec 100644
--- a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
@@ -150,6 +150,13 @@
   /// Cached previous token for calculating preceding whitespace.
   Token previousToken;
 
+  /// 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) :
@@ -161,49 +168,59 @@
   }
 
   visitAnnotation(Annotation node) {
-    emitToken(node.atSign);
+    token(node.atSign);
     visit(node.name);
     visitPrefixed('.', node.constructorName);
     visit(node.arguments);
   }
 
   visitArgumentDefinitionTest(ArgumentDefinitionTest node) {
-    emitToken(node.question);
+    token(node.question);
     visit(node.identifier);
   }
 
   visitArgumentList(ArgumentList node) {
-    emitToken(node.leftParenthesis);
+    token(node.leftParenthesis);
     visitList(node.arguments, ', ');
-    emitToken(node.rightParenthesis);
+    token(node.rightParenthesis);
   }
 
   visitAsExpression(AsExpression node) {
     visit(node.expression);
-    emitToken(node.asOperator, prefix: ' ', suffix: ' ');
+    space();
+    token(node.asOperator);
+    space();
     visit(node.type);
   }
 
   visitAssertStatement(AssertStatement node) {
-    emitToken(node.keyword, suffix: ' (');
+    token(node.keyword);
+    space();
+    token(node.leftParenthesis);
     visit(node.condition);
-    emitToken(node.semicolon, prefix: ')');
+    token(node.rightParenthesis);
+    token(node.semicolon);
   }
 
   visitAssignmentExpression(AssignmentExpression node) {
     visit(node.leftHandSide);
-    emitToken(node.operator, prefix: ' ', suffix: ' ');
+    space();
+    token(node.operator);
+    space();
     visit(node.rightHandSide);
   }
 
   visitBinaryExpression(BinaryExpression node) {
     visit(node.leftOperand);
-    emitToken(node.operator, prefix: ' ', suffix: ' ');
+    space();
+    token(node.operator);
+    space();
     visit(node.rightOperand);
   }
 
   visitBlock(Block node) {
-    emitToken(node.leftBracket);
+    token(node.leftBracket);
+    needsNewline = true;
     indent();
 
     for (var stmt in node.statements) {
@@ -211,11 +228,9 @@
     }
 
     unindent();
-    newline();
-    print('}');
-//TODO(pquitslund): make this work    
-//    emitToken(node.rightBracket);
-    previousToken = node.rightBracket;
+    preservePrecedingNewlines = true;
+    needsNewline = true;
+    token(node.rightBracket);
   }
 
   visitBlockFunctionBody(BlockFunctionBody node) {
@@ -223,13 +238,15 @@
   }
 
   visitBooleanLiteral(BooleanLiteral node) {
-    emitToken(node.literal);
+    token(node.literal);
   }
 
   visitBreakStatement(BreakStatement node) {
-    emitToken(node.keyword);
+    preservePrecedingNewlines = true;
+    token(node.keyword);
     visitPrefixed(' ', node.label);
-    emitToken(node.semicolon);
+    token(node.semicolon);
+    needsNewline = true;
   }
 
   visitCascadeExpression(CascadeExpression node) {
@@ -241,28 +258,34 @@
     visitPrefixed('on ', node.exceptionType);
     if (node.catchKeyword != null) {
       if (node.exceptionType != null) {
-        print(' ');
+        space();
       }
-      print('catch (');
+      token(node.catchKeyword);
+      space();
+      token(node.leftParenthesis);
       visit(node.exceptionParameter);
       visitPrefixed(', ', node.stackTraceParameter);
-      print(') ');
+      token(node.rightParenthesis);
+      space();
     } else {
-      print(' ');
+      space();
     }
     visit(node.body);
-    newline();
+    needsNewline = true;
   }
 
   visitClassDeclaration(ClassDeclaration node) {
-    emitToken(node.abstractKeyword, suffix: ' ');
-    emitToken(node.classKeyword, suffix: ' ');
+    preservePrecedingNewlines = true;
+    modifier(node.abstractKeyword);
+    token(node.classKeyword);
+    space();
     visit(node.name);
     visit(node.typeParameters);
     visitPrefixed(' ', node.extendsClause);
     visitPrefixed(' ', node.withClause);
     visitPrefixed(' ', node.implementsClause);
-    emitToken(node.leftBracket, prefix: ' ');
+    space();
+    token(node.leftBracket);
     indent();
 
     for (var i = 0; i < node.members.length; i++) {
@@ -271,21 +294,26 @@
 
     unindent();
 
-    emitToken(node.rightBracket, minNewlines: 1);
+    emitPrecedingNewlines(node.rightBracket, min: 1);
+    token(node.rightBracket);
   }
 
   visitClassTypeAlias(ClassTypeAlias node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visit(node.name);
     visit(node.typeParameters);
-    print(' = ');
+    space();
+    token(node.equals);
+    space();
     if (node.abstractKeyword != null) {
-      print('abstract ');
+      token(node.abstractKeyword);
+      space();
     }
     visit(node.superclass);
     visitPrefixed(' ', node.withClause);
     visitPrefixed(' ', node.implementsClause);
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitComment(Comment node) => null;
@@ -293,31 +321,40 @@
   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);
-    var prefix = scriptTag == null ? '' : ' ';
-    visitPrefixedList(prefix, directives, ' ');
-    //prefix = scriptTag == null && directives.isEmpty ? '' : ' ';
-    prefix = '';
-    visitPrefixedList(prefix, node.declarations);
+    visitList(directives);
+    visitList(node.declarations);
 
-    //TODO(pquitslund): move this?
-    newline();
+    // Handle trailing whitespace
+    preservePrecedingNewlines = true;
+    token(node.endToken /* EOF */);
   }
 
   visitConditionalExpression(ConditionalExpression node) {
     visit(node.condition);
-    print(' ? ');
+    space();
+    token(node.question);
+    space();
     visit(node.thenExpression);
-    print(' : ');
+    space();
+    token(node.colon);
+    space();
     visit(node.elseExpression);
   }
 
   visitConstructorDeclaration(ConstructorDeclaration node) {
-    emitToken(node.externalKeyword, suffix: ' ');
-    emitToken(node.constKeyword, suffix: ' ');
-    emitToken(node.factoryKeyword, suffix: ' ');
+    modifier(node.externalKeyword);
+    modifier(node.constKeyword);
+    modifier(node.factoryKeyword);
     visit(node.returnType);
     visitPrefixed('.', node.name);
     visit(node.parameters);
@@ -327,9 +364,12 @@
   }
 
   visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    emitToken(node.keyword, suffix: '.');
+    token(node.keyword);
+    token(node.period);
     visit(node.fieldName);
-    print(' = ');
+    space();
+    token(node.equals);
+    space();
     visit(node.expression);
   }
 
@@ -339,150 +379,179 @@
   }
 
   visitContinueStatement(ContinueStatement node) {
-    emitToken(node.keyword);
+    token(node.keyword);
     visitPrefixed(' ', node.label);
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitDeclaredIdentifier(DeclaredIdentifier node) {
-    emitToken(node.keyword, suffix: ' ');
-    visitSuffixed(node.type, ' ');
+    token(node.keyword);
+    space();
+    visit(node.type);
+    //TODO(pquitslund): avoiding visitSuffixed(..) but we can do better
+    if (node.type != null) {
+      space();
+    }
     visit(node.identifier);
   }
 
   visitDefaultFormalParameter(DefaultFormalParameter node) {
     visit(node.parameter);
     if (node.separator != null) {
-      print(' ');
-      print(node.separator.lexeme);
+      space();
+      token(node.separator);
       visitPrefixed(' ', node.defaultValue);
     }
   }
 
   visitDoStatement(DoStatement node) {
-    emitToken(node.doKeyword, suffix: ' ');
+    token(node.doKeyword);
+    space();
     visit(node.body);
-    emitToken(node.whileKeyword, prefix: ' ', suffix: ' (');
+    space();
+    token(node.whileKeyword);
+    space();
+    token(node.leftParenthesis);
     visit(node.condition);
-    emitToken(node.semicolon, prefix: ')');
+    token(node.rightParenthesis);
+    token(node.semicolon);
   }
 
   visitDoubleLiteral(DoubleLiteral node) {
-    print(node.literal.lexeme);
+    token(node.literal);
   }
 
   visitEmptyFunctionBody(EmptyFunctionBody node) {
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitEmptyStatement(EmptyStatement node) {
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitExportDirective(ExportDirective node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visit(node.uri);
     visitPrefixedList(' ', node.combinators, ' ');
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    emitToken(node.functionDefinition, suffix: ' ');
+    token(node.functionDefinition);
+    space();
     visit(node.expression);
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitExpressionStatement(ExpressionStatement node) {
     visit(node.expression);
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitExtendsClause(ExtendsClause node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visit(node.superclass);
   }
 
   visitFieldDeclaration(FieldDeclaration node) {
-    emitToken(node.keyword, suffix: ' ');
+    needsNewline = true;
+    preservePrecedingNewlines = true;
+    modifier(node.keyword);
     visit(node.fields);
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitFieldFormalParameter(FieldFormalParameter node) {
-    emitToken(node.keyword, suffix: ' ');
-    visitSuffixed(node.type, ' ');
-    print('this.');
+    token(node.keyword);
+    space();
+    visit(node.type);
+    space();
+    token(node.thisToken);
+    token(node.period);
     visit(node.identifier);
     visit(node.parameters);
   }
 
   visitForEachStatement(ForEachStatement node) {
-    print('for (');
+    token(node.forKeyword);
+    space();
+    token(node.leftParenthesis);
     visit(node.loopVariable);
-    print(' in ');
+    space();
+    token(node.inKeyword);
+    space();
     visit(node.iterator);
-    print(') ');
+    token(node.rightParenthesis);
+    space();
     visit(node.body);
   }
 
   visitFormalParameterList(FormalParameterList node) {
     var groupEnd = null;
-    print('(');
+    token(node.leftParenthesis);
     var parameters = node.parameters;
     var size = parameters.length;
     for (var i = 0; i < size; i++) {
       var parameter = parameters[i];
       if (i > 0) {
-        print(', ');
+        append(', ');
       }
       if (groupEnd == null && parameter is DefaultFormalParameter) {
         if (identical(parameter.kind, ParameterKind.NAMED)) {
           groupEnd = '}';
-          print('{');
+          append('{');
         } else {
           groupEnd = ']';
-          print('[');
+          append('[');
         }
       }
       parameter.accept(this);
     }
     if (groupEnd != null) {
-      print(groupEnd);
+      append(groupEnd);
     }
-    print(')');
+    token(node.rightParenthesis);
   }
 
   visitForStatement(ForStatement node) {
+    token(node.forKeyword);
+    space();
+    token(node.leftParenthesis);
     var initialization = node.initialization;
-    print('for (');
     if (initialization != null) {
       visit(initialization);
     } else {
       visit(node.variables);
     }
-    print(';');
+    token(node.leftSeparator);
     visitPrefixed(' ', node.condition);
-    print(';');
+    token(node.rightSeparator);
     visitPrefixedList(' ', node.updaters, ', ');
-    print(') ');
+    token(node.leftParenthesis);
+    space();
     visit(node.body);
   }
 
   visitFunctionDeclaration(FunctionDeclaration node) {
+    needsNewline = true;
+    preservePrecedingNewlines = true;
     visitSuffixed(node.returnType, ' ');
-    emitToken(node.propertyKeyword, suffix: ' ');
+    token(node.propertyKeyword, followedBy: space);
     visit(node.name);
     visit(node.functionExpression);
   }
 
   visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
     visit(node.functionDeclaration);
-    print(';');
+    // TODO(pquitslund): fix and handle in function body
+    append(';');
   }
 
   visitFunctionExpression(FunctionExpression node) {
     visit(node.parameters);
-    print(' ');
+    space();
     visit(node.body);
   }
 
@@ -492,12 +561,13 @@
   }
 
   visitFunctionTypeAlias(FunctionTypeAlias node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visitSuffixed(node.returnType, ' ');
     visit(node.name);
     visit(node.typeParameters);
     visit(node.parameters);
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
@@ -507,81 +577,96 @@
   }
 
   visitHideCombinator(HideCombinator node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visitList(node.hiddenNames, ', ');
   }
 
   visitIfStatement(IfStatement node) {
-    emitToken(node.ifKeyword);
-    print(' (');
+    preservePrecedingNewlines = true;
+    token(node.ifKeyword);
+    space();
+    token(node.leftParenthesis);
     visit(node.condition);
-    print(') ');
+    token(node.rightParenthesis);
+    space();
     visit(node.thenStatement);
-    visitPrefixed(' else ', node.elseStatement);
+    //visitPrefixed(' else ', node.elseStatement);
+    if (node.elseStatement != null) {
+      space();
+      token(node.elseKeyword);
+      space();
+      visit(node.elseStatement);
+    }
+    needsNewline = true;
   }
-
+  
   visitImplementsClause(ImplementsClause node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visitList(node.interfaces, ', ');
   }
 
   visitImportDirective(ImportDirective node) {
-    emitToken(node.keyword, suffix: ' ');
+    preservePrecedingNewlines = true;
+    token(node.keyword);
+    space();
     visit(node.uri);
     visitPrefixed(' as ', node.prefix);
     visitPrefixedList(' ', node.combinators, ' ');
-    emitToken(node.semicolon);
+    token(node.semicolon);
+    needsNewline = true;
   }
 
   visitIndexExpression(IndexExpression node) {
     if (node.isCascaded) {
-      print('..');
+      token(node.period);
     } else {
       visit(node.target);
     }
-    print('[');
+    token(node.leftBracket);
     visit(node.index);
-    print(']');
+    token(node.rightBracket);
   }
 
   visitInstanceCreationExpression(InstanceCreationExpression node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visit(node.constructorName);
     visit(node.argumentList);
   }
 
   visitIntegerLiteral(IntegerLiteral node) {
-    print(node.literal.lexeme);
+    token(node.literal);
   }
 
   visitInterpolationExpression(InterpolationExpression node) {
     if (node.rightBracket != null) {
-      print('\${');
+      token(node.leftBracket);
       visit(node.expression);
-      print('}');
+      token(node.rightBracket);
     } else {
-      print('\$');
+      token(node.leftBracket);
       visit(node.expression);
     }
   }
 
   visitInterpolationString(InterpolationString node) {
-    print(node.contents.lexeme);
+    token(node.contents);
   }
 
   visitIsExpression(IsExpression node) {
     visit(node.expression);
-    if (node.notOperator == null) {
-      print(' is ');
-    } else {
-      print(' is! ');
-    }
+    space();
+    token(node.isOperator);
+    token(node.notOperator);
+    space();
     visit(node.type);
   }
 
   visitLabel(Label node) {
     visit(node.label);
-    print(':');
+    token(node.colon);
   }
 
   visitLabeledStatement(LabeledStatement node) {
@@ -590,49 +675,51 @@
   }
 
   visitLibraryDirective(LibraryDirective node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visit(node.name);
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitLibraryIdentifier(LibraryIdentifier node) {
-    print(node.name);
+    append(node.name);
   }
 
   visitListLiteral(ListLiteral node) {
     if (node.modifier != null) {
-      print(node.modifier.lexeme);
-      print(' ');
+      token(node.modifier);
+      space();
     }
     visit(node.typeArguments);
-    print('[');
+    token(node.leftBracket);
     visitList(node.elements, ', ');
-    print(']');
+    token(node.rightBracket);
   }
 
   visitMapLiteral(MapLiteral node) {
-    if (node.modifier != null) {
-      print(node.modifier.lexeme);
-      print(' ');
-    }
+    modifier(node.modifier);
     visitSuffixed(node.typeArguments, ' ');
-    print('{');
+    token(node.leftBracket);
     visitList(node.entries, ', ');
-    print('}');
+    token(node.rightBracket);
   }
 
   visitMapLiteralEntry(MapLiteralEntry node) {
     visit(node.key);
-    print(' : ');
+    space();
+    token(node.separator);
+    space();
     visit(node.value);
   }
 
   visitMethodDeclaration(MethodDeclaration node) {
-    emitToken(node.externalKeyword, suffix: ' ');
-    emitToken(node.modifierKeyword, suffix: ' ');
+    needsNewline = true;
+    preservePrecedingNewlines = true;
+    modifier(node.externalKeyword);
+    modifier(node.modifierKeyword);
     visitSuffixed(node.returnType, ' ');
-    emitToken(node.propertyKeyword, suffix: ' ');
-    emitToken(node.operatorKeyword, suffix: ' ');
+    modifier(node.propertyKeyword);
+    modifier(node.operatorKeyword);
     visit(node.name);
     if (!node.isGetter) {
       visit(node.parameters);
@@ -642,7 +729,7 @@
 
   visitMethodInvocation(MethodInvocation node) {
     if (node.isCascaded) {
-      print('..');
+      token(node.period);
     } else {
       visitSuffixed(node.target, '.');
     }
@@ -656,107 +743,114 @@
   }
 
   visitNativeClause(NativeClause node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visit(node.name);
   }
 
   visitNativeFunctionBody(NativeFunctionBody node) {
-    emitToken(node.nativeToken, suffix: ' ');
+    token(node.nativeToken);
+    space();
     visit(node.stringLiteral);
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitNullLiteral(NullLiteral node) {
-    emitToken(node.literal);
+    token(node.literal);
   }
 
   visitParenthesizedExpression(ParenthesizedExpression node) {
-    emitToken(node.leftParenthesis);
+    token(node.leftParenthesis);
     visit(node.expression);
-    emitToken(node.rightParenthesis);
+    token(node.rightParenthesis);
   }
 
   visitPartDirective(PartDirective node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visit(node.uri);
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitPartOfDirective(PartOfDirective node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visit(node.libraryName);
-    emitToken(node.semicolon);
+    token(node.semicolon);
   }
 
   visitPostfixExpression(PostfixExpression node) {
     visit(node.operand);
-    print(node.operator.lexeme);
+    token(node.operator);
   }
 
   visitPrefixedIdentifier(PrefixedIdentifier node) {
     visit(node.prefix);
-    print('.');
+    token(node.period);
     visit(node.identifier);
   }
 
   visitPrefixExpression(PrefixExpression node) {
-    emitToken(node.operator);
+    token(node.operator);
     visit(node.operand);
   }
 
   visitPropertyAccess(PropertyAccess node) {
     if (node.isCascaded) {
-      print('..');
+      token(node.operator);
     } else {
       visit(node.target);
-      print('.');
+      token(node.operator);
     }
     visit(node.propertyName);
   }
 
   visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
-    emitToken(node.keyword);
+    token(node.keyword);
     visitPrefixed('.', node.constructorName);
     visit(node.argumentList);
   }
 
   visitRethrowExpression(RethrowExpression node) {
-    emitToken(node.keyword);
+    token(node.keyword);
   }
 
   visitReturnStatement(ReturnStatement node) {
+    preservePrecedingNewlines = true;
     var expression = node.expression;
     if (expression == null) {
-      emitToken(node.keyword, minNewlines: 1);
-      emitToken(node.semicolon);
+      token(node.keyword);
+      token(node.semicolon);
     } else {
-      emitToken(node.keyword, suffix: ' ', minNewlines: 1);
+      token(node.keyword);
+      space();
       expression.accept(this);
-      emitToken(node.semicolon);
+      token(node.semicolon);
     }
   }
 
   visitScriptTag(ScriptTag node) {
-    print(node.scriptTag.lexeme);
+    token(node.scriptTag);
   }
 
   visitShowCombinator(ShowCombinator node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visitList(node.shownNames, ', ');
   }
 
   visitSimpleFormalParameter(SimpleFormalParameter node) {
-    emitToken(node.keyword, suffix: ' ');
+    modifier(node.keyword);
     visitSuffixed(node.type, ' ');
     visit(node.identifier);
   }
 
   visitSimpleIdentifier(SimpleIdentifier node) {
-    emitToken(node.token);
+    token(node.token);
   }
 
   visitSimpleStringLiteral(SimpleStringLiteral node) {
-    emitToken(node.literal);
+    token(node.literal);
   }
 
   visitStringInterpolation(StringInterpolation node) {
@@ -764,42 +858,50 @@
   }
 
   visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    emitToken(node.keyword);
+    token(node.keyword);
     visitPrefixed('.', node.constructorName);
     visit(node.argumentList);
   }
 
   visitSuperExpression(SuperExpression node) {
-    emitToken(node.keyword);
+    token(node.keyword);
   }
 
   visitSwitchCase(SwitchCase node) {
+    preservePrecedingNewlines = true;
     visitSuffixedList(node.labels, ' ', ' ');
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visit(node.expression);
-    print(':');
+    token(node.colon);
     indent();
+    needsNewline = true;
     visitList(node.statements);
     unindent();
   }
 
   visitSwitchDefault(SwitchDefault node) {
+    preservePrecedingNewlines = true;
     visitSuffixedList(node.labels, ' ', ' ');
-    emitToken(node.keyword, suffix: ': ');
+    token(node.keyword);
+    token(node.colon);
+    space();
     visitList(node.statements, ' ');
   }
 
   visitSwitchStatement(SwitchStatement node) {
-    emitToken(node.keyword);
-    print(' (');
+    token(node.keyword);
+    space();
+    token(node.leftParenthesis);
     visit(node.expression);
-    print(') ');
-    emitToken(node.leftBracket);
+    token(node.rightParenthesis);
+    space();
+    token(node.leftBracket);
     indent();
     visitList(node.members);
     unindent();
-    emitToken(node.rightBracket);
-    newline();
+    token(node.rightBracket);
+    needsNewline = true;
   }
 
   visitSymbolLiteral(SymbolLiteral node) {
@@ -807,29 +909,34 @@
   }
 
   visitThisExpression(ThisExpression node) {
-    emitToken(node.keyword);
+    token(node.keyword);
   }
 
   visitThrowExpression(ThrowExpression node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visit(node.expression);
   }
 
   visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    visitSuffixed(node.variables, ';');
+    preservePrecedingNewlines = true;
+    visit(node.variables);
+    token(node.semicolon);
   }
 
   visitTryStatement(TryStatement node) {
-    emitToken(node.tryKeyword, suffix: ' ');
+    preservePrecedingNewlines = true;
+    token(node.tryKeyword);
+    space();
     visit(node.body);
     visitPrefixedList(' ', node.catchClauses, ' ');
     visitPrefixed(' finally ', node.finallyClause);
   }
 
   visitTypeArgumentList(TypeArgumentList node) {
-    emitToken(node.leftBracket);
+    token(node.leftBracket);
     visitList(node.arguments, ', ');
-    emitToken(node.rightBracket);
+    token(node.rightBracket);
   }
 
   visitTypeName(TypeName node) {
@@ -843,36 +950,47 @@
   }
 
   visitTypeParameterList(TypeParameterList node) {
-    emitToken(node.leftBracket);
+    token(node.leftBracket);
     visitList(node.typeParameters, ', ');
-    emitToken(node.rightBracket);
+    token(node.rightBracket);
   }
 
   visitVariableDeclaration(VariableDeclaration node) {
     visit(node.name);
-    visitPrefixed(' = ', node.initializer);
+    if (node.initializer != null) {
+      space();
+      token(node.equals);
+      space();
+      visit(node.initializer);
+    }
   }
 
   visitVariableDeclarationList(VariableDeclarationList node) {
-    emitToken(node.keyword, suffix: ' ');
+    token(node.keyword);
+    space();
     visitSuffixed(node.type, ' ');
     visitList(node.variables, ', ');
   }
 
   visitVariableDeclarationStatement(VariableDeclarationStatement node) {
     visit(node.variables);
-    emitToken(node.semicolon);
+    token(node.semicolon);
+    needsNewline = true;
   }
 
   visitWhileStatement(WhileStatement node) {
-    emitToken(node.keyword, suffix: ' (');
+    token(node.keyword);
+    space();
+    token(node.leftParenthesis);
     visit(node.condition);
-    print(') ');
+    token(node.rightParenthesis);
+    space();
     visit(node.body);
   }
 
   visitWithClause(WithClause node) {
-    emitToken(node.withKeyword, suffix: ' ');
+    token(node.withKeyword);
+    space();
     visitList(node.mixinTypes, ', ');
   }
 
@@ -888,7 +1006,7 @@
   visitSuffixed(ASTNode node, String suffix) {
     if (node != null) {
       node.accept(this);
-      print(suffix);
+      append(suffix);
     }
   }
 
@@ -896,7 +1014,7 @@
   /// it is non-null.
   visitPrefixed(String prefix, ASTNode node) {
     if (node != null) {
-      print(prefix);
+      append(prefix);
       node.accept(this);
     }
   }
@@ -905,7 +1023,7 @@
   /// body is not empty.
   visitPrefixedBody(String prefix, FunctionBody body) {
     if (body is! EmptyFunctionBody) {
-      print(prefix);
+      append(prefix);
     }
     visit(body);
   }
@@ -916,7 +1034,7 @@
       var size = nodes.length;
       for (var i = 0; i < size; i++) {
         if (i > 0) {
-          print(separator);
+          append(separator);
         }
         nodes[i].accept(this);
       }
@@ -930,11 +1048,11 @@
       if (size > 0) {
         for (var i = 0; i < size; i++) {
           if (i > 0) {
-            print(separator);
+            append(separator);
           }
           nodes[i].accept(this);
         }
-        print(suffix);
+        append(suffix);
       }
     }
   }
@@ -945,10 +1063,10 @@
     if (nodes != null) {
       var size = nodes.length;
       if (size > 0) {
-        print(prefix);
+        append(prefix);
         for (var i = 0; i < size; i++) {
           if (i > 0 && separator != null) {
-            print(separator);
+            append(separator);
           }
           nodes[i].accept(this);
         }
@@ -956,37 +1074,50 @@
     }
   }
 
-
-  /// Emit the given [token], if it's non-null, preceded by any detected 
-  /// newlines or a minimum as specified by [minNewlines], printing a [prefix] 
-  /// before and a [suffix] after.
-  emitToken(Token token, {String prefix, String suffix, 
-      int minNewlines: 0}) {
+  /// 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}) {
     if (token != null) {
-      print(prefix);
-      emitPrecedingNewlines(token, min: minNewlines);
-      print(token.lexeme);
-      print(suffix);
-    }
+      if (needsNewline) {
+        minNewlines = max(1, minNewlines);
+      }
+      if (preservePrecedingNewlines || minNewlines > 0) {
+        var emitted = emitPrecedingNewlines(token, min: minNewlines);
+        preservePrecedingNewlines = false;
+        if (emitted > 0) {
+          needsNewline = false;
+        }
+      }
+      append(token.lexeme);
+      if (followedBy != null) { 
+        followedBy();
+      }
+      previousToken = token;
+    }    
+  }
+    
+  /// Emit a non-breakable space.
+  space() {
+    //TODO(pquitslund): replace with a proper space token
+    append(' ');
   }
   
-  /// Print the given [string] to the source writer if it's non-null.
-  print(String string) {
+  /// 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);
     }
   }
-  
-  /// Emit a newline.
-  newline() {
-   writer.newline();
-  }
-  
-  /// Emit [n] newlines.
-  newlines(n) {
-   writer.newlines(n);
-  }
-  
+    
   /// Indent.
   indent() {
     writer.indent();
@@ -998,18 +1129,19 @@
   }
   
   /// Emit any detected newlines or a minimum as specified by [minNewlines].
-  emitPrecedingNewlines(Token token, {min: 0}) {
+  int emitPrecedingNewlines(Token token, {min: 0}) {
     var comment = token.precedingComments;
     var currentToken = comment != null ? comment : token;
     var lines = max(min, countNewlinesBetween(previousToken, currentToken));
-    newlines(lines);
+    writer.newlines(lines);
     while (comment != null) {
-      print(comment.toString().trim());
-      newline();
+      append(comment.toString().trim());
+      writer.newline();
       comment = comment.next;
     }
 
     previousToken = token;
+    return lines;
   }
 
   /// Count the blanks between these two nodes.
diff --git a/pkg/analyzer_experimental/test/services/formatter_test.dart b/pkg/analyzer_experimental/test/services/formatter_test.dart
index 3f21446..2ad1d13 100644
--- a/pkg/analyzer_experimental/test/services/formatter_test.dart
+++ b/pkg/analyzer_experimental/test/services/formatter_test.dart
@@ -21,9 +21,13 @@
 
     test('CU (1)', () {
       expectCUFormatsTo(
-          'class A  {\n'
-          '}',
           'class A {\n'
+          '  var z;\n'
+          '  inc(int x) => ++x;\n'
+          '}\n',
+          'class A {\n'
+          '  var z;\n'
+          '  inc(int x) => ++x;\n'
           '}\n'
         );
     });
@@ -31,7 +35,7 @@
     test('CU (2)', () {
       expectCUFormatsTo(
           'class      A  {  \n'
-          '}',
+          '}\n',
           'class A {\n'
           '}\n'
         );
@@ -42,19 +46,78 @@
           'class A {\n'
           '  }',
           'class A {\n'
-          '}\n'
+          '}'
         );
     });
 
     test('CU (4)', () {
       expectCUFormatsTo(
           ' class A {\n'
-          '}',
+          '}\n',
           'class A {\n'
           '}\n'
         );
     });
 
+    test('CU (5)', () {
+      expectCUFormatsTo(
+          'class A  { int meaningOfLife() => 42; }',
+          'class A {\n'
+          '  int meaningOfLife() => 42;\n'
+          '}'
+      );
+    });
+    
+    
+//    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 - top level', () {
+      expectCUFormatsTo(
+          '\n\n'
+          'foo() {\n'
+          '}\n'
+          'bar() {\n'
+          '}\n',
+          '\n\n'
+          'foo() {\n'
+          '}\n'
+          'bar() {\n'
+          '}\n'
+      );
+      expectCUFormatsTo(
+          'const A = 42;\n'
+          'final foo = 32;\n',
+          'const A = 42;\n'
+          'final foo = 32;\n'
+      );
+    });
+    
+    test('CU - imports', () {
+      expectCUFormatsTo(
+          'import "dart:io";\n\n'
+          'import "package:unittest/unittest.dart";\n'
+          'foo() {\n'
+          '}\n',
+          'import "dart:io";\n\n'
+          'import "package:unittest/unittest.dart";\n'
+          'foo() {\n'
+          '}\n'
+      );
+    });
+
     test('CU w/class decl comment', () {
       expectCUFormatsTo(
           'import "foo";\n\n'
@@ -64,29 +127,64 @@
           'import "foo";\n\n'
           '//Killer class\n'
           'class A {\n'
-          '}\n'
+          '}'
         );
     });
 
-
+    test('CU (method body)', () {
+      expectCUFormatsTo(
+          'class A {\n'
+          '  foo(path) {\n'
+          '    var buffer = new StringBuffer();\n'
+          '    var file = new File(path);\n'
+          '    return file;\n'
+          '  }\n'
+          '}\n',
+          'class A {\n'
+          '  foo(path) {\n'
+          '    var buffer = new StringBuffer();\n'
+          '    var file = new File(path);\n'
+          '    return file;\n'
+          '  }\n'
+          '}\n'
+      );
+      expectCUFormatsTo(
+          'class A {\n'
+          '  foo(files) {\n'
+          '    for (var  file in files) {\n'
+          '      print(file);\n'
+          '    }\n'
+          '  }\n'
+          '}\n',
+          'class A {\n'
+          '  foo(files) {\n'
+          '    for (var file in files) {\n'
+          '      print(file);\n'
+          '    }\n'
+          '  }\n'
+          '}\n'
+      );
+    });
+    
     test('CU (method indent)', () {
       expectCUFormatsTo(
           'class A {\n'
           'void x(){\n'
           '}\n'
-          '}',
+          '}\n',
           'class A {\n'
           '  void x() {\n'
           '  }\n'
           '}\n'
-        );
+      );
     });
 
     test('CU (method indent - 2)', () {
       expectCUFormatsTo(
           'class A {\n'
-          ' static  bool x(){ return true; }\n'
-          ' }',
+          ' static  bool x(){\n'
+          'return true; }\n'
+          ' }\n',
           'class A {\n'
           '  static bool x() {\n'
           '    return true;\n'
@@ -99,7 +197,7 @@
       expectCUFormatsTo(
           'class A {\n'
           ' int x() =>   42   + 3 ;  \n'
-          '   }',
+          '   }\n',
           'class A {\n'
           '  int x() => 42 + 3;\n'
           '}\n'
@@ -110,10 +208,12 @@
       expectCUFormatsTo(
           'class A {\n'
           ' int x() { \n'
-          'if (true) {return 42;\n'
-          '} else { return 13; }\n'
+          'if (true) {\n'
+          'return 42;\n'
+          '} else {\n'
+          'return 13;\n }\n'
           '   }'
-          '}',
+          '}\n',
           'class A {\n'
           '  int x() {\n'
           '    if (true) {\n'
@@ -192,7 +292,7 @@
         'case "fig":\n'
         'print("bleh");\n'
         'break;\n'
-        '}\n',
+        '}',
         'switch (fruit) {\n'
         '  case "apple":\n'
         '    print("delish");\n'
@@ -200,7 +300,7 @@
         '  case "fig":\n'
         '    print("bleh");\n'
         '    break;\n'
-        '}\n'
+        '}'
       );
     });
   
@@ -217,12 +317,12 @@
         'doSomething();\n'
         '} catch (e) {\n'
         'print(e);\n'
-        '}\n',
+        '}',
         'try {\n'
         '  doSomething();\n'
         '} catch (e) {\n'
         '  print(e);\n'
-        '}\n'
+        '}'
       );
     });
     
diff --git a/pkg/barback/lib/barback.dart b/pkg/barback/lib/barback.dart
index a211873..e37bd1b 100644
--- a/pkg/barback/lib/barback.dart
+++ b/pkg/barback/lib/barback.dart
@@ -6,9 +6,10 @@
 
 export 'src/asset.dart';
 export 'src/asset_id.dart';
+export 'src/asset_set.dart';
 export 'src/barback.dart';
 export 'src/build_result.dart';
-export 'src/errors.dart';
+export 'src/errors.dart' hide flattenAggregateExceptions;
 export 'src/package_provider.dart';
 export 'src/transform.dart' show Transform;
 export 'src/transform_logger.dart';
diff --git a/pkg/barback/lib/src/asset_cascade.dart b/pkg/barback/lib/src/asset_cascade.dart
index 341480d..e8e9355 100644
--- a/pkg/barback/lib/src/asset_cascade.dart
+++ b/pkg/barback/lib/src/asset_cascade.dart
@@ -10,10 +10,10 @@
 import 'asset.dart';
 import 'asset_id.dart';
 import 'asset_node.dart';
+import 'asset_set.dart';
 import 'build_result.dart';
 import 'cancelable_future.dart';
 import 'errors.dart';
-import 'change_batch.dart';
 import 'package_graph.dart';
 import 'phase.dart';
 import 'transformer.dart';
@@ -83,31 +83,14 @@
   /// last began.
   var _newChanges = false;
 
+  /// Returns all currently-available output assets from this cascade.
+  AssetSet get availableOutputs => _phases.last.availableOutputs;
+
   /// Creates a new [AssetCascade].
   ///
-  /// It loads source assets within [package] using [provider] and then uses
-  /// [transformerPhases] to generate output files from them.
-  //TODO(rnystrom): Better way of specifying transformers and their ordering.
-  AssetCascade(this.graph, this.package,
-      Iterable<Iterable<Transformer>> transformerPhases) {
-    // Flatten the phases to a list so we can traverse backwards to wire up
-    // each phase to its next.
-    var phases = transformerPhases.toList();
-
-    // Each phase writes its outputs as inputs to the next phase after it.
-    // Add a phase at the end for the final outputs of the last phase.
-    phases.add([]);
-
-    Phase nextPhase = null;
-    for (var transformers in phases.reversed) {
-      nextPhase = new Phase(this, _phases.length, transformers.toList(),
-          nextPhase);
-      nextPhase.onDirty.listen((_) {
-        _newChanges = true;
-        _waitForProcess();
-      });
-      _phases.insert(0, nextPhase);
-    }
+  /// It loads source assets within [package] using [provider].
+  AssetCascade(this.graph, this.package) {
+    _addPhase(new Phase(this, []));
   }
 
   /// Gets the asset identified by [id].
@@ -128,7 +111,7 @@
     // * If [id] has never been generated and all active transformers provide
     //   metadata about the file names of assets it can emit, we can prove that
     //   none of them can emit [id] and fail early.
-    return _phases.last.getInput(id).then((node) {
+    return _phases.last.getOutput(id).then((node) {
       // If the requested asset is available, we can just return it.
       if (node != null && node.state.isAvailable) return node;
 
@@ -190,11 +173,42 @@
     });
   }
 
+  /// Sets this cascade's transformer phases to [transformers].
+  void updateTransformers(Iterable<Iterable<Transformer>> transformers) {
+    transformers = transformers.toList();
+
+    for (var i = 0; i < transformers.length; i++) {
+      if (_phases.length > i) {
+        _phases[i].updateTransformers(transformers[i]);
+        continue;
+      }
+
+      _addPhase(_phases.last.addPhase(transformers[i]));
+    }
+
+    if (transformers.length < _phases.length) {
+      for (var i = transformers.length; i < _phases.length; i++) {
+        // TODO(nweiz): actually remove phases rather than emptying them of
+        // transformers.
+        _phases[i].updateTransformers([]);
+      }
+    }
+  }
+
   void reportError(BarbackException error) {
     _accumulatedErrors.add(error);
     _errorsController.add(error);
   }
 
+  /// Add [phase] to the end of [_phases] and watch its [onDirty] stream.
+  void _addPhase(Phase phase) {
+    phase.onDirty.listen((_) {
+      _newChanges = true;
+      _waitForProcess();
+    });
+    _phases.add(phase);
+  }
+
   /// Starts the build process asynchronously if there is work to be done.
   ///
   /// Returns a future that completes with the background processing is done.
diff --git a/pkg/barback/lib/src/asset_forwarder.dart b/pkg/barback/lib/src/asset_forwarder.dart
new file mode 100644
index 0000000..7dc74dc
--- /dev/null
+++ b/pkg/barback/lib/src/asset_forwarder.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library barback.asset_forwarder;
+
+import 'dart:async';
+
+import 'asset_node.dart';
+
+/// A wrapper for an [AssetNode] that forwards events to a new node.
+///
+/// A forwarder is used when a class wants to forward an [AssetNode] that it
+/// gets as an input, but also wants to have control over when that node is
+/// marked as removed. The forwarder can be closed, thus removing its output
+/// node, without the original node having been removed.
+class AssetForwarder {
+  /// The subscription on the input node.
+  StreamSubscription _subscription;
+
+  /// The controller for the output node.
+  final AssetNodeController _controller;
+
+  /// The node to which events are forwarded.
+  AssetNode get node => _controller.node;
+
+  AssetForwarder(AssetNode node)
+      : _controller = new AssetNodeController(node.id, node.transform) {
+    _subscription = node.onStateChange.listen((state) {
+      if (state.isAvailable) {
+        _controller.setAvailable(node.asset);
+      } else if (state.isDirty) {
+        _controller.setDirty();
+      } else {
+        assert(state.isRemoved);
+        close();
+      }
+    });
+
+    if (node.state.isAvailable) {
+      _controller.setAvailable(node.asset);
+    } else if (node.state.isRemoved) {
+      close();
+    }
+  }
+
+  /// Closes the forwarder and marks [node] as removed.
+  void close() {
+    if (_controller.node.state.isRemoved) return;
+    _subscription.cancel();
+    _controller.setRemoved();
+  }
+}
diff --git a/pkg/barback/lib/src/asset_id.dart b/pkg/barback/lib/src/asset_id.dart
index d9cef32..c4ed1d8 100644
--- a/pkg/barback/lib/src/asset_id.dart
+++ b/pkg/barback/lib/src/asset_id.dart
@@ -4,9 +4,6 @@
 
 library barback.asset_id;
 
-import 'dart:async';
-import 'dart:io';
-
 import 'package:path/path.dart' as pathos;
 
 /// AssetIDs always use POSIX style paths regardless of the host platform.
diff --git a/pkg/barback/lib/src/asset_node.dart b/pkg/barback/lib/src/asset_node.dart
index 587f2bd..edc7408 100644
--- a/pkg/barback/lib/src/asset_node.dart
+++ b/pkg/barback/lib/src/asset_node.dart
@@ -9,7 +9,6 @@
 import 'asset.dart';
 import 'asset_id.dart';
 import 'errors.dart';
-import 'phase.dart';
 import 'transform_node.dart';
 
 /// Describes the current state of an asset as part of a transformation graph.
diff --git a/pkg/barback/lib/src/asset_set.dart b/pkg/barback/lib/src/asset_set.dart
index b432425..08c2db9 100644
--- a/pkg/barback/lib/src/asset_set.dart
+++ b/pkg/barback/lib/src/asset_set.dart
@@ -4,9 +4,7 @@
 
 library barback.asset_set;
 
-import 'dart:async';
 import 'dart:collection';
-import 'dart:io';
 
 import 'asset.dart';
 import 'asset_id.dart';
diff --git a/pkg/barback/lib/src/barback.dart b/pkg/barback/lib/src/barback.dart
index 3dcb23e..313d42c 100644
--- a/pkg/barback/lib/src/barback.dart
+++ b/pkg/barback/lib/src/barback.dart
@@ -8,10 +8,12 @@
 
 import 'asset.dart';
 import 'asset_id.dart';
+import 'asset_set.dart';
 import 'build_result.dart';
 import 'errors.dart';
 import 'package_graph.dart';
 import 'package_provider.dart';
+import 'transformer.dart';
 
 /// A general-purpose asynchronous build dependency graph manager.
 ///
@@ -88,4 +90,19 @@
   /// Removes [removed] from the graph's known set of source assets.
   void removeSources(Iterable<AssetId> removed) =>
       _graph.removeSources(removed);
-}
\ No newline at end of file
+
+  /// Gets all output assets.
+  ///
+  /// If a build is currently in progress, waits until it completes. The
+  /// returned future will complete with a [BarbackException] if the build is
+  /// not successful.
+  Future<AssetSet> getAllAssets() => _graph.getAllAssets();
+
+  /// Sets the transformer phases for [package]'s assets to [transformers].
+  ///
+  /// To the extent that [transformers] is similar to the previous transformer
+  /// phases for [package], the existing asset graph will be preserved.
+  void updateTransformers(String package,
+          Iterable<Iterable<Transformer>> transformers) =>
+      _graph.updateTransformers(package, transformers);
+}
diff --git a/pkg/barback/lib/src/build_result.dart b/pkg/barback/lib/src/build_result.dart
index 89ee681..2cb305c 100644
--- a/pkg/barback/lib/src/build_result.dart
+++ b/pkg/barback/lib/src/build_result.dart
@@ -8,6 +8,7 @@
 
 import 'package:stack_trace/stack_trace.dart';
 
+import 'errors.dart';
 import 'utils.dart';
 
 /// An event indicating that the cascade has finished building all assets.
@@ -23,7 +24,7 @@
   bool get succeeded => errors.isEmpty;
 
   BuildResult(Iterable<BarbackException> errors)
-      : errors = errors.toSet();
+      : errors = flattenAggregateExceptions(errors).toSet();
 
   /// Creates a build result indicating a successful build.
   ///
diff --git a/pkg/barback/lib/src/change_batch.dart b/pkg/barback/lib/src/change_batch.dart
index aa2a1c4..8f98995 100644
--- a/pkg/barback/lib/src/change_batch.dart
+++ b/pkg/barback/lib/src/change_batch.dart
@@ -4,7 +4,6 @@
 
 library barback.change_batch;
 
-import 'asset.dart';
 import 'asset_id.dart';
 
 /// Represents a batch of source asset changes: additions, removals and
diff --git a/pkg/barback/lib/src/errors.dart b/pkg/barback/lib/src/errors.dart
index f356066..a240bb4 100644
--- a/pkg/barback/lib/src/errors.dart
+++ b/pkg/barback/lib/src/errors.dart
@@ -5,12 +5,12 @@
 library barback.errors;
 
 import 'dart:async';
-import 'dart:io';
 
 import 'package:stack_trace/stack_trace.dart';
 
 import 'asset_id.dart';
 import 'transformer.dart';
+import 'utils.dart';
 
 /// Error thrown when an asset with [id] cannot be found.
 class AssetNotFoundException implements Exception {
@@ -21,10 +21,54 @@
   String toString() => "Could not find asset $id.";
 }
 
+/// Replaces any occurrences of [AggregateException] in [errors] with the list
+/// of errors it contains.
+Iterable<BarbackException> flattenAggregateExceptions(
+    Iterable<BarbackException> errors) {
+  return errors.expand((error) {
+    if (error is! AggregateException) return [error];
+    return error.errors;
+  });
+}
+
 /// The interface for exceptions from the barback graph or its transformers.
 ///
 /// These exceptions are never produced by programming errors in barback.
-abstract class BarbackException implements Exception {}
+abstract class BarbackException implements Exception {
+  /// Takes a collection of [BarbackExceptions] and returns a single exception
+  /// that contains them all.
+  ///
+  /// If [errors] is empty, returns `null`. If it only has one error, that
+  /// error is returned. Otherwise, an [AggregateException] is returned.
+  static BarbackException aggregate(Iterable<BarbackException> errors) {
+    if (errors.isEmpty) return null;
+    if (errors.length == 1) return errors.single;
+    return new AggregateException(errors);
+  }
+}
+
+/// An error that wraps a collection of other [BarbackException]s.
+///
+/// It implicitly flattens any [AggregateException]s that occur in the list of
+/// exceptions it wraps.
+class AggregateException implements BarbackException {
+  final Set<BarbackException> errors;
+
+  AggregateException(Iterable<BarbackException> errors)
+      : errors = flattenAggregateExceptions(errors).toSet();
+
+  String toString() {
+    var buffer = new StringBuffer();
+    buffer.writeln("Multiple errors occurred:\n");
+
+    for (var error in errors) {
+      buffer.writeln(prefixLines(error.toString(),
+                                 prefix: "  ", firstPrefix: "- "));
+    }
+
+    return buffer.toString();
+  }
+}
 
 /// Error thrown when two or more transformers both output an asset with [id].
 class AssetCollisionException implements BarbackException {
@@ -67,34 +111,49 @@
       "same package (${transform.primaryId.package}).";
 }
 
-/// Error wrapping an exception thrown by a transform.
-class TransformerException implements BarbackException {
-  /// The transform that threw the exception.
-  final TransformInfo transform;
-
+/// Base class for an error that wraps another.
+abstract class _WrappedException implements BarbackException {
   /// The wrapped exception.
   final error;
 
-  TransformerException(this.transform, this.error);
+  _WrappedException(this.error);
 
-  String toString() => "Transform $transform threw error: $error\n" +
-    new Trace.from(getAttachedStackTrace(error)).terse.toString();
+  String get _message;
+
+  String toString() {
+    var result = "$_message: $error";
+
+    var stack = getAttachedStackTrace(error);
+    if (stack != null) {
+      result = "$result\n${new Trace.from(stack).terse}";
+    }
+
+    return result;
+  }
+}
+
+/// Error wrapping an exception thrown by a transform.
+class TransformerException extends _WrappedException {
+  /// The transform that threw the exception.
+  final TransformInfo transform;
+
+  TransformerException(this.transform, error)
+      : super(error);
+
+  String get _message => "Transform $transform threw error";
 }
 
 /// Error thrown when a source asset [id] fails to load.
 ///
 /// This can be thrown either because the source asset was expected to exist and
 /// did not or because reading it failed somehow.
-class AssetLoadException implements BarbackException {
+class AssetLoadException extends _WrappedException {
   final AssetId id;
 
-  /// The wrapped exception.
-  final error;
+  AssetLoadException(this.id, error)
+      : super(error);
 
-  AssetLoadException(this.id, this.error);
-
-  String toString() => "Failed to load source asset $id: $error\n"
-      "${new Trace.from(getAttachedStackTrace(error)).terse}";
+  String get _message => "Failed to load source asset $id";
 }
 
 /// Information about a single transform in the barback graph.
diff --git a/pkg/barback/lib/src/package_graph.dart b/pkg/barback/lib/src/package_graph.dart
index c46ed55..a402a27 100644
--- a/pkg/barback/lib/src/package_graph.dart
+++ b/pkg/barback/lib/src/package_graph.dart
@@ -6,15 +6,14 @@
 
 import 'dart:async';
 
-import 'package:stack_trace/stack_trace.dart';
-
-import 'asset.dart';
 import 'asset_cascade.dart';
 import 'asset_id.dart';
 import 'asset_node.dart';
+import 'asset_set.dart';
 import 'build_result.dart';
 import 'errors.dart';
 import 'package_provider.dart';
+import 'transformer.dart';
 import 'utils.dart';
 
 /// The collection of [AssetCascade]s for an entire application.
@@ -55,12 +54,17 @@
   Stream<BarbackException> get errors => _errors;
   Stream<BarbackException> _errors;
 
+  /// The most recent error emitted from a cascade's result stream.
+  ///
+  /// This is used to pipe an unexpected error from a build to the resulting
+  /// [Future] returned by [getAllAssets].
+  var _lastUnexpectedError;
+
   /// Creates a new [PackageGraph] that will transform assets in all packages
   /// made available by [provider].
   PackageGraph(this.provider) {
     for (var package in provider.packages) {
-      var cascade = new AssetCascade(this, package,
-          provider.getTransformers(package));
+      var cascade = new AssetCascade(this, package);
       // The initial result for each cascade is "success" since the cascade
       // doesn't start building until some source in that graph is updated.
       _cascadeResults[package] = new BuildResult.success();
@@ -76,7 +80,10 @@
         // errors, the result will automatically be considered a success.
         _resultsController.add(new BuildResult(unionAll(
             _cascadeResults.values.map((result) => result.errors))));
-      }, onError: _resultsController.addError);
+      }, onError: (error) {
+        _lastUnexpectedError = error;
+        _resultsController.addError(error);
+      });
     }
 
     _errors = mergeStreams(_cascades.values.map((cascade) => cascade.errors));
@@ -95,6 +102,38 @@
     return new Future.value(null);
   }
 
+  /// Gets all output assets.
+  ///
+  /// If a build is currently in progress, waits until it completes. The
+  /// returned future will complete with an error if the build is not
+  /// successful.
+  Future<AssetSet> getAllAssets() {
+    if (_cascadeResults.values.contains(null)) {
+      // A build is still ongoing, so wait for it to complete and try again.
+      return results.first.then((_) => getAllAssets());
+    }
+
+    // If an unexpected error occurred, complete with that.
+    if (_lastUnexpectedError != null) {
+      var error = _lastUnexpectedError;
+      _lastUnexpectedError = null;
+      return new Future.error(error);
+    }
+
+    // If the build completed with an error, complete the future with it.
+    var errors = unionAll(
+        _cascadeResults.values.map((result) => result.errors));
+    if (errors.isNotEmpty) {
+      return new Future.error(BarbackException.aggregate(errors));
+    }
+
+    // Otherwise, return all of the final output assets.
+    var assets = unionAll(_cascades.values.map(
+        (cascade) => cascade.availableOutputs.toSet()));
+
+    return new Future.value(new AssetSet.from(assets));
+  }
+
   /// Adds [sources] to the graph's known set of source assets.
   ///
   /// Begins applying any transforms that can consume any of the sources. If a
@@ -118,4 +157,10 @@
       cascade.removeSources(ids);
     });
   }
+
+  void updateTransformers(String package,
+      Iterable<Iterable<Transformer>> transformers) {
+    _cascadeResults[package] = null;
+    _cascades[package].updateTransformers(transformers);
+  }
 }
diff --git a/pkg/barback/lib/src/package_provider.dart b/pkg/barback/lib/src/package_provider.dart
index 031caf8..349785c 100644
--- a/pkg/barback/lib/src/package_provider.dart
+++ b/pkg/barback/lib/src/package_provider.dart
@@ -8,7 +8,6 @@
 
 import 'asset.dart';
 import 'asset_id.dart';
-import 'transformer.dart';
 
 /// API for locating and accessing packages on disk.
 ///
@@ -21,12 +20,6 @@
   /// dependencies.
   Iterable<String> get packages;
 
-  /// Returns the list of transformer phases that are applicable to [package].
-  ///
-  /// The phases will be run in sequence, with the outputs of one pipelined into
-  /// the next. All [Transformer]s in a single phase will be run in parallel.
-  Iterable<Iterable<Transformer>> getTransformers(String package);
-
   /// Loads an asset from disk.
   ///
   /// This should be re-entrant; it may be called multiple times with the same
diff --git a/pkg/barback/lib/src/phase.dart b/pkg/barback/lib/src/phase.dart
index 86444ad..690126a 100644
--- a/pkg/barback/lib/src/phase.dart
+++ b/pkg/barback/lib/src/phase.dart
@@ -7,14 +7,13 @@
 import 'dart:async';
 import 'dart:collection';
 
-import 'asset.dart';
 import 'asset_cascade.dart';
 import 'asset_id.dart';
 import 'asset_node.dart';
 import 'asset_set.dart';
 import 'errors.dart';
+import 'phase_input.dart';
 import 'stream_pool.dart';
-import 'transform_node.dart';
 import 'transformer.dart';
 import 'utils.dart';
 
@@ -34,47 +33,16 @@
   /// The cascade that owns this phase.
   final AssetCascade cascade;
 
-  /// This phase's position relative to the other phases. Zero-based.
-  final int _index;
-
   /// The transformers that can access [inputs].
   ///
   /// Their outputs will be available to the next phase.
-  final List<Transformer> _transformers;
+  final Set<Transformer> _transformers;
 
-  /// The inputs that are available for transforms in this phase to consume.
+  /// The inputs for this phase.
   ///
   /// For the first phase, these will be the source assets. For all other
   /// phases, they will be the outputs from the previous phase.
-  final _inputs = new Map<AssetId, AssetNode>();
-
-  /// The transforms currently applicable to assets in [inputs], indexed by
-  /// the ids of their primary inputs.
-  ///
-  /// These are the transforms that have been "wired up": they represent a
-  /// repeatable transformation of a single concrete set of inputs. "dart2js"
-  /// is a transformer. "dart2js on web/main.dart" is a transform.
-  final _transforms = new Map<AssetId, Set<TransformNode>>();
-
-  /// Controllers for assets that aren't consumed by transforms in this phase.
-  ///
-  /// These assets are passed to the next phase unmodified. They need
-  /// intervening controllers to ensure that the outputs can be marked dirty
-  /// when determining whether transforms apply, and removed if they do.
-  final _passThroughControllers = new Map<AssetId, AssetNodeController>();
-
-  /// Futures that will complete once the transformers that can consume a given
-  /// asset are determined.
-  ///
-  /// Whenever an asset is added or modified, we need to asynchronously
-  /// determine which transformers can use it as their primary input. We can't
-  /// start processing until we know which transformers to run, and this allows
-  /// us to wait until we do.
-  var _adjustTransformersFutures = new Map<AssetId, Future>();
-
-  /// New asset nodes that were added while [_adjustTransformers] was still
-  /// being run on an old version of that asset.
-  var _pendingNewInputs = new Map<AssetId, AssetNode>();
+  final _inputs = new Map<AssetId, PhaseInput>();
 
   /// A map of output ids to the asset node outputs for those ids and the
   /// transforms that produced those asset nodes.
@@ -97,18 +65,25 @@
 
   /// A controller whose stream feeds into [_onDirtyPool].
   ///
-  /// This is used whenever an input is added, changed, or removed. It's
-  /// sometimes redundant with the events collected from [_transforms], but this
-  /// stream is necessary for new and removed inputs, and the transform stream
-  /// is necessary for modified secondary inputs.
+  /// This is used whenever an input is added or transforms are changed.
   final _onDirtyController = new StreamController.broadcast(sync: true);
 
   /// The phase after this one.
   ///
   /// Outputs from this phase will be passed to it.
-  final Phase _next;
+  Phase get next => _next;
+  Phase _next;
 
-  Phase(this.cascade, this._index, this._transformers, this._next) {
+  /// Returns all currently-available output assets for this phase.
+  AssetSet get availableOutputs {
+    return new AssetSet.from(_outputs.values
+        .map((queue) => queue.first)
+        .where((node) => node.state.isAvailable)
+        .map((node) => node.asset));
+  }
+
+  Phase(this.cascade, Iterable<Transformer> transformers)
+      : _transformers = transformers.toSet() {
     _onDirtyPool.add(_onDirtyController.stream);
   }
 
@@ -123,51 +98,13 @@
   /// removed and re-created. The phase will automatically handle updated assets
   /// using the [AssetNode.onStateChange] stream.
   void addInput(AssetNode node) {
-    // We remove [node.id] from [inputs] as soon as the node is removed rather
-    // than at the same time [node.id] is removed from [_transforms] so we don't
-    // have to wait on [_adjustTransformers]. It's important that [inputs] is
-    // always up-to-date so that the [AssetCascade] can look there for available
-    // assets.
-    _inputs[node.id] = node;
-    node.whenRemoved.then((_) => _inputs.remove(node.id));
+    if (_inputs.containsKey(node.id)) _inputs[node.id].remove();
 
-    if (!_adjustTransformersFutures.containsKey(node.id)) {
-      _transforms[node.id] = new Set<TransformNode>();
-      _adjustTransformers(node);
-      return;
-    }
-
-    // If an input is added while the same input is still being processed,
-    // that means that the asset was removed and recreated while
-    // [_adjustTransformers] was being run on the old value. We have to wait
-    // until that finishes, then run it again on whatever the newest version
-    // of that asset is.
-
-    // We may already be waiting for the existing [_adjustTransformers] call to
-    // finish. If so, all we need to do is change the node that will be loaded
-    // after it completes.
-    var containedKey = _pendingNewInputs.containsKey(node.id);
-    _pendingNewInputs[node.id] = node;
-    if (containedKey) return;
-
-    // If we aren't already waiting, start doing so.
-    _adjustTransformersFutures[node.id].then((_) {
-      assert(!_adjustTransformersFutures.containsKey(node.id));
-      assert(_pendingNewInputs.containsKey(node.id));
-      _transforms[node.id] = new Set<TransformNode>();
-      _adjustTransformers(_pendingNewInputs.remove(node.id));
-    }, onError: (_) {
-      // If there was a programmatic error while processing the old input,
-      // we don't want to just ignore it; it may have left the system in an
-      // inconsistent state. We also don't want to top-level it, so we
-      // ignore it here but don't start processing the new input. That way
-      // when [process] is called, the error will be piped through its
-      // return value.
-    }).catchError((e) {
-      // If our code above has a programmatic error, ensure it will be piped
-      // through [process] by putting it into [_adjustTransformersFutures].
-      _adjustTransformersFutures[node.id] = new Future.error(e);
-    });
+    var input = new PhaseInput(this, node, _transformers);
+    _inputs[node.id] = input;
+    input.input.whenRemoved.then((_) => _inputs.remove(node.id));
+    _onDirtyPool.add(input.onDirty);
+    _onDirtyController.add(null);
   }
 
   /// Gets the asset node for an input [id].
@@ -175,189 +112,60 @@
   /// If an input with that ID cannot be found, returns null.
   Future<AssetNode> getInput(AssetId id) {
     return newFuture(() {
-      if (id.package == cascade.package) return _inputs[id];
-      return cascade.graph.getAssetNode(id);
+      if (id.package != cascade.package) return cascade.graph.getAssetNode(id);
+      if (_inputs.containsKey(id)) return _inputs[id].input;
+      return null;
     });
   }
 
-  /// Asynchronously determines which transformers can consume [node] as a
-  /// primary input and creates transforms for them.
+  /// Gets the asset node for an output [id].
   ///
-  /// This ensures that if [node] is modified or removed during or after the
-  /// time it takes to adjust its transformers, they're appropriately
-  /// re-adjusted. Its progress can be tracked in [_adjustTransformersFutures].
-  void _adjustTransformers(AssetNode node) {
-    // Mark the phase as dirty. This may not actually end up creating any new
-    // transforms, but we want adding or removing a source asset to consistently
-    // kick off a build, even if that build does nothing.
+  /// If an output with that ID cannot be found, returns null.
+  Future<AssetNode> getOutput(AssetId id) {
+    return newFuture(() {
+      if (id.package != cascade.package) return cascade.graph.getAssetNode(id);
+      if (!_outputs.containsKey(id)) return null;
+      return _outputs[id].first;
+    });
+  }
+
+  /// Set this phase's transformers to [transformers].
+  void updateTransformers(Iterable<Transformer> transformers) {
     _onDirtyController.add(null);
-
-    // If there's a pass-through for this node, mark it dirty while we figure
-    // out whether we need to add any transforms for it.
-    var controller = _passThroughControllers[node.id];
-    if (controller != null) controller.setDirty();
-
-    // Once the input is available, hook up transformers for it. If it changes
-    // while that's happening, try again.
-    _adjustTransformersFutures[node.id] = node.tryUntilStable((asset) {
-      var oldTransformers = _transforms[node.id]
-          .map((transform) => transform.transformer).toSet();
-
-      return _removeStaleTransforms(asset)
-          .then((_) => _addFreshTransforms(node, oldTransformers));
-    }).then((_) {
-      _adjustPassThrough(node);
-
-      // Now all the transforms are set up correctly and the asset is available
-      // for the time being. Set up handlers for when the asset changes in the
-      // future.
-      node.onStateChange.first.then((state) {
-        if (state.isRemoved) {
-          _onDirtyController.add(null);
-          _transforms.remove(node.id);
-          var passThrough = _passThroughControllers.remove(node.id);
-          if (passThrough != null) passThrough.setRemoved();
-        } else {
-          _adjustTransformers(node);
-        }
-      }).catchError((e) {
-        _adjustTransformersFutures[node.id] = new Future.error(e);
-      });
-    }).catchError((error) {
-      if (error is! AssetNotFoundException || error.id != node.id) throw error;
-
-      // If the asset is removed, [tryUntilStable] will throw an
-      // [AssetNotFoundException]. In that case, just remove all transforms for
-      // the node, and its pass-through.
-      _transforms.remove(node.id);
-      var passThrough = _passThroughControllers.remove(node.id);
-      if (passThrough != null) passThrough.setRemoved();
-    }).whenComplete(() {
-      _adjustTransformersFutures.remove(node.id);
-    });
-
-    // Don't top-level errors coming from the input processing. Any errors will
-    // eventually be piped through [process]'s returned Future.
-    _adjustTransformersFutures[node.id].catchError((_) {});
-  }
-
-  // Remove any old transforms that used to have [asset] as a primary asset but
-  // no longer apply to its new contents.
-  Future _removeStaleTransforms(Asset asset) {
-    return Future.wait(_transforms[asset.id].map((transform) {
-      // TODO(rnystrom): Catch all errors from isPrimary() and redirect to
-      // results.
-      return transform.transformer.isPrimary(asset).then((isPrimary) {
-        if (isPrimary) return;
-        _transforms[asset.id].remove(transform);
-        _onDirtyPool.remove(transform.onDirty);
-        transform.remove();
-      });
-    }));
-  }
-
-  // Add new transforms for transformers that consider [node]'s asset to be a
-  // primary input.
-  //
-  // [oldTransformers] is the set of transformers that had [node] as a primary
-  // input prior to this. They don't need to be checked, since they were removed
-  // or preserved in [_removeStaleTransforms].
-  Future _addFreshTransforms(AssetNode node, Set<Transformer> oldTransformers) {
-    return Future.wait(_transformers.map((transformer) {
-      if (oldTransformers.contains(transformer)) return new Future.value();
-
-      // If the asset is unavailable, the results of this [_adjustTransformers]
-      // run will be discarded, so we can just short-circuit.
-      if (node.asset == null) return new Future.value();
-
-      // We can safely access [node.asset] here even though it might have
-      // changed since (as above) if it has, [_adjustTransformers] will just be
-      // re-run.
-      // TODO(rnystrom): Catch all errors from isPrimary() and redirect to
-      // results.
-      return transformer.isPrimary(node.asset).then((isPrimary) {
-        if (!isPrimary) return;
-        var transform = new TransformNode(this, transformer, node);
-        _transforms[node.id].add(transform);
-        _onDirtyPool.add(transform.onDirty);
-      });
-    }));
-  }
-
-  /// Adjust whether [node] is passed through the phase unmodified, based on
-  /// whether it's consumed by other transforms in this phase.
-  ///
-  /// If [node] was already passed-through, this will update the passed-through
-  /// value.
-  void _adjustPassThrough(AssetNode node) {
-    assert(node.state.isAvailable);
-
-    if (_transforms[node.id].isEmpty) {
-      var controller = _passThroughControllers[node.id];
-      if (controller != null) {
-        controller.setAvailable(node.asset);
-      } else {
-        _passThroughControllers[node.id] =
-            new AssetNodeController.available(node.asset, node.transform);
-      }
-    } else {
-      var controller = _passThroughControllers.remove(node.id);
-      if (controller != null) controller.setRemoved();
+    _transformers.clear();
+    _transformers.addAll(transformers);
+    for (var input in _inputs.values) {
+      input.updateTransformers(_transformers);
     }
   }
 
+  /// Add a new phase after this one with [transformers].
+  ///
+  /// This may only be called on a phase with no phase following it.
+  Phase addPhase(Iterable<Transformer> transformers) {
+    assert(_next == null);
+    _next = new Phase(cascade, transformers);
+    for (var outputs in _outputs.values) {
+      _next.addInput(outputs.first);
+    }
+    return _next;
+  }
+
   /// Processes this phase.
   ///
   /// Returns a future that completes when processing is done. If there is
   /// nothing to process, returns `null`.
   Future process() {
-    if (_adjustTransformersFutures.isEmpty) return _processTransforms();
-    return _waitForInputs().then((_) => _processTransforms());
-  }
+    if (!_inputs.values.any((input) => input.isDirty)) return null;
 
-  Future _waitForInputs() {
-    if (_adjustTransformersFutures.isEmpty) return new Future.value();
-    return Future.wait(_adjustTransformersFutures.values)
-        .then((_) => _waitForInputs());
-  }
-
-  /// Applies all currently wired up and dirty transforms.
-  Future _processTransforms() {
-    if (_next == null) return;
-
-    var newPassThroughs = _passThroughControllers.values
-        .map((controller) => controller.node)
-        .where((output) {
-      return !_outputs.containsKey(output.id) ||
-        !_outputs[output.id].contains(output);
-    }).toSet();
-
-    // Convert this to a list so we can safely modify _transforms while
-    // iterating over it.
-    var dirtyTransforms =
-        flatten(_transforms.values.map((transforms) => transforms.toList()))
-        .where((transform) => transform.isDirty).toList();
-
-    if (dirtyTransforms.isEmpty && newPassThroughs.isEmpty) return null;
-
-    var collisions = _passAssetsThrough(newPassThroughs);
-    return Future.wait(dirtyTransforms.map((transform) {
-      return transform.apply().then((outputs) {
-        for (var output in outputs) {
-          if (_outputs.containsKey(output.id)) {
-            _outputs[output.id].add(output);
-            collisions.add(output.id);
-          } else {
-            _outputs[output.id] = new Queue<AssetNode>.from([output]);
-            _next.addInput(output);
-          }
-
-          _handleOutputRemoval(output);
-        }
+    return Future.wait(_inputs.values.map((input) {
+      if (!input.isDirty) return new Future.value(new Set());
+      return input.process().then((outputs) {
+        return outputs.where(_addOutput).map((output) => output.id).toSet();
       });
-    })).then((_) {
+    })).then((collisionsList) {
       // Report collisions in a deterministic order.
-      collisions = collisions.toList();
+      var collisions = unionAll(collisionsList).toList();
       collisions.sort((a, b) => a.compareTo(b));
       for (var collision in collisions) {
         // Ensure that there's still a collision. It's possible it was resolved
@@ -371,28 +179,21 @@
     });
   }
 
-  /// Pass all new assets that aren't consumed by transforms through to the next
-  /// phase.
+  /// Add [output] as an output of this phase, forwarding it to the next phase
+  /// if necessary.
   ///
-  /// Returns a set of asset ids that have collisions between new passed-through
-  /// assets and pre-existing transform outputs.
-  Set<AssetId> _passAssetsThrough(Set<AssetId> newPassThroughs) {
-    var collisions = new Set<AssetId>();
-    for (var output in newPassThroughs) {
-      if (_outputs.containsKey(output.id)) {
-        // There shouldn't be another pass-through asset with the same id.
-        assert(!_outputs[output.id].any((asset) => asset.transform == null));
+  /// Returns whether or not [output] collides with another pre-existing output.
+  bool _addOutput(AssetNode output) {
+    _handleOutputRemoval(output);
 
-        _outputs[output.id].add(output);
-        collisions.add(output.id);
-      } else {
-        _outputs[output.id] = new Queue<AssetNode>.from([output]);
-        _next.addInput(output);
-      }
-
-      _handleOutputRemoval(output);
+    if (_outputs.containsKey(output.id)) {
+      _outputs[output.id].add(output);
+      return true;
     }
-    return collisions;
+
+    _outputs[output.id] = new Queue<AssetNode>.from([output]);
+    if (_next != null) _next.addInput(output);
+    return false;
   }
 
   /// Properly resolve collisions when [output] is removed.
@@ -414,7 +215,7 @@
       // (chronologically) to the next phase. Pump the event queue first to give
       // [_next] a chance to handle the removal of its input before getting a
       // new input.
-      if (wasFirst) {
+      if (wasFirst && _next != null) {
         newFuture(() => _next.addInput(assets.first));
       }
 
diff --git a/pkg/barback/lib/src/phase_input.dart b/pkg/barback/lib/src/phase_input.dart
new file mode 100644
index 0000000..7ba6c20
--- /dev/null
+++ b/pkg/barback/lib/src/phase_input.dart
@@ -0,0 +1,296 @@
+// Copyright (c) 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.phase_input;
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'asset.dart';
+import 'asset_forwarder.dart';
+import 'asset_node.dart';
+import 'errors.dart';
+import 'stream_pool.dart';
+import 'transform_node.dart';
+import 'transformer.dart';
+import 'utils.dart';
+
+/// A class for watching a single [AssetNode] and running any transforms that
+/// take that node as a primary input.
+class PhaseInput {
+  /// The phase for which this is an input.
+  final Phase _phase;
+
+  /// The transformers to (potentially) run against [input].
+  final Set<Transformer> _transformers;
+
+  /// The transforms currently applicable to [input].
+  ///
+  /// These are the transforms that have been "wired up": they represent a
+  /// repeatable transformation of a single concrete set of inputs. "dart2js" is
+  /// a transformer. "dart2js on web/main.dart" is a transform.
+  final _transforms = new Set<TransformNode>();
+
+  /// A forwarder for the input [AssetNode] for this phase.
+  ///
+  /// This is used to mark the node as removed should the input ever be removed.
+  final AssetForwarder _inputForwarder;
+
+  /// The asset node for this input.
+  AssetNode get input => _inputForwarder.node;
+
+  /// The controller that's used for the output node if [input] isn't consumed
+  /// by any transformers.
+  ///
+  /// This needs an intervening controller to ensure that the output can be
+  /// marked dirty when determining whether transforms apply, and removed if
+  /// they do. It's null if the asset is not being passed through.
+  AssetNodeController _passThroughController;
+
+  /// Whether [_passThroughController] has been newly created since [process]
+  /// last completed.
+  bool _newPassThrough = false;
+
+  /// A Future that will complete once the transformers that consume [input] are
+  /// determined.
+  Future _adjustTransformersFuture;
+
+  /// A stream that emits an event whenever this input becomes dirty and needs
+  /// [process] to be called.
+  ///
+  /// This may emit events when the input was already dirty or while processing
+  /// transforms. Events are emitted synchronously to ensure that the dirty
+  /// state is thoroughly propagated as soon as any assets are changed.
+  Stream get onDirty => _onDirtyPool.stream;
+  final _onDirtyPool = new StreamPool.broadcast();
+
+  /// A controller whose stream feeds into [_onDirtyPool].
+  ///
+  /// This is used whenever the input is changed or removed. It's sometimes
+  /// redundant with the events collected from [_transforms], but this stream is
+  /// necessary for removed inputs, and the transform stream is necessary for
+  /// modified secondary inputs.
+  final _onDirtyController = new StreamController.broadcast(sync: true);
+
+  /// Whether this input is dirty and needs [process] to be called.
+  bool get isDirty => _adjustTransformersFuture != null ||
+      _newPassThrough || _transforms.any((transform) => transform.isDirty);
+
+  PhaseInput(this._phase, AssetNode input, Iterable<Transformer> transformers)
+      : _transformers = transformers.toSet(),
+        _inputForwarder = new AssetForwarder(input) {
+    _onDirtyPool.add(_onDirtyController.stream);
+
+    input.onStateChange.listen((state) {
+      if (state.isRemoved) {
+        remove();
+      } else if (_adjustTransformersFuture == null) {
+        _adjustTransformers();
+      }
+    });
+
+    _adjustTransformers();
+  }
+
+  /// Removes this input.
+  ///
+  /// This marks all outputs of the input as removed.
+  void remove() {
+    _onDirtyController.add(null);
+    _onDirtyPool.close();
+    _inputForwarder.close();
+    if (_passThroughController != null) {
+      _passThroughController.setRemoved();
+      _passThroughController = null;
+    }
+  }
+
+  /// Set this input's transformers to [transformers].
+  void updateTransformers(Set<Transformer> newTransformers) {
+    var oldTransformers = _transformers.toSet();
+    for (var removedTransformer in
+         oldTransformers.difference(newTransformers)) {
+      _transformers.remove(removedTransformer);
+
+      // If the transformers are being adjusted for [id], it will
+      // automatically pick up on [removedTransformer] being gone.
+      if (_adjustTransformersFuture != null) continue;
+
+      _transforms.removeWhere((transform) {
+        if (transform.transformer != removedTransformer) return false;
+        transform.remove();
+        return true;
+      });
+    }
+
+    if (_transforms.isEmpty && _adjustTransformersFuture == null &&
+        _passThroughController == null) {
+      _passThroughController =
+          new AssetNodeController.available(input.asset, input.transform);
+      _newPassThrough = true;
+    }
+
+    var brandNewTransformers = newTransformers.difference(oldTransformers);
+    if (brandNewTransformers.isEmpty) return;
+
+    brandNewTransformers.forEach(_transformers.add);
+    _adjustTransformers();
+  }
+
+  /// Asynchronously determines which transformers can consume [input] as a
+  /// primary input and creates transforms for them.
+  ///
+  /// This ensures that if [input] is modified or removed during or after the
+  /// time it takes to adjust its transformers, they're appropriately
+  /// re-adjusted. Its progress can be tracked in [_adjustTransformersFuture].
+  void _adjustTransformers() {
+    // Mark the input as dirty. This may not actually end up creating any new
+    // transforms, but we want adding or removing a source asset to consistently
+    // kick off a build, even if that build does nothing.
+    _onDirtyController.add(null);
+
+    // If there's a pass-through for this input, mark it dirty while we figure
+    // out whether we need to add any transforms for it.
+    if (_passThroughController != null) _passThroughController.setDirty();
+
+    // Once the input is available, hook up transformers for it. If it changes
+    // while that's happening, try again.
+    _adjustTransformersFuture = _tryUntilStable((asset, transformers) {
+      var oldTransformers =
+          _transforms.map((transform) => transform.transformer).toSet();
+
+      return _removeStaleTransforms(asset, transformers).then((_) =>
+          _addFreshTransforms(transformers, oldTransformers));
+    }).then((_) => _adjustPassThrough()).catchError((error) {
+      if (error is! AssetNotFoundException || error.id != input.id) {
+        throw error;
+      }
+
+      // If the asset is removed, [_tryUntilStable] will throw an
+      // [AssetNotFoundException]. In that case, just remove it.
+      remove();
+    }).whenComplete(() {
+      _adjustTransformersFuture = null;
+    });
+
+    // Don't top-level errors coming from the input processing. Any errors will
+    // eventually be piped through [process]'s returned Future.
+    _adjustTransformersFuture.catchError((_) {});
+  }
+
+  // Remove any old transforms that used to have [asset] as a primary asset but
+  // no longer apply to its new contents.
+  Future _removeStaleTransforms(Asset asset, Set<Transformer> transformers) {
+    return Future.wait(_transforms.map((transform) {
+      return newFuture(() {
+        if (!transformers.contains(transform.transformer)) return false;
+
+        // TODO(rnystrom): Catch all errors from isPrimary() and redirect to
+        // results.
+        return transform.transformer.isPrimary(asset);
+      }).then((isPrimary) {
+        if (isPrimary) return;
+        _transforms.remove(transform);
+        transform.remove();
+      });
+    }));
+  }
+
+  // Add new transforms for transformers that consider [input]'s asset to be a
+  // primary input.
+  //
+  // [oldTransformers] is the set of transformers for which there were
+  // transforms that had [input] as a primary input prior to this. They don't
+  // need to be checked, since their transforms were removed or preserved in
+  // [_removeStaleTransforms].
+  Future _addFreshTransforms(Set<Transformer> transformers,
+      Set<Transformer> oldTransformers) {
+    return Future.wait(transformers.map((transformer) {
+      if (oldTransformers.contains(transformer)) return new Future.value();
+
+      // If the asset is unavailable, the results of this [_adjustTransformers]
+      // run will be discarded, so we can just short-circuit.
+      if (input.asset == null) return new Future.value();
+
+      // We can safely access [input.asset] here even though it might have
+      // changed since (as above) if it has, [_adjustTransformers] will just be
+      // re-run.
+      // TODO(rnystrom): Catch all errors from isPrimary() and redirect to
+      // results.
+      return transformer.isPrimary(input.asset).then((isPrimary) {
+        if (!isPrimary) return;
+        var transform = new TransformNode(_phase, transformer, input);
+        _transforms.add(transform);
+        _onDirtyPool.add(transform.onDirty);
+      });
+    }));
+  }
+
+  /// Adjust whether [input] is passed through the phase unmodified, based on
+  /// whether it's consumed by other transforms in this phase.
+  ///
+  /// If [input] was already passed-through, this will update the passed-through
+  /// value.
+  void _adjustPassThrough() {
+    assert(input.state.isAvailable);
+
+    if (_transforms.isEmpty) {
+      if (_passThroughController != null) {
+        _passThroughController.setAvailable(input.asset);
+      } else {
+        _passThroughController =
+            new AssetNodeController.available(input.asset, input.transform);
+        _newPassThrough = true;
+      }
+    } else if (_passThroughController != null) {
+      _passThroughController.setRemoved();
+      _passThroughController = null;
+      _newPassThrough = false;
+    }
+  }
+
+  /// Like [AssetNode.tryUntilStable], but also re-runs [callback] if this
+  /// phase's transformers are modified.
+  Future _tryUntilStable(
+      Future callback(Asset asset, Set<Transformer> transformers)) {
+    var oldTransformers;
+    return input.tryUntilStable((asset) {
+      oldTransformers = _transformers.toSet();
+      return callback(asset, _transformers);
+    }).then((result) {
+      if (setEquals(oldTransformers, _transformers)) return result;
+      return _tryUntilStable(callback);
+    });
+  }
+
+  /// Processes the transforms for this input.
+  Future<Set<AssetNode>> process() {
+    if (_adjustTransformersFuture == null) return _processTransforms();
+    return _waitForInputs().then((_) => _processTransforms());
+  }
+
+  Future _waitForInputs() {
+    // Return a synchronous future so we can be sure [_adjustTransformers] isn't
+    // called between now and when the Future completes.
+    if (_adjustTransformersFuture == null) return new Future.sync(() {});
+    return _adjustTransformersFuture.then((_) => _waitForInputs());
+  }
+
+  /// Applies all currently wired up and dirty transforms.
+  Future<Set<AssetNode>> _processTransforms() {
+    if (input.state.isRemoved) return new Future.value(new Set());
+
+    if (_passThroughController != null) {
+      if (!_newPassThrough) return new Future.value(new Set());
+      _newPassThrough = false;
+      return new Future.value(
+          new Set<AssetNode>.from([_passThroughController.node]));
+    }
+
+    return Future.wait(_transforms.map((transform) {
+      if (!transform.isDirty) return new Future.value(new Set());
+      return transform.apply();
+    })).then((outputs) => unionAll(outputs));
+  }
+}
diff --git a/pkg/barback/lib/src/transform.dart b/pkg/barback/lib/src/transform.dart
index c254778..d5d7176 100644
--- a/pkg/barback/lib/src/transform.dart
+++ b/pkg/barback/lib/src/transform.dart
@@ -13,7 +13,6 @@
 import 'errors.dart';
 import 'transform_logger.dart';
 import 'transform_node.dart';
-import 'utils.dart';
 
 /// Creates a [Transform] by forwarding to the private constructor.
 ///
diff --git a/pkg/barback/lib/src/transform_node.dart b/pkg/barback/lib/src/transform_node.dart
index 1d3d1dd..578b2fa 100644
--- a/pkg/barback/lib/src/transform_node.dart
+++ b/pkg/barback/lib/src/transform_node.dart
@@ -14,7 +14,6 @@
 import 'phase.dart';
 import 'transform.dart';
 import 'transformer.dart';
-import 'utils.dart';
 
 /// Describes a transform on a set of assets and its relationship to the build
 /// dependency graph.
@@ -133,7 +132,7 @@
       // Don't allow partial results from a failed transform.
       newOutputs.clear();
     }).then((_) {
-      if (_isDirty) return [];
+      if (_isDirty) return new Set();
 
       return _adjustOutputs(newOutputs);
     });
diff --git a/pkg/barback/lib/src/transformer.dart b/pkg/barback/lib/src/transformer.dart
index 422066f..e8479f1 100644
--- a/pkg/barback/lib/src/transformer.dart
+++ b/pkg/barback/lib/src/transformer.dart
@@ -5,7 +5,6 @@
 library barback.transformer;
 
 import 'dart:async';
-import 'dart:io';
 
 import 'asset.dart';
 import 'transform.dart';
@@ -17,6 +16,15 @@
 /// files are all examples of transformers. To define your own transformation
 /// step, extend (or implement) this class.
 abstract class Transformer {
+  /// Override this to return a space-separated list of file extensions
+  /// (with leading `.`) that are allowed for the primary inputs to this
+  /// transformer.
+  ///
+  /// If you don't override [isPrimary] yourself, it defaults to allowing any
+  /// asset whose extension matches one of the ones returned by this. If you
+  /// don't override [isPrimary] *or* this, it allows all files.
+  String get allowedExtensions => null;
+
   /// Returns `true` if [input] can be a primary input for this transformer.
   ///
   /// While a transformer can read from multiple input files, one must be the
@@ -29,7 +37,20 @@
   /// of those to generate the final JS. However you still run dart2js "on" a
   /// single file: the entrypoint Dart file that has your `main()` method.
   /// This entrypoint file would be the primary input.
-  Future<bool> isPrimary(Asset input);
+  ///
+  /// If this is not overridden, defaults to allow any asset whose extension
+  /// matches one of the ones returned by [allowedExtensions]. If *that* is
+  /// not overridden, allows all assets.
+  Future<bool> isPrimary(Asset input) {
+    // Allow all files if [primaryExtensions] is not overridden.
+    if (allowedExtensions == null) return new Future.value(true);
+
+    for (var extension in allowedExtensions.split(" ")) {
+      if (input.id.extension == extension) return new Future.value(true);
+    }
+
+    return new Future.value(false);
+  }
 
   /// Run this transformer on on the primary input specified by [transform].
   ///
diff --git a/pkg/barback/lib/src/utils.dart b/pkg/barback/lib/src/utils.dart
index bee6084..3272e9e 100644
--- a/pkg/barback/lib/src/utils.dart
+++ b/pkg/barback/lib/src/utils.dart
@@ -72,6 +72,10 @@
 Map mapMapValues(Map map, fn(key, value)) =>
   new Map.fromIterable(map.keys, value: (key) => fn(key, map[key]));
 
+/// Returns whether [set1] has exactly the same elements as [set2].
+bool setEquals(Set set1, Set set2) =>
+  set1.length == set2.length && set1.containsAll(set2);
+
 /// Merges [streams] into a single stream that emits events from all sources.
 Stream mergeStreams(Iterable<Stream> streams) {
   streams = streams.toList();
diff --git a/pkg/barback/test/asset_id_test.dart b/pkg/barback/test/asset_id_test.dart
index 6e4a7d8..a55bb18 100644
--- a/pkg/barback/test/asset_id_test.dart
+++ b/pkg/barback/test/asset_id_test.dart
@@ -4,8 +4,6 @@
 
 library barback.test.asset_id_test;
 
-import 'dart:async';
-
 import 'package:barback/barback.dart';
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/barback/test/asset_set_test.dart b/pkg/barback/test/asset_set_test.dart
index 5b6b652..3208329 100644
--- a/pkg/barback/test/asset_set_test.dart
+++ b/pkg/barback/test/asset_set_test.dart
@@ -4,11 +4,7 @@
 
 library barback.test.asset_set_test;
 
-import 'dart:async';
-import 'dart:io';
-
 import 'package:barback/barback.dart';
-import 'package:barback/src/asset_set.dart';
 import 'package:unittest/unittest.dart';
 
 import 'utils.dart';
diff --git a/pkg/barback/test/package_graph/add_remove_transform_test.dart b/pkg/barback/test/package_graph/add_remove_transform_test.dart
new file mode 100644
index 0000000..b79c69a
--- /dev/null
+++ b/pkg/barback/test/package_graph/add_remove_transform_test.dart
@@ -0,0 +1,240 @@
+// Copyright (c) 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.package_graph.transform_test;
+
+import 'package:barback/src/utils.dart';
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../utils.dart';
+
+main() {
+  initConfig();
+  test("a new transformer is applied to a matching asset", () {
+    initGraph(["app|foo.blub"]);
+
+    updateSources(["app|foo.blub"]);
+    expectAsset("app|foo.blub", "foo");
+    buildShouldSucceed();
+
+    updateTransformers("app", [[new RewriteTransformer("blub", "blab")]]);
+    expectAsset("app|foo.blab", "foo.blab");
+    expectNoAsset("app|foo.blub");
+    buildShouldSucceed();
+  });
+
+  test("a new transformer is not applied to a non-matching asset", () {
+    initGraph(["app|foo.blub"]);
+
+    updateSources(["app|foo.blub"]);
+    expectAsset("app|foo.blub", "foo");
+    buildShouldSucceed();
+
+    updateTransformers("app", [[new RewriteTransformer("zip", "zap")]]);
+    expectAsset("app|foo.blub", "foo");
+    expectNoAsset("app|foo.zap");
+    buildShouldSucceed();
+  });
+
+  test("updateTransformers doesn't re-run an old transformer", () {
+    var rewrite = new RewriteTransformer("blub", "blab");
+    initGraph(["app|foo.blub"], {"app": [[rewrite]]});
+
+    updateSources(["app|foo.blub"]);
+    expectAsset("app|foo.blab", "foo.blab");
+    expectNoAsset("app|foo.blub");
+    buildShouldSucceed();
+
+    updateTransformers("app", [[rewrite]]);
+    expectAsset("app|foo.blab", "foo.blab");
+    expectNoAsset("app|foo.blub");
+    buildShouldSucceed();
+
+    expect(rewrite.numRuns, completion(equals(1)));
+  });
+
+  test("updateTransformers re-runs old transformers in a new phase", () {
+    var rewrite1 = new RewriteTransformer("txt", "blub");
+    var rewrite2 = new RewriteTransformer("blub", "blab");
+    initGraph(["app|foo.txt"], {"app": [[rewrite1], [rewrite2]]});
+
+    updateSources(["app|foo.txt"]);
+    expectAsset("app|foo.blab", "foo.blub.blab");
+    expectNoAsset("app|foo.blub");
+    buildShouldSucceed();
+
+    updateTransformers("app", [[rewrite2], [rewrite1]]);
+    expectAsset("app|foo.blub", "foo.blub");
+    expectNoAsset("app|foo.blab");
+    buildShouldSucceed();
+  });
+
+  test("updateTransformers re-runs an old transformer when a previous phase "
+      "changes", () {
+    var rewrite = new RewriteTransformer("txt", "out");
+    initGraph(["app|foo.txt"], {"app": [[], [rewrite]]});
+
+    updateSources(["app|foo.txt"]);
+    expectAsset("app|foo.out", "foo.out");
+    buildShouldSucceed();
+
+    updateTransformers("app", [
+      [new RewriteTransformer("txt", "txt")],
+      [rewrite]
+    ]);
+    expectAsset("app|foo.out", "foo.txt.out");
+    buildShouldSucceed();
+  });
+
+  test("a removed transformer is no longer applied", () {
+    initGraph(["app|foo.blub"], {"app": [
+      [new RewriteTransformer("blub", "blab")]
+    ]});
+
+    updateSources(["app|foo.blub"]);
+    expectAsset("app|foo.blab", "foo.blab");
+    expectNoAsset("app|foo.blub");
+    buildShouldSucceed();
+
+    updateTransformers("app", []);
+    expectAsset("app|foo.blub", "foo");
+    expectNoAsset("app|foo.blab");
+    buildShouldSucceed();
+  });
+
+  test("a new transformer is pipelined", () {
+    var rewrite1 = new RewriteTransformer("source", "phase1");
+    var rewrite3 = new RewriteTransformer("phase2", "phase3");
+    initGraph(["app|foo.source"], {"app": [
+      [rewrite1],
+      [rewrite3]
+    ]});
+
+    updateSources(["app|foo.source"]);
+    expectNoAsset("app|foo.phase3");
+    buildShouldSucceed();
+
+    updateTransformers("app", [
+      [rewrite1],
+      [new RewriteTransformer("phase1", "phase2")],
+      [rewrite3]
+    ]);
+    expectAsset("app|foo.phase3", "foo.phase1.phase2.phase3");
+    buildShouldSucceed();
+  });
+
+  test("a removed transformer is un-pipelined", () {
+    var rewrite1 = new RewriteTransformer("source", "phase1");
+    var rewrite3 = new RewriteTransformer("phase2", "phase3");
+    initGraph(["app|foo.source"], {"app": [
+      [rewrite1],
+      [new RewriteTransformer("phase1", "phase2")],
+      [rewrite3]
+    ]});
+
+    updateSources(["app|foo.source"]);
+    expectAsset("app|foo.phase3", "foo.phase1.phase2.phase3");
+    buildShouldSucceed();
+
+    updateTransformers("app", [[rewrite1], [rewrite3]]);
+    expectNoAsset("app|foo.phase3");
+    buildShouldSucceed();
+  });
+
+  test("a transformer is removed during isPrimary", () {
+    var rewrite = new RewriteTransformer("blub", "blab");
+    initGraph(["app|foo.blub"], {"app": [[rewrite]]});
+
+    rewrite.pauseIsPrimary("app|foo.blub");
+    updateSources(["app|foo.blub"]);
+    // Ensure we're waiting on [rewrite.isPrimary].
+    schedule(pumpEventQueue);
+
+    updateTransformers("app", []);
+    rewrite.resumeIsPrimary("app|foo.blub");
+    expectAsset("app|foo.blub", "foo");
+    expectNoAsset("app|foo.blab");
+    buildShouldSucceed();
+  });
+
+  test("a transformer is removed during apply", () {
+    var rewrite = new RewriteTransformer("blub", "blab");
+    initGraph(["app|foo.blub"], {"app": [[rewrite]]});
+
+    rewrite.pauseApply();
+    updateSources(["app|foo.blub"]);
+    // Ensure we're waiting on [rewrite.apply].
+    schedule(pumpEventQueue);
+
+    updateTransformers("app", []);
+    rewrite.resumeApply();
+    expectAsset("app|foo.blub", "foo");
+    expectNoAsset("app|foo.blab");
+    buildShouldSucceed();
+  });
+
+  test("a new transformer can see pass-through assets", () {
+    var rewrite = new RewriteTransformer("zip", "zap");
+    initGraph(["app|foo.blub"], {"app": [[rewrite]]});
+
+    updateSources(["app|foo.blub"]);
+    buildShouldSucceed();
+
+    updateTransformers("app", [
+      [rewrite],
+      [new RewriteTransformer("blub", "blab")]
+    ]);
+    expectAsset("app|foo.blab", "foo.blab");
+    expectNoAsset("app|foo.blub");
+    buildShouldSucceed();
+  });
+
+  test("a cross-package transform sees a new transformer in a new phase", () {
+    // TODO(nweiz): make this work.
+    return;
+
+    var rewrite = new RewriteTransformer("inc", "inc");
+    initGraph({
+      "pkg1|foo.txt": "pkg2|foo.inc",
+      "pkg2|foo.inc": "foo"
+    }, {
+      "pkg1": [[new ManyToOneTransformer("txt")]],
+      "pkg2": [[rewrite]]
+    });
+
+    updateSources(["pkg1|foo.txt", "pkg2|foo.inc"]);
+    expectAsset("pkg1|foo.out", "foo");
+    buildShouldSucceed();
+
+    updateTransformers("pkg2", [
+      [rewrite],
+      [new RewriteTransformer("inc", "inc")]
+    ]);
+    expectAsset("pkg1|foo.out", "foo.inc.inc");
+    buildShouldSucceed();
+  });
+
+  test("a cross-package transform doesn't see a removed transformer in a "
+      "removed phase", () {
+    var rewrite = new RewriteTransformer("inc", "inc");
+    initGraph({
+      "pkg1|foo.txt": "pkg2|foo.inc",
+      "pkg2|foo.inc": "foo"
+    }, {
+      "pkg1": [[new ManyToOneTransformer("txt")]],
+      "pkg2": [
+        [rewrite],
+        [new RewriteTransformer("inc", "inc")]
+      ]
+    });
+
+    updateSources(["pkg1|foo.txt", "pkg2|foo.inc"]);
+    expectAsset("pkg1|foo.out", "foo.inc.inc");
+    buildShouldSucceed();
+
+    updateTransformers("pkg2", [[rewrite]]);
+    expectAsset("pkg1|foo.out", "foo.inc");
+    buildShouldSucceed();
+  });
+}
\ No newline at end of file
diff --git a/pkg/barback/test/package_graph/errors_test.dart b/pkg/barback/test/package_graph/errors_test.dart
index 8e4fd89..8c74991 100644
--- a/pkg/barback/test/package_graph/errors_test.dart
+++ b/pkg/barback/test/package_graph/errors_test.dart
@@ -4,9 +4,6 @@
 
 library barback.test.package_graph.source_test;
 
-import 'dart:async';
-
-import 'package:barback/barback.dart';
 import 'package:barback/src/utils.dart';
 import 'package:scheduled_test/scheduled_test.dart';
 
diff --git a/pkg/barback/test/package_graph/get_all_assets_test.dart b/pkg/barback/test/package_graph/get_all_assets_test.dart
new file mode 100644
index 0000000..0ece84b
--- /dev/null
+++ b/pkg/barback/test/package_graph/get_all_assets_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 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.barback_test;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../utils.dart';
+
+main() {
+  initConfig();
+
+  test("gets all source assets", () {
+    initGraph(["app|a.txt", "app|b.txt", "app|c.txt"]);
+    updateSources(["app|a.txt", "app|b.txt", "app|c.txt"]);
+    expectAllAssets(["app|a.txt", "app|b.txt", "app|c.txt"]);
+    buildShouldSucceed();
+  });
+
+  test("includes transformed outputs, but not consumed ones", () {
+    initGraph(["app|a.txt", "app|foo.blub"], {"app": [
+      [new RewriteTransformer("blub", "blab")]
+    ]});
+    updateSources(["app|a.txt", "app|foo.blub"]);
+    expectAllAssets(["app|a.txt", "app|foo.blab"]);
+    buildShouldSucceed();
+  });
+
+  test("includes non-primary inputs to transformers", () {
+    var transformer = new ManyToOneTransformer("txt");
+    initGraph({
+      "app|a.txt": "a.inc",
+      "app|a.inc": "a"
+    }, {"app": [[transformer]]});
+
+    updateSources(["app|a.txt", "app|a.inc"]);
+    expectAllAssets(["app|a.inc", "app|a.out"]);
+    buildShouldSucceed();
+  });
+
+  test("completes to an error if two transformers output the same file", () {
+    initGraph(["app|foo.a"], {"app": [
+      [
+        new RewriteTransformer("a", "b"),
+        new RewriteTransformer("a", "b")
+      ]
+    ]});
+    updateSources(["app|foo.a"]);
+    expectAllAssetsShouldFail(isAssetCollisionException("app|foo.b"));
+  });
+
+  test("completes to an error if a transformer fails", () {
+    initGraph(["app|foo.txt"], {"app": [
+      [new BadTransformer(["app|foo.out"])]
+    ]});
+
+    updateSources(["app|foo.txt"]);
+    expectAllAssetsShouldFail(isTransformerException(
+        equals(BadTransformer.ERROR)));
+  });
+
+  test("completes to an aggregate error if there are multiple errors", () {
+    initGraph(["app|foo.txt"], {"app": [
+      [
+        new BadTransformer(["app|foo.out"]),
+        new BadTransformer(["app|foo.out2"])
+      ]
+    ]});
+
+    updateSources(["app|foo.txt"]);
+    expectAllAssetsShouldFail(isAggregateException([
+      isTransformerException(equals(BadTransformer.ERROR)),
+      isTransformerException(equals(BadTransformer.ERROR))
+    ]));
+  });
+}
diff --git a/pkg/barback/test/package_graph/source_test.dart b/pkg/barback/test/package_graph/source_test.dart
index 4c47df3..b5763a8 100644
--- a/pkg/barback/test/package_graph/source_test.dart
+++ b/pkg/barback/test/package_graph/source_test.dart
@@ -4,10 +4,6 @@
 
 library barback.test.package_graph.source_test;
 
-import 'dart:async';
-
-import 'package:barback/barback.dart';
-import 'package:barback/src/utils.dart';
 import 'package:scheduled_test/scheduled_test.dart';
 
 import '../utils.dart';
diff --git a/pkg/barback/test/package_graph/transform_test.dart b/pkg/barback/test/package_graph/transform_test.dart
index 4d7b97e..8c108b3 100644
--- a/pkg/barback/test/package_graph/transform_test.dart
+++ b/pkg/barback/test/package_graph/transform_test.dart
@@ -4,9 +4,6 @@
 
 library barback.test.package_graph.transform_test;
 
-import 'dart:async';
-
-import 'package:barback/barback.dart';
 import 'package:barback/src/utils.dart';
 import 'package:scheduled_test/scheduled_test.dart';
 
@@ -1058,5 +1055,45 @@
       expectNoAsset("pkg1|c.done");
       buildShouldSucceed();
     });
+
+    test("sees a transformer that's newly applied to a cross-package "
+        "dependency", () {
+      initGraph({
+        "pkg1|a.txt": "pkg2|a.inc",
+        "pkg2|a.inc": "a"
+      }, {
+        "pkg1": [[new ManyToOneTransformer("txt")]],
+        "pkg2": [[new CheckContentTransformer("b", " transformed")]]
+      });
+
+      updateSources(["pkg1|a.txt", "pkg2|a.inc"]);
+      expectAsset("pkg1|a.out", "a");
+      buildShouldSucceed();
+
+      modifyAsset("pkg2|a.inc", "b");
+      updateSources(["pkg2|a.inc"]);
+      expectAsset("pkg1|a.out", "b transformed");
+      buildShouldSucceed();
+    });
+
+    test("doesn't see a transformer that's newly not applied to a "
+        "cross-package dependency", () {
+      initGraph({
+        "pkg1|a.txt": "pkg2|a.inc",
+        "pkg2|a.inc": "a"
+      }, {
+        "pkg1": [[new ManyToOneTransformer("txt")]],
+        "pkg2": [[new CheckContentTransformer("a", " transformed")]]
+      });
+
+      updateSources(["pkg1|a.txt", "pkg2|a.inc"]);
+      expectAsset("pkg1|a.out", "a transformed");
+      buildShouldSucceed();
+
+      modifyAsset("pkg2|a.inc", "b");
+      updateSources(["pkg2|a.inc"]);
+      expectAsset("pkg1|a.out", "b");
+      buildShouldSucceed();
+    });
   });
 }
diff --git a/pkg/barback/test/transformer/many_to_one.dart b/pkg/barback/test/transformer/many_to_one.dart
index 45f8f25..59a190c 100644
--- a/pkg/barback/test/transformer/many_to_one.dart
+++ b/pkg/barback/test/transformer/many_to_one.dart
@@ -7,7 +7,6 @@
 import 'dart:async';
 
 import 'package:barback/barback.dart';
-import 'package:barback/src/utils.dart';
 
 import 'mock.dart';
 
diff --git a/pkg/barback/test/transformer_test.dart b/pkg/barback/test/transformer_test.dart
new file mode 100644
index 0000000..9df3f4a
--- /dev/null
+++ b/pkg/barback/test/transformer_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.
+
+library barback.test.transformer_test;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+main() {
+  initConfig();
+
+  group("isPrimary", () {
+    test("defaults to allowedExtensions", () {
+      var transformer = new ExtensionTransformer(".txt .bin");
+      expect(transformer.isPrimary(makeAsset("foo.txt")),
+          completion(isTrue));
+
+      expect(transformer.isPrimary(makeAsset("foo.bin")),
+          completion(isTrue));
+
+      expect(transformer.isPrimary(makeAsset("foo.nottxt")),
+          completion(isFalse));
+    });
+
+    test("allows all files if allowedExtensions is not overridden", () {
+      var transformer = new MockTransformer();
+      expect(transformer.isPrimary(makeAsset("foo.txt")),
+          completion(isTrue));
+
+      expect(transformer.isPrimary(makeAsset("foo.bin")),
+          completion(isTrue));
+
+      expect(transformer.isPrimary(makeAsset("anything")),
+          completion(isTrue));
+    });
+  });
+}
+
+Asset makeAsset(String path) =>
+    new Asset.fromString(new AssetId.parse("app|$path"), "");
+
+class MockTransformer extends Transformer {
+  MockTransformer();
+
+  Future apply(Transform transform) => new Future.value();
+}
+
+class ExtensionTransformer extends Transformer {
+  final String allowedExtensions;
+
+  ExtensionTransformer(this.allowedExtensions);
+
+  Future apply(Transform transform) => new Future.value();
+}
\ No newline at end of file
diff --git a/pkg/barback/test/utils.dart b/pkg/barback/test/utils.dart
index 99a7ec1..73f4f8b 100644
--- a/pkg/barback/test/utils.dart
+++ b/pkg/barback/test/utils.dart
@@ -9,7 +9,6 @@
 import 'dart:io';
 
 import 'package:barback/barback.dart';
-import 'package:barback/src/asset_set.dart';
 import 'package:barback/src/cancelable_future.dart';
 import 'package:barback/src/utils.dart';
 import 'package:path/path.dart' as pathos;
@@ -61,9 +60,38 @@
   if (assets == null) assets = [];
   if (transformers == null) transformers = {};
 
-  _provider = new MockProvider(assets, transformers);
+  var assetList;
+  if (assets is Map) {
+    assetList = assets.keys.map((asset) {
+      var id = new AssetId.parse(asset);
+      return new _MockAsset(id, assets[asset]);
+    });
+  } else if (assets is Iterable) {
+    assetList = assets.map((asset) {
+      var id = new AssetId.parse(asset);
+      var contents = pathos.basenameWithoutExtension(id.path);
+      return new _MockAsset(id, contents);
+    });
+  }
+
+  var assetMap = mapMapValues(groupBy(assetList, (asset) => asset.id.package),
+      (package, assets) => new AssetSet.from(assets));
+
+  // Make sure that packages that have transformers but no assets are considered
+  // by MockProvider to exist.
+  for (var package in transformers.keys) {
+    assetMap.putIfAbsent(package, () => new AssetSet());
+  }
+
+  _provider = new MockProvider(assetMap);
   _barback = new Barback(_provider);
   _nextBuildResult = 0;
+
+  transformers.forEach(_barback.updateTransformers);
+
+  // There should be one successful build after adding all the transformers but
+  // before adding any sources.
+  if (!transformers.isEmpty) buildShouldSucceed();
 }
 
 /// Updates [assets] in the current [PackageProvider].
@@ -102,6 +130,13 @@
 void removeSourcesSync(Iterable assets) =>
     _barback.removeSources(_parseAssets(assets));
 
+/// Sets the transformers for [package] to [transformers].
+void updateTransformers(String package,
+    Iterable<Iterable<Transformer>> transformers) {
+  schedule(() => _barback.updateTransformers(package, transformers),
+      "updating transformers for $package");
+}
+
 /// Parse a list of strings or [AssetId]s into a list of [AssetId]s.
 List<AssetId> _parseAssets(Iterable assets) {
   return assets.map((asset) {
@@ -223,6 +258,39 @@
   }, "get asset $name");
 }
 
+/// Schedules an expectation that the graph will output all of the given
+/// assets, and no others.
+///
+/// [assets] is a list of strings that can be parsed to [AssetID]s.
+void expectAllAssets(Iterable<String> assets) {
+  var expected = assets.map((asset) => new AssetId.parse(asset));
+
+  schedule(() {
+    return _barback.getAllAssets().then((actualAssets) {
+      var actualIds = actualAssets.map((asset) => asset.id).toSet();
+
+      for (var id in expected) {
+        expect(actualIds, contains(id));
+        actualIds.remove(id);
+      }
+
+      expect(actualIds, isEmpty);
+    });
+  }, "get all assets, expecting ${expected.join(', ')}");
+}
+
+/// Schedules an expectation that [Barback.getAllAssets] will return a [Future]
+/// that completes to a error that matches [matcher].
+///
+/// If [match] is a [List], then it expects the completed error to be an
+/// [AggregateException] whose errors match each matcher in the list. Otherwise,
+/// [match] should be a single matcher that the error should match.
+void expectAllAssetsShouldFail(Matcher matcher) {
+  schedule(() {
+    expect(_barback.getAllAssets(), throwsA(matcher));
+  }, "get all assets should fail");
+}
+
 /// Schedules an expectation that a [getAssetById] call for the given asset
 /// won't terminate at this point in the schedule.
 void expectAssetDoesNotComplete(String name) {
@@ -236,6 +304,25 @@
   }, "asset $id should not complete");
 }
 
+/// Returns a matcher for an [AggregateException] containing errors that match
+/// [matchers].
+Matcher isAggregateException(Iterable<Matcher> errors) {
+  // Match the aggregate error itself.
+  var matchers = [
+    new isInstanceOf<AggregateException>(),
+    transform((error) => error.errors, hasLength(errors.length),
+        'errors.length == ${errors.length}')
+  ];
+
+  // Make sure its contained errors match the matchers.
+  for (var error in errors) {
+    matchers.add(transform((error) => error.errors, contains(error),
+        error.toString()));
+  }
+
+  return allOf(matchers);
+}
+
 /// Returns a matcher for an [AssetNotFoundException] with the given [id].
 Matcher isAssetNotFoundException(String name) {
   var id = new AssetId.parse(name);
@@ -340,9 +427,9 @@
 
 /// An [AssetProvider] that provides the given set of assets.
 class MockProvider implements PackageProvider {
-  Iterable<String> get packages => _packages.keys;
+  Iterable<String> get packages => _assets.keys;
 
-  Map<String, _MockPackage> _packages;
+  Map<String, AssetSet> _assets;
 
   /// The set of assets for which [MockLoadException]s should be emitted if
   /// they're loaded.
@@ -366,42 +453,19 @@
     _pauseCompleter = null;
   }
 
-  MockProvider(assets,
-      Map<String, Iterable<Iterable<Transformer>>> transformers) {
-    var assetList;
-    if (assets is Map) {
-      assetList = assets.keys.map((asset) {
-        var id = new AssetId.parse(asset);
-        return new _MockAsset(id, assets[asset]);
-      });
-    } else if (assets is Iterable) {
-      assetList = assets.map((asset) {
-        var id = new AssetId.parse(asset);
-        var contents = pathos.basenameWithoutExtension(id.path);
-        return new _MockAsset(id, contents);
-      });
-    }
-
-    _packages = mapMapValues(groupBy(assetList, (asset) => asset.id.package),
-        (package, assets) {
-      var packageTransformers = transformers[package];
-      if (packageTransformers == null) packageTransformers = [];
-      return new _MockPackage(
-          new AssetSet.from(assets), packageTransformers.toList());
-    });
-
+  MockProvider(this._assets) {
     // If there are no assets or transformers, add a dummy package. This better
     // simulates the real world, where there'll always be at least the
     // entrypoint package.
-    if (_packages.isEmpty) {
-      _packages = {"app": new _MockPackage(new AssetSet(), [])};
+    if (_assets.isEmpty) {
+      _assets = {"app": new AssetSet()};
     }
   }
 
   void _modifyAsset(String name, String contents) {
     var id = new AssetId.parse(name);
     _errors.remove(id);
-    _packages[id.package].assets[id].contents = contents;
+    _assets[id.package][id].contents = contents;
   }
 
   void _setAssetError(String name) => _errors.add(new AssetId.parse(name));
@@ -411,23 +475,15 @@
       throw new UnimplementedError("Doesn't handle 'within' yet.");
     }
 
-    return _packages[package].assets.map((asset) => asset.id);
-  }
-
-  Iterable<Iterable<Transformer>> getTransformers(String package) {
-    var mockPackage = _packages[package];
-    if (mockPackage == null) {
-      throw new ArgumentError("No package named $package.");
-    }
-    return mockPackage.transformers;
+    return _assets[package].map((asset) => asset.id);
   }
 
   Future<Asset> getAsset(AssetId id) {
     // Eagerly load the asset so we can test an asset's value changing between
     // when a load starts and when it finishes.
-    var package = _packages[id.package];
+    var assets = _assets[id.package];
     var asset;
-    if (package != null) asset = package.assets[id];
+    if (assets != null) asset = assets[id];
 
     var hasError = _errors.contains(id);
 
@@ -455,16 +511,6 @@
   String toString() => "Error loading $id.";
 }
 
-/// Used by [MockProvider] to keep track of which assets and transformers exist
-/// for each package.
-class _MockPackage {
-  final AssetSet assets;
-  final List<List<Transformer>> transformers;
-
-  _MockPackage(this.assets, Iterable<Iterable<Transformer>> transformers)
-      : transformers = transformers.map((phase) => phase.toList()).toList();
-}
-
 /// An implementation of [Asset] that never hits the file system.
 class _MockAsset implements Asset {
   final AssetId id;
diff --git a/pkg/crypto/lib/crypto.dart b/pkg/crypto/lib/crypto.dart
index f5f737b..ee11c25 100644
--- a/pkg/crypto/lib/crypto.dart
+++ b/pkg/crypto/lib/crypto.dart
@@ -2,6 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+/**
+ * Cryptographic algorithms, with support for hash functions such as
+ * SHA-1, SHA-256, HMAC, and MD5.
+ */
 library crypto;
 
 import 'dart:math';
diff --git a/pkg/custom_element/lib/custom-elements.debug.js b/pkg/custom_element/lib/custom-elements.debug.js
new file mode 100644
index 0000000..400730b
--- /dev/null
+++ b/pkg/custom_element/lib/custom-elements.debug.js
@@ -0,0 +1,1458 @@
+// Copyright (c) 2012 The Polymer Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+(function() {
+
+var scope = window.PolymerLoader = {};
+var flags = {};
+
+// convert url arguments to flags
+
+if (!flags.noOpts) {
+  location.search.slice(1).split('&').forEach(function(o) {
+    o = o.split('=');
+    o[0] && (flags[o[0]] = o[1] || true);
+  });
+}
+
+// process global logFlags
+
+parseLogFlags(flags);
+
+function load(scopeName) {
+  // imports
+
+  var scope = window[scopeName];
+  var entryPointName = scope.entryPointName;
+  var processFlags = scope.processFlags;
+
+  // acquire attributes and base path from entry point
+
+  var entryPoint = findScript(entryPointName);
+  var base = entryPoint.basePath;
+
+  // acquire common flags
+  var flags = scope.flags;
+
+  // convert attributes to flags
+  var flags = PolymerLoader.flags;
+  for (var i=0, a; (a=entryPoint.attributes[i]); i++) {
+    if (a.name !== 'src') {
+      flags[a.name] = a.value || true;
+    }
+  }
+
+  // parse log flags into global
+  parseLogFlags(flags);
+
+  // exports
+
+  scope.basePath = base;
+  scope.flags = flags;
+
+  // process flags for dynamic dependencies
+
+  if (processFlags) {
+    processFlags.call(scope, flags);
+  }
+
+  // post-process imports
+
+  var modules = scope.modules || [];
+  var sheets = scope.sheets || [];
+
+  // write script tags for dependencies
+
+  modules.forEach(function(src) {
+    document.write('<script src="' + base + src + '"></script>');
+  });
+
+  // write link tags for styles
+
+  sheets.forEach(function(src) {
+    document.write('<link rel="stylesheet" href="' + base + src + '">');
+  });
+}
+
+// utility method
+
+function findScript(fileName) {
+  var script = document.querySelector('script[src*="' + fileName + '"]');
+  var src = script.attributes.src.value;
+  script.basePath = src.slice(0, src.indexOf(fileName));
+  return script;
+}
+
+function parseLogFlags(flags) {
+  var logFlags = window.logFlags = window.logFlags || {};
+  if (flags.log) {
+    flags.log.split(',').forEach(function(f) {
+      logFlags[f] = true;
+    });
+  }
+}
+
+scope.flags = flags;
+scope.load = load;
+
+})();
+
+window.CustomElements = {flags:{}};
+// SideTable is a weak map where possible. If WeakMap is not available the
+// association is stored as an expando property.
+var SideTable;
+// TODO(arv): WeakMap does not allow for Node etc to be keys in Firefox
+if (typeof WeakMap !== 'undefined' && navigator.userAgent.indexOf('Firefox/') < 0) {
+  SideTable = WeakMap;
+} else {
+  (function() {
+    var defineProperty = Object.defineProperty;
+    var hasOwnProperty = Object.hasOwnProperty;
+    var counter = new Date().getTime() % 1e9;
+
+    SideTable = function() {
+      this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__');
+    };
+
+    SideTable.prototype = {
+      set: function(key, value) {
+        defineProperty(key, this.name, {value: value, writable: true});
+      },
+      get: function(key) {
+        return hasOwnProperty.call(key, this.name) ? key[this.name] : undefined;
+      },
+      delete: function(key) {
+        this.set(key, undefined);
+      }
+    }
+  })();
+}
+
+(function(global) {
+
+  var registrationsTable = new SideTable();
+
+  // We use setImmediate or postMessage for our future callback.
+  var setImmediate = window.msSetImmediate;
+
+  // Use post message to emulate setImmediate.
+  if (!setImmediate) {
+    var setImmediateQueue = [];
+    var sentinel = String(Math.random());
+    window.addEventListener('message', function(e) {
+      if (e.data === sentinel) {
+        var queue = setImmediateQueue;
+        setImmediateQueue = [];
+        queue.forEach(function(func) {
+          func();
+        });
+      }
+    });
+    setImmediate = function(func) {
+      setImmediateQueue.push(func);
+      window.postMessage(sentinel, '*');
+    };
+  }
+
+  // This is used to ensure that we never schedule 2 callas to setImmediate
+  var isScheduled = false;
+
+  // Keep track of observers that needs to be notified next time.
+  var scheduledObservers = [];
+
+  /**
+   * Schedules |dispatchCallback| to be called in the future.
+   * @param {MutationObserver} observer
+   */
+  function scheduleCallback(observer) {
+    scheduledObservers.push(observer);
+    if (!isScheduled) {
+      isScheduled = true;
+      setImmediate(dispatchCallbacks);
+    }
+  }
+
+  function wrapIfNeeded(node) {
+    return window.ShadowDOMPolyfill &&
+        window.ShadowDOMPolyfill.wrapIfNeeded(node) ||
+        node;
+  }
+
+  function dispatchCallbacks() {
+    // http://dom.spec.whatwg.org/#mutation-observers
+
+    isScheduled = false; // Used to allow a new setImmediate call above.
+
+    var observers = scheduledObservers;
+    scheduledObservers = [];
+    // Sort observers based on their creation UID (incremental).
+    observers.sort(function(o1, o2) {
+      return o1.uid_ - o2.uid_;
+    });
+
+    var anyNonEmpty = false;
+    observers.forEach(function(observer) {
+
+      // 2.1, 2.2
+      var queue = observer.takeRecords();
+      // 2.3. Remove all transient registered observers whose observer is mo.
+      removeTransientObserversFor(observer);
+
+      // 2.4
+      if (queue.length) {
+        observer.callback_(queue, observer);
+        anyNonEmpty = true;
+      }
+    });
+
+    // 3.
+    if (anyNonEmpty)
+      dispatchCallbacks();
+  }
+
+  function removeTransientObserversFor(observer) {
+    observer.nodes_.forEach(function(node) {
+      var registrations = registrationsTable.get(node);
+      if (!registrations)
+        return;
+      registrations.forEach(function(registration) {
+        if (registration.observer === observer)
+          registration.removeTransientObservers();
+      });
+    });
+  }
+
+  /**
+   * This function is used for the "For each registered observer observer (with
+   * observer's options as options) in target's list of registered observers,
+   * run these substeps:" and the "For each ancestor ancestor of target, and for
+   * each registered observer observer (with options options) in ancestor's list
+   * of registered observers, run these substeps:" part of the algorithms. The
+   * |options.subtree| is checked to ensure that the callback is called
+   * correctly.
+   *
+   * @param {Node} target
+   * @param {function(MutationObserverInit):MutationRecord} callback
+   */
+  function forEachAncestorAndObserverEnqueueRecord(target, callback) {
+    for (var node = target; node; node = node.parentNode) {
+      var registrations = registrationsTable.get(node);
+
+      if (registrations) {
+        for (var j = 0; j < registrations.length; j++) {
+          var registration = registrations[j];
+          var options = registration.options;
+
+          // Only target ignores subtree.
+          if (node !== target && !options.subtree)
+            continue;
+
+          var record = callback(options);
+          if (record)
+            registration.enqueue(record);
+        }
+      }
+    }
+  }
+
+  var uidCounter = 0;
+
+  /**
+   * The class that maps to the DOM MutationObserver interface.
+   * @param {Function} callback.
+   * @constructor
+   */
+  function JsMutationObserver(callback) {
+    this.callback_ = callback;
+    this.nodes_ = [];
+    this.records_ = [];
+    this.uid_ = ++uidCounter;
+  }
+
+  JsMutationObserver.prototype = {
+    observe: function(target, options) {
+      target = wrapIfNeeded(target);
+
+      // 1.1
+      if (!options.childList && !options.attributes && !options.characterData ||
+
+          // 1.2
+          options.attributeOldValue && !options.attributes ||
+
+          // 1.3
+          options.attributeFilter && options.attributeFilter.length &&
+              !options.attributes ||
+
+          // 1.4
+          options.characterDataOldValue && !options.characterData) {
+
+        throw new SyntaxError();
+      }
+
+      var registrations = registrationsTable.get(target);
+      if (!registrations)
+        registrationsTable.set(target, registrations = []);
+
+      // 2
+      // If target's list of registered observers already includes a registered
+      // observer associated with the context object, replace that registered
+      // observer's options with options.
+      var registration;
+      for (var i = 0; i < registrations.length; i++) {
+        if (registrations[i].observer === this) {
+          registration = registrations[i];
+          registration.removeListeners();
+          registration.options = options;
+          break;
+        }
+      }
+
+      // 3.
+      // Otherwise, add a new registered observer to target's list of registered
+      // observers with the context object as the observer and options as the
+      // options, and add target to context object's list of nodes on which it
+      // is registered.
+      if (!registration) {
+        registration = new Registration(this, target, options);
+        registrations.push(registration);
+        this.nodes_.push(target);
+      }
+
+      registration.addListeners();
+    },
+
+    disconnect: function() {
+      this.nodes_.forEach(function(node) {
+        var registrations = registrationsTable.get(node);
+        for (var i = 0; i < registrations.length; i++) {
+          var registration = registrations[i];
+          if (registration.observer === this) {
+            registration.removeListeners();
+            registrations.splice(i, 1);
+            // Each node can only have one registered observer associated with
+            // this observer.
+            break;
+          }
+        }
+      }, this);
+      this.records_ = [];
+    },
+
+    takeRecords: function() {
+      var copyOfRecords = this.records_;
+      this.records_ = [];
+      return copyOfRecords;
+    }
+  };
+
+  /**
+   * @param {string} type
+   * @param {Node} target
+   * @constructor
+   */
+  function MutationRecord(type, target) {
+    this.type = type;
+    this.target = target;
+    this.addedNodes = [];
+    this.removedNodes = [];
+    this.previousSibling = null;
+    this.nextSibling = null;
+    this.attributeName = null;
+    this.attributeNamespace = null;
+    this.oldValue = null;
+  }
+
+  function copyMutationRecord(original) {
+    var record = new MutationRecord(original.type, original.target);
+    record.addedNodes = original.addedNodes.slice();
+    record.removedNodes = original.removedNodes.slice();
+    record.previousSibling = original.previousSibling;
+    record.nextSibling = original.nextSibling;
+    record.attributeName = original.attributeName;
+    record.attributeNamespace = original.attributeNamespace;
+    record.oldValue = original.oldValue;
+    return record;
+  };
+
+  // We keep track of the two (possibly one) records used in a single mutation.
+  var currentRecord, recordWithOldValue;
+
+  /**
+   * Creates a record without |oldValue| and caches it as |currentRecord| for
+   * later use.
+   * @param {string} oldValue
+   * @return {MutationRecord}
+   */
+  function getRecord(type, target) {
+    return currentRecord = new MutationRecord(type, target);
+  }
+
+  /**
+   * Gets or creates a record with |oldValue| based in the |currentRecord|
+   * @param {string} oldValue
+   * @return {MutationRecord}
+   */
+  function getRecordWithOldValue(oldValue) {
+    if (recordWithOldValue)
+      return recordWithOldValue;
+    recordWithOldValue = copyMutationRecord(currentRecord);
+    recordWithOldValue.oldValue = oldValue;
+    return recordWithOldValue;
+  }
+
+  function clearRecords() {
+    currentRecord = recordWithOldValue = undefined;
+  }
+
+  /**
+   * @param {MutationRecord} record
+   * @return {boolean} Whether the record represents a record from the current
+   * mutation event.
+   */
+  function recordRepresentsCurrentMutation(record) {
+    return record === recordWithOldValue || record === currentRecord;
+  }
+
+  /**
+   * Selects which record, if any, to replace the last record in the queue.
+   * This returns |null| if no record should be replaced.
+   *
+   * @param {MutationRecord} lastRecord
+   * @param {MutationRecord} newRecord
+   * @param {MutationRecord}
+   */
+  function selectRecord(lastRecord, newRecord) {
+    if (lastRecord === newRecord)
+      return lastRecord;
+
+    // Check if the the record we are adding represents the same record. If
+    // so, we keep the one with the oldValue in it.
+    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord))
+      return recordWithOldValue;
+
+    return null;
+  }
+
+  /**
+   * Class used to represent a registered observer.
+   * @param {MutationObserver} observer
+   * @param {Node} target
+   * @param {MutationObserverInit} options
+   * @constructor
+   */
+  function Registration(observer, target, options) {
+    this.observer = observer;
+    this.target = target;
+    this.options = options;
+    this.transientObservedNodes = [];
+  }
+
+  Registration.prototype = {
+    enqueue: function(record) {
+      var records = this.observer.records_;
+      var length = records.length;
+
+      // There are cases where we replace the last record with the new record.
+      // For example if the record represents the same mutation we need to use
+      // the one with the oldValue. If we get same record (this can happen as we
+      // walk up the tree) we ignore the new record.
+      if (records.length > 0) {
+        var lastRecord = records[length - 1];
+        var recordToReplaceLast = selectRecord(lastRecord, record);
+        if (recordToReplaceLast) {
+          records[length - 1] = recordToReplaceLast;
+          return;
+        }
+      } else {
+        scheduleCallback(this.observer);
+      }
+
+      records[length] = record;
+    },
+
+    addListeners: function() {
+      this.addListeners_(this.target);
+    },
+
+    addListeners_: function(node) {
+      var options = this.options;
+      if (options.attributes)
+        node.addEventListener('DOMAttrModified', this, true);
+
+      if (options.characterData)
+        node.addEventListener('DOMCharacterDataModified', this, true);
+
+      if (options.childList)
+        node.addEventListener('DOMNodeInserted', this, true);
+
+      if (options.childList || options.subtree)
+        node.addEventListener('DOMNodeRemoved', this, true);
+    },
+
+    removeListeners: function() {
+      this.removeListeners_(this.target);
+    },
+
+    removeListeners_: function(node) {
+      var options = this.options;
+      if (options.attributes)
+        node.removeEventListener('DOMAttrModified', this, true);
+
+      if (options.characterData)
+        node.removeEventListener('DOMCharacterDataModified', this, true);
+
+      if (options.childList)
+        node.removeEventListener('DOMNodeInserted', this, true);
+
+      if (options.childList || options.subtree)
+        node.removeEventListener('DOMNodeRemoved', this, true);
+    },
+
+    /**
+     * Adds a transient observer on node. The transient observer gets removed
+     * next time we deliver the change records.
+     * @param {Node} node
+     */
+    addTransientObserver: function(node) {
+      // Don't add transient observers on the target itself. We already have all
+      // the required listeners set up on the target.
+      if (node === this.target)
+        return;
+
+      this.addListeners_(node);
+      this.transientObservedNodes.push(node);
+      var registrations = registrationsTable.get(node);
+      if (!registrations)
+        registrationsTable.set(node, registrations = []);
+
+      // We know that registrations does not contain this because we already
+      // checked if node === this.target.
+      registrations.push(this);
+    },
+
+    removeTransientObservers: function() {
+      var transientObservedNodes = this.transientObservedNodes;
+      this.transientObservedNodes = [];
+
+      transientObservedNodes.forEach(function(node) {
+        // Transient observers are never added to the target.
+        this.removeListeners_(node);
+
+        var registrations = registrationsTable.get(node);
+        for (var i = 0; i < registrations.length; i++) {
+          if (registrations[i] === this) {
+            registrations.splice(i, 1);
+            // Each node can only have one registered observer associated with
+            // this observer.
+            break;
+          }
+        }
+      }, this);
+    },
+
+    handleEvent: function(e) {
+      // Stop propagation since we are managing the propagation manually.
+      // This means that other mutation events on the page will not work
+      // correctly but that is by design.
+      e.stopImmediatePropagation();
+
+      switch (e.type) {
+        case 'DOMAttrModified':
+          // http://dom.spec.whatwg.org/#concept-mo-queue-attributes
+
+          var name = e.attrName;
+          var namespace = e.relatedNode.namespaceURI;
+          var target = e.target;
+
+          // 1.
+          var record = new getRecord('attributes', target);
+          record.attributeName = name;
+          record.attributeNamespace = namespace;
+
+          // 2.
+          var oldValue =
+              e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
+
+          forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+            // 3.1, 4.2
+            if (!options.attributes)
+              return;
+
+            // 3.2, 4.3
+            if (options.attributeFilter && options.attributeFilter.length &&
+                options.attributeFilter.indexOf(name) === -1 &&
+                options.attributeFilter.indexOf(namespace) === -1) {
+              return;
+            }
+            // 3.3, 4.4
+            if (options.attributeOldValue)
+              return getRecordWithOldValue(oldValue);
+
+            // 3.4, 4.5
+            return record;
+          });
+
+          break;
+
+        case 'DOMCharacterDataModified':
+          // http://dom.spec.whatwg.org/#concept-mo-queue-characterdata
+          var target = e.target;
+
+          // 1.
+          var record = getRecord('characterData', target);
+
+          // 2.
+          var oldValue = e.prevValue;
+
+
+          forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+            // 3.1, 4.2
+            if (!options.characterData)
+              return;
+
+            // 3.2, 4.3
+            if (options.characterDataOldValue)
+              return getRecordWithOldValue(oldValue);
+
+            // 3.3, 4.4
+            return record;
+          });
+
+          break;
+
+        case 'DOMNodeRemoved':
+          this.addTransientObserver(e.target);
+          // Fall through.
+        case 'DOMNodeInserted':
+          // http://dom.spec.whatwg.org/#concept-mo-queue-childlist
+          var target = e.relatedNode;
+          var changedNode = e.target;
+          var addedNodes, removedNodes;
+          if (e.type === 'DOMNodeInserted') {
+            addedNodes = [changedNode];
+            removedNodes = [];
+          } else {
+
+            addedNodes = [];
+            removedNodes = [changedNode];
+          }
+          var previousSibling = changedNode.previousSibling;
+          var nextSibling = changedNode.nextSibling;
+
+          // 1.
+          var record = getRecord('childList', target);
+          record.addedNodes = addedNodes;
+          record.removedNodes = removedNodes;
+          record.previousSibling = previousSibling;
+          record.nextSibling = nextSibling;
+
+          forEachAncestorAndObserverEnqueueRecord(target, function(options) {
+            // 2.1, 3.2
+            if (!options.childList)
+              return;
+
+            // 2.2, 3.3
+            return record;
+          });
+
+      }
+
+      clearRecords();
+    }
+  };
+
+  global.JsMutationObserver = JsMutationObserver;
+
+})(this);
+
+if (!window.MutationObserver) {
+  window.MutationObserver =
+      window.WebKitMutationObserver ||
+      window.JsMutationObserver;
+  if (!MutationObserver) {
+    throw new Error("no mutation observer support");
+  }
+}
+
+(function(scope){
+
+/*
+if (HTMLElement.prototype.webkitShadowRoot) {
+  Object.defineProperty(HTMLElement.prototype, 'shadowRoot', {
+    get: function() {
+      return this.webkitShadowRoot;
+    }
+  };
+}
+*/
+
+// walk the subtree rooted at node, applying 'find(element, data)' function
+// to each element
+// if 'find' returns true for 'element', do not search element's subtree
+function findAll(node, find, data) {
+  var e = node.firstElementChild;
+  if (!e) {
+    e = node.firstChild;
+    while (e && e.nodeType !== Node.ELEMENT_NODE) {
+      e = e.nextSibling;
+    }
+  }
+  while (e) {
+    if (find(e, data) !== true) {
+      findAll(e, find, data);
+    }
+    e = e.nextElementSibling;
+  }
+  return null;
+}
+
+// walk all shadowRoots on a given node.
+function forRoots(node, cb) {
+  var root = node.webkitShadowRoot;
+  while(root) {
+    forSubtree(root, cb);
+    root = root.olderShadowRoot;
+  }
+}
+
+// walk the subtree rooted at node, including descent into shadow-roots,
+// applying 'cb' to each element
+function forSubtree(node, cb) {
+  //logFlags.dom && node.childNodes && node.childNodes.length && console.group('subTree: ', node);
+  findAll(node, function(e) {
+    if (cb(e)) {
+      return true;
+    }
+    forRoots(e, cb);
+  });
+  forRoots(node, cb);
+  //logFlags.dom && node.childNodes && node.childNodes.length && console.groupEnd();
+}
+
+// manage lifecycle on added node
+function added(node) {
+  if (upgrade(node)) {
+    insertedNode(node);
+    return true;
+  }
+  inserted(node);
+}
+
+// manage lifecycle on added node's subtree only
+function addedSubtree(node) {
+  forSubtree(node, function(e) {
+    if (added(e)) {
+      return true;
+    }
+  });
+}
+
+// manage lifecycle on added node and it's subtree
+function addedNode(node) {
+  return added(node) || addedSubtree(node);
+}
+
+// upgrade custom elements at node, if applicable
+function upgrade(node) {
+  if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
+    var type = node.getAttribute('is') || node.localName;
+    var definition = scope.registry[type];
+    if (definition) {
+      logFlags.dom && console.group('upgrade:', node.localName);
+      scope.upgrade(node);
+      logFlags.dom && console.groupEnd();
+      return true;
+    }
+  }
+}
+
+function insertedNode(node) {
+  inserted(node);
+  if (inDocument(node)) {
+    forSubtree(node, function(e) {
+      inserted(e);
+    });
+  }
+}
+
+// TODO(sjmiles): if there are descents into trees that can never have inDocument(*) true, fix this
+
+function inserted(element) {
+  // TODO(sjmiles): it's possible we were inserted and removed in the space
+  // of one microtask, in which case we won't be 'inDocument' here
+  // But there are other cases where we are testing for inserted without
+  // specific knowledge of mutations, and must test 'inDocument' to determine
+  // whether to call inserted
+  // If we can factor these cases into separate code paths we can have
+  // better diagnostics.
+  // TODO(sjmiles): when logging, do work on all custom elements so we can
+  // track behavior even when callbacks not defined
+  //console.log('inserted: ', element.localName);
+  if (element.enteredDocumentCallback || (element.__upgraded__ && logFlags.dom)) {
+    logFlags.dom && console.group('inserted:', element.localName);
+    if (inDocument(element)) {
+      element.__inserted = (element.__inserted || 0) + 1;
+      // if we are in a 'removed' state, bluntly adjust to an 'inserted' state
+      if (element.__inserted < 1) {
+        element.__inserted = 1;
+      }
+      // if we are 'over inserted', squelch the callback
+      if (element.__inserted > 1) {
+        logFlags.dom && console.warn('inserted:', element.localName,
+          'insert/remove count:', element.__inserted)
+      } else if (element.enteredDocumentCallback) {
+        logFlags.dom && console.log('inserted:', element.localName);
+        element.enteredDocumentCallback();
+      }
+    }
+    logFlags.dom && console.groupEnd();
+  }
+}
+
+function removedNode(node) {
+  removed(node);
+  forSubtree(node, function(e) {
+    removed(e);
+  });
+}
+
+function removed(element) {
+  // TODO(sjmiles): temporary: do work on all custom elements so we can track
+  // behavior even when callbacks not defined
+  if (element.leftDocumentCallback || (element.__upgraded__ && logFlags.dom)) {
+    logFlags.dom && console.log('removed:', element.localName);
+    if (!inDocument(element)) {
+      element.__inserted = (element.__inserted || 0) - 1;
+      // if we are in a 'inserted' state, bluntly adjust to an 'removed' state
+      if (element.__inserted > 0) {
+        element.__inserted = 0;
+      }
+      // if we are 'over removed', squelch the callback
+      if (element.__inserted < 0) {
+        logFlags.dom && console.warn('removed:', element.localName,
+            'insert/remove count:', element.__inserted)
+      } else if (element.leftDocumentCallback) {
+        element.leftDocumentCallback();
+      }
+    }
+  }
+}
+
+function inDocument(element) {
+  var p = element;
+  while (p) {
+    if (p == element.ownerDocument) {
+      return true;
+    }
+    p = p.parentNode || p.host;
+  }
+}
+
+function watchShadow(node) {
+  if (node.webkitShadowRoot && !node.webkitShadowRoot.__watched) {
+    logFlags.dom && console.log('watching shadow-root for: ', node.localName);
+    // watch all unwatched roots...
+    var root = node.webkitShadowRoot;
+    while (root) {
+      watchRoot(root);
+      root = root.olderShadowRoot;
+    }
+  }
+}
+
+function watchRoot(root) {
+  if (!root.__watched) {
+    observe(root);
+    root.__watched = true;
+  }
+}
+
+function watchAllShadows(node) {
+  watchShadow(node);
+  forSubtree(node, function(e) {
+    watchShadow(node);
+  });
+}
+
+function filter(inNode) {
+  switch (inNode.localName) {
+    case 'style':
+    case 'script':
+    case 'template':
+    case undefined:
+      return true;
+  }
+}
+
+function handler(mutations) {
+  //
+  if (logFlags.dom) {
+    var mx = mutations[0];
+    if (mx && mx.type === 'childList' && mx.addedNodes) {
+        if (mx.addedNodes) {
+          var d = mx.addedNodes[0];
+          while (d && d !== document && !d.host) {
+            d = d.parentNode;
+          }
+          var u = d && (d.URL || d._URL || (d.host && d.host.localName)) || '';
+          u = u.split('/?').shift().split('/').pop();
+        }
+    }
+    console.group('mutations (%d) [%s]', mutations.length, u || '');
+  }
+  //
+  mutations.forEach(function(mx) {
+    //logFlags.dom && console.group('mutation');
+    if (mx.type === 'childList') {
+      forEach(mx.addedNodes, function(n) {
+        //logFlags.dom && console.log(n.localName);
+        if (filter(n)) {
+          return;
+        }
+        // watch shadow-roots on nodes that have had them attached manually
+        // TODO(sjmiles): remove if createShadowRoot is overridden
+        // TODO(sjmiles): removed as an optimization, manual shadow roots
+        // must be watched explicitly
+        //watchAllShadows(n);
+        // nodes added may need lifecycle management
+        addedNode(n);
+      });
+      // removed nodes may need lifecycle management
+      forEach(mx.removedNodes, function(n) {
+        //logFlags.dom && console.log(n.localName);
+        if (filter(n)) {
+          return;
+        }
+        removedNode(n);
+      });
+    }
+    //logFlags.dom && console.groupEnd();
+  });
+  logFlags.dom && console.groupEnd();
+};
+
+var observer = new MutationObserver(handler);
+
+function takeRecords() {
+  // TODO(sjmiles): ask Raf why we have to call handler ourselves
+  handler(observer.takeRecords());
+}
+
+var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
+
+function observe(inRoot) {
+  observer.observe(inRoot, {childList: true, subtree: true});
+}
+
+function observeDocument(document) {
+  observe(document);
+}
+
+function upgradeDocument(document) {
+  logFlags.dom && console.group('upgradeDocument: ', (document.URL || document._URL || '').split('/').pop());
+  addedNode(document);
+  logFlags.dom && console.groupEnd();
+}
+
+// exports
+
+scope.watchShadow = watchShadow;
+scope.watchAllShadows = watchAllShadows;
+
+scope.upgradeAll = addedNode;
+scope.upgradeSubtree = addedSubtree;
+
+scope.observeDocument = observeDocument;
+scope.upgradeDocument = upgradeDocument;
+
+scope.takeRecords = takeRecords;
+
+})(window.CustomElements);
+
+/**
+ * Implements `document.register`
+ * @module CustomElements
+*/
+
+/**
+ * Polyfilled extensions to the `document` object.
+ * @class Document
+*/
+
+(function(scope) {
+
+// imports
+
+if (!scope) {
+  scope = window.CustomElements = {flags:{}};
+}
+var flags = scope.flags;
+
+// native document.register?
+
+var hasNative = Boolean(document.webkitRegister || document.register);
+var useNative = !flags.register && hasNative;
+
+if (useNative) {
+
+  // normalize
+  document.register = document.register || document.webkitRegister;
+
+  // stub
+  var nop = function() {};
+
+  // exports
+  scope.registry = {};
+  scope.upgradeElement = nop;
+
+  scope.watchShadow = nop;
+  scope.watchAllShadows = nop;
+  scope.upgrade = nop;
+  scope.upgradeAll = nop;
+  scope.upgradeSubtree = nop;
+  scope.observeDocument = nop;
+  scope.upgradeDocument = nop;
+  scope.takeRecords = nop;
+
+} else {
+
+  /**
+   * Registers a custom tag name with the document.
+   *
+   * When a registered element is created, a `readyCallback` method is called
+   * in the scope of the element. The `readyCallback` method can be specified on
+   * either `inOptions.prototype` or `inOptions.lifecycle` with the latter taking
+   * precedence.
+   *
+   * @method register
+   * @param {String} inName The tag name to register. Must include a dash ('-'),
+   *    for example 'x-component'.
+   * @param {Object} inOptions
+   *    @param {String} [inOptions.extends]
+   *      (_off spec_) Tag name of an element to extend (or blank for a new
+   *      element). This parameter is not part of the specification, but instead
+   *      is a hint for the polyfill because the extendee is difficult to infer.
+   *      Remember that the input prototype must chain to the extended element's
+   *      prototype (or HTMLElement.prototype) regardless of the value of
+   *      `extends`.
+   *    @param {Object} inOptions.prototype The prototype to use for the new
+   *      element. The prototype must inherit from HTMLElement.
+   *    @param {Object} [inOptions.lifecycle]
+   *      Callbacks that fire at important phases in the life of the custom
+   *      element.
+   *
+   * @example
+   *      FancyButton = document.register("fancy-button", {
+   *        extends: 'button',
+   *        prototype: Object.create(HTMLButtonElement.prototype, {
+   *          readyCallback: {
+   *            value: function() {
+   *              console.log("a fancy-button was created",
+   *            }
+   *          }
+   *        })
+   *      });
+   * @return {Function} Constructor for the newly registered type.
+   */
+  function register(inName, inOptions) {
+    //console.warn('document.register("' + inName + '", ', inOptions, ')');
+    // construct a defintion out of options
+    // TODO(sjmiles): probably should clone inOptions instead of mutating it
+    var definition = inOptions || {};
+    if (!inName) {
+      // TODO(sjmiles): replace with more appropriate error (EricB can probably
+      // offer guidance)
+      throw new Error('Name argument must not be empty');
+    }
+    // record name
+    definition.name = inName;
+    // must have a prototype, default to an extension of HTMLElement
+    // TODO(sjmiles): probably should throw if no prototype, check spec
+    if (!definition.prototype) {
+      // TODO(sjmiles): replace with more appropriate error (EricB can probably
+      // offer guidance)
+      throw new Error('Options missing required prototype property');
+    }
+    // ensure a lifecycle object so we don't have to null test it
+    definition.lifecycle = definition.lifecycle || {};
+    // build a list of ancestral custom elements (for native base detection)
+    // TODO(sjmiles): we used to need to store this, but current code only
+    // uses it in 'resolveTagName': it should probably be inlined
+    definition.ancestry = ancestry(definition.extends);
+    // extensions of native specializations of HTMLElement require localName
+    // to remain native, and use secondary 'is' specifier for extension type
+    resolveTagName(definition);
+    // some platforms require modifications to the user-supplied prototype
+    // chain
+    resolvePrototypeChain(definition);
+    // overrides to implement attributeChanged callback
+    overrideAttributeApi(definition.prototype);
+    // 7.1.5: Register the DEFINITION with DOCUMENT
+    registerDefinition(inName, definition);
+    // 7.1.7. Run custom element constructor generation algorithm with PROTOTYPE
+    // 7.1.8. Return the output of the previous step.
+    definition.ctor = generateConstructor(definition);
+    definition.ctor.prototype = definition.prototype;
+    // force our .constructor to be our actual constructor
+    definition.prototype.constructor = definition.ctor;
+    // if initial parsing is complete
+    if (scope.ready) {
+      // upgrade any pre-existing nodes of this type
+      scope.upgradeAll(document);
+    }
+    return definition.ctor;
+  }
+
+  function ancestry(inExtends) {
+    var extendee = registry[inExtends];
+    if (extendee) {
+      return ancestry(extendee.extends).concat([extendee]);
+    }
+    return [];
+  }
+
+  function resolveTagName(inDefinition) {
+    // if we are explicitly extending something, that thing is our
+    // baseTag, unless it represents a custom component
+    var baseTag = inDefinition.extends;
+    // if our ancestry includes custom components, we only have a
+    // baseTag if one of them does
+    for (var i=0, a; (a=inDefinition.ancestry[i]); i++) {
+      baseTag = a.is && a.tag;
+    }
+    // our tag is our baseTag, if it exists, and otherwise just our name
+    inDefinition.tag = baseTag || inDefinition.name;
+    if (baseTag) {
+      // if there is a base tag, use secondary 'is' specifier
+      inDefinition.is = inDefinition.name;
+    }
+  }
+
+  function resolvePrototypeChain(inDefinition) {
+    // if we don't support __proto__ we need to locate the native level
+    // prototype for precise mixing in
+    if (!Object.__proto__) {
+      // default prototype
+      var native = HTMLElement.prototype;
+      // work out prototype when using type-extension
+      if (inDefinition.is) {
+        var inst = document.createElement(inDefinition.tag);
+        native = Object.getPrototypeOf(inst);
+      }
+      // ensure __proto__ reference is installed at each point on the prototype
+      // chain.
+      // NOTE: On platforms without __proto__, a mixin strategy is used instead
+      // of prototype swizzling. In this case, this generated __proto__ provides
+      // limited support for prototype traversal.
+      var proto = inDefinition.prototype, ancestor;
+      while (proto && (proto !== native)) {
+        var ancestor = Object.getPrototypeOf(proto);
+        proto.__proto__ = ancestor;
+        proto = ancestor;
+      }
+    }
+    // cache this in case of mixin
+    inDefinition.native = native;
+  }
+
+  // SECTION 4
+
+  function instantiate(inDefinition) {
+    // 4.a.1. Create a new object that implements PROTOTYPE
+    // 4.a.2. Let ELEMENT by this new object
+    //
+    // the custom element instantiation algorithm must also ensure that the
+    // output is a valid DOM element with the proper wrapper in place.
+    //
+    return upgrade(domCreateElement(inDefinition.tag), inDefinition);
+  }
+
+  function upgrade(inElement, inDefinition) {
+    // some definitions specify an 'is' attribute
+    if (inDefinition.is) {
+      inElement.setAttribute('is', inDefinition.is);
+    }
+    // make 'element' implement inDefinition.prototype
+    implement(inElement, inDefinition);
+    // flag as upgraded
+    inElement.__upgraded__ = true;
+    // there should never be a shadow root on inElement at this point
+    // we require child nodes be upgraded before `created`
+    scope.upgradeSubtree(inElement);
+    // lifecycle management
+    created(inElement);
+    // OUTPUT
+    return inElement;
+  }
+
+  function implement(inElement, inDefinition) {
+    // prototype swizzling is best
+    if (Object.__proto__) {
+      inElement.__proto__ = inDefinition.prototype;
+    } else {
+      // where above we can re-acquire inPrototype via
+      // getPrototypeOf(Element), we cannot do so when
+      // we use mixin, so we install a magic reference
+      customMixin(inElement, inDefinition.prototype, inDefinition.native);
+      inElement.__proto__ = inDefinition.prototype;
+    }
+  }
+
+  function customMixin(inTarget, inSrc, inNative) {
+    // TODO(sjmiles): 'used' allows us to only copy the 'youngest' version of
+    // any property. This set should be precalculated. We also need to
+    // consider this for supporting 'super'.
+    var used = {};
+    // start with inSrc
+    var p = inSrc;
+    // sometimes the default is HTMLUnknownElement.prototype instead of
+    // HTMLElement.prototype, so we add a test
+    // the idea is to avoid mixing in native prototypes, so adding
+    // the second test is WLOG
+    while (p !== inNative && p !== HTMLUnknownElement.prototype) {
+      var keys = Object.getOwnPropertyNames(p);
+      for (var i=0, k; k=keys[i]; i++) {
+        if (!used[k]) {
+          Object.defineProperty(inTarget, k,
+              Object.getOwnPropertyDescriptor(p, k));
+          used[k] = 1;
+        }
+      }
+      p = Object.getPrototypeOf(p);
+    }
+  }
+
+  function created(inElement) {
+    // invoke createdCallback
+    if (inElement.createdCallback) {
+      inElement.createdCallback();
+    }
+  }
+
+  // attribute watching
+
+  function overrideAttributeApi(prototype) {
+    // overrides to implement callbacks
+    // TODO(sjmiles): should support access via .attributes NamedNodeMap
+    // TODO(sjmiles): preserves user defined overrides, if any
+    var setAttribute = prototype.setAttribute;
+    prototype.setAttribute = function(name, value) {
+      changeAttribute.call(this, name, value, setAttribute);
+    }
+    var removeAttribute = prototype.removeAttribute;
+    prototype.removeAttribute = function(name, value) {
+      changeAttribute.call(this, name, value, removeAttribute);
+    }
+  }
+
+  function changeAttribute(name, value, operation) {
+    var oldValue = this.getAttribute(name);
+    operation.apply(this, arguments);
+    if (this.attributeChangedCallback
+        && (this.getAttribute(name) !== oldValue)) {
+      this.attributeChangedCallback(name, oldValue);
+    }
+  }
+
+  // element registry (maps tag names to definitions)
+
+  var registry = {};
+
+  function registerDefinition(inName, inDefinition) {
+    if (registry[inName]) {
+      throw new Error('Cannot register a tag more than once');
+    }
+    registry[inName] = inDefinition;
+  }
+
+  function generateConstructor(inDefinition) {
+    return function() {
+      return instantiate(inDefinition);
+    };
+  }
+
+  function createElement(tag, typeExtension) {
+    // TODO(sjmiles): ignore 'tag' when using 'typeExtension', we could
+    // error check it, or perhaps there should only ever be one argument
+    var definition = registry[typeExtension || tag];
+    if (definition) {
+      return new definition.ctor();
+    }
+    return domCreateElement(tag);
+  }
+
+  function upgradeElement(inElement) {
+    if (!inElement.__upgraded__ && (inElement.nodeType === Node.ELEMENT_NODE)) {
+      var type = inElement.getAttribute('is') || inElement.localName;
+      var definition = registry[type];
+      return definition && upgrade(inElement, definition);
+    }
+  }
+
+  function cloneNode(deep) {
+    // call original clone
+    var n = domCloneNode.call(this, deep);
+    // upgrade the element and subtree
+    scope.upgradeAll(n);
+    // return the clone
+    return n;
+  }
+  // capture native createElement before we override it
+
+  var domCreateElement = document.createElement.bind(document);
+
+  // capture native cloneNode before we override it
+
+  var domCloneNode = Node.prototype.cloneNode;
+
+  // exports
+
+  document.register = register;
+  document.createElement = createElement; // override
+  Node.prototype.cloneNode = cloneNode; // override
+
+  scope.registry = registry;
+
+  /**
+   * Upgrade an element to a custom element. Upgrading an element
+   * causes the custom prototype to be applied, an `is` attribute
+   * to be attached (as needed), and invocation of the `readyCallback`.
+   * `upgrade` does nothing if the element is already upgraded, or
+   * if it matches no registered custom tag name.
+   *
+   * @method ugprade
+   * @param {Element} inElement The element to upgrade.
+   * @return {Element} The upgraded element.
+   */
+  scope.upgrade = upgradeElement;
+}
+
+scope.hasNative = hasNative;
+scope.useNative = useNative;
+
+})(window.CustomElements);
+
+(function() {
+
+// import
+
+var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : 'none';
+
+// highlander object for parsing a document tree
+
+var parser = {
+  selectors: [
+    'link[rel=' + IMPORT_LINK_TYPE + ']'
+  ],
+  map: {
+    link: 'parseLink'
+  },
+  parse: function(inDocument) {
+    if (!inDocument.__parsed) {
+      // only parse once
+      inDocument.__parsed = true;
+      // all parsable elements in inDocument (depth-first pre-order traversal)
+      var elts = inDocument.querySelectorAll(parser.selectors);
+      // for each parsable node type, call the mapped parsing method
+      forEach(elts, function(e) {
+        parser[parser.map[e.localName]](e);
+      });
+      // upgrade all upgradeable static elements, anything dynamically
+      // created should be caught by observer
+      CustomElements.upgradeDocument(inDocument);
+      // observe document for dom changes
+      CustomElements.observeDocument(inDocument);
+    }
+  },
+  parseLink: function(linkElt) {
+    // imports
+    if (isDocumentLink(linkElt)) {
+      this.parseImport(linkElt);
+    }
+  },
+  parseImport: function(linkElt) {
+    if (linkElt.content) {
+      parser.parse(linkElt.content);
+    }
+  }
+};
+
+function isDocumentLink(inElt) {
+  return (inElt.localName === 'link'
+      && inElt.getAttribute('rel') === IMPORT_LINK_TYPE);
+}
+
+var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
+
+// exports
+
+CustomElements.parser = parser;
+
+})();
+(function(){
+
+// bootstrap parsing
+
+function bootstrap() {
+  // go async so call stack can unwind
+  setTimeout(function() {
+    // parse document
+    CustomElements.parser.parse(document);
+    // one more pass before register is 'live'
+    CustomElements.upgradeDocument(document);
+    // set internal 'ready' flag, now document.register will trigger
+    // synchronous upgrades
+    CustomElements.ready = true;
+    // capture blunt profiling data
+    CustomElements.readyTime = Date.now();
+    if (window.HTMLImports) {
+      CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;
+    }
+    // notify the system that we are bootstrapped
+    document.body.dispatchEvent(
+      new CustomEvent('WebComponentsReady', {bubbles: true})
+    );
+  }, 0);
+}
+
+// CustomEvent shim for IE
+if (typeof window.CustomEvent !== 'function') {
+  window.CustomEvent = function(inType) {
+     var e = document.createEvent('HTMLEvents');
+     e.initEvent(inType, true, true);
+     return e;
+  };
+}
+
+if (document.readyState === 'complete') {
+  bootstrap();
+} else {
+  var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' : 'DOMContentLoaded';
+  window.addEventListener(loadEvent, bootstrap);
+}
+
+})();
diff --git a/pkg/custom_element/lib/custom-elements.min.js b/pkg/custom_element/lib/custom-elements.min.js
new file mode 100644
index 0000000..f0c3e81
--- /dev/null
+++ b/pkg/custom_element/lib/custom-elements.min.js
@@ -0,0 +1,28 @@
+// Copyright (c) 2012 The Polymer Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+window.CustomElements={flags:{}};var SideTable;if("undefined"!=typeof WeakMap&&navigator.userAgent.indexOf("Firefox/")<0?SideTable=WeakMap:function(){var a=Object.defineProperty,b=Object.hasOwnProperty,c=(new Date).getTime()%1e9;SideTable=function(){this.name="__st"+(1e9*Math.random()>>>0)+(c++ +"__")},SideTable.prototype={set:function(b,c){a(b,this.name,{value:c,writable:!0})},get:function(a){return b.call(a,this.name)?a[this.name]:void 0},"delete":function(a){this.set(a,void 0)}}}(),function(a){function b(a){u.push(a),t||(t=!0,q(d))}function c(a){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(a)||a}function d(){t=!1;var a=u;u=[],a.sort(function(a,b){return a.uid_-b.uid_});var b=!1;a.forEach(function(a){var c=a.takeRecords();e(a),c.length&&(a.callback_(c,a),b=!0)}),b&&d()}function e(a){a.nodes_.forEach(function(b){var c=p.get(b);c&&c.forEach(function(b){b.observer===a&&b.removeTransientObservers()})})}function f(a,b){for(var c=a;c;c=c.parentNode){var d=p.get(c);if(d)for(var e=0;e<d.length;e++){var f=d[e],g=f.options;if(c===a||g.subtree){var h=b(g);h&&f.enqueue(h)}}}}function g(a){this.callback_=a,this.nodes_=[],this.records_=[],this.uid_=++v}function h(a,b){this.type=a,this.target=b,this.addedNodes=[],this.removedNodes=[],this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function i(a){var b=new h(a.type,a.target);return b.addedNodes=a.addedNodes.slice(),b.removedNodes=a.removedNodes.slice(),b.previousSibling=a.previousSibling,b.nextSibling=a.nextSibling,b.attributeName=a.attributeName,b.attributeNamespace=a.attributeNamespace,b.oldValue=a.oldValue,b}function j(a,b){return w=new h(a,b)}function k(a){return x?x:(x=i(w),x.oldValue=a,x)}function l(){w=x=void 0}function m(a){return a===x||a===w}function n(a,b){return a===b?a:x&&m(a)?x:null}function o(a,b,c){this.observer=a,this.target=b,this.options=c,this.transientObservedNodes=[]}var p=new SideTable,q=window.msSetImmediate;if(!q){var r=[],s=String(Math.random());window.addEventListener("message",function(a){if(a.data===s){var b=r;r=[],b.forEach(function(a){a()})}}),q=function(a){r.push(a),window.postMessage(s,"*")}}var t=!1,u=[],v=0;g.prototype={observe:function(a,b){if(a=c(a),!b.childList&&!b.attributes&&!b.characterData||b.attributeOldValue&&!b.attributes||b.attributeFilter&&b.attributeFilter.length&&!b.attributes||b.characterDataOldValue&&!b.characterData)throw new SyntaxError;var d=p.get(a);d||p.set(a,d=[]);for(var e,f=0;f<d.length;f++)if(d[f].observer===this){e=d[f],e.removeListeners(),e.options=b;break}e||(e=new o(this,a,b),d.push(e),this.nodes_.push(a)),e.addListeners()},disconnect:function(){this.nodes_.forEach(function(a){for(var b=p.get(a),c=0;c<b.length;c++){var d=b[c];if(d.observer===this){d.removeListeners(),b.splice(c,1);break}}},this),this.records_=[]},takeRecords:function(){var a=this.records_;return this.records_=[],a}};var w,x;o.prototype={enqueue:function(a){var c=this.observer.records_,d=c.length;if(c.length>0){var e=c[d-1],f=n(e,a);if(f)return c[d-1]=f,void 0}else b(this.observer);c[d]=a},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(a){var b=this.options;b.attributes&&a.addEventListener("DOMAttrModified",this,!0),b.characterData&&a.addEventListener("DOMCharacterDataModified",this,!0),b.childList&&a.addEventListener("DOMNodeInserted",this,!0),(b.childList||b.subtree)&&a.addEventListener("DOMNodeRemoved",this,!0)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(a){var b=this.options;b.attributes&&a.removeEventListener("DOMAttrModified",this,!0),b.characterData&&a.removeEventListener("DOMCharacterDataModified",this,!0),b.childList&&a.removeEventListener("DOMNodeInserted",this,!0),(b.childList||b.subtree)&&a.removeEventListener("DOMNodeRemoved",this,!0)},addTransientObserver:function(a){if(a!==this.target){this.addListeners_(a),this.transientObservedNodes.push(a);var b=p.get(a);b||p.set(a,b=[]),b.push(this)}},removeTransientObservers:function(){var a=this.transientObservedNodes;this.transientObservedNodes=[],a.forEach(function(a){this.removeListeners_(a);for(var b=p.get(a),c=0;c<b.length;c++)if(b[c]===this){b.splice(c,1);break}},this)},handleEvent:function(a){switch(a.stopImmediatePropagation(),a.type){case"DOMAttrModified":var b=a.attrName,c=a.relatedNode.namespaceURI,d=a.target,e=new j("attributes",d);e.attributeName=b,e.attributeNamespace=c;var g=a.attrChange===MutationEvent.ADDITION?null:a.prevValue;f(d,function(a){return!a.attributes||a.attributeFilter&&a.attributeFilter.length&&-1===a.attributeFilter.indexOf(b)&&-1===a.attributeFilter.indexOf(c)?void 0:a.attributeOldValue?k(g):e});break;case"DOMCharacterDataModified":var d=a.target,e=j("characterData",d),g=a.prevValue;f(d,function(a){return a.characterData?a.characterDataOldValue?k(g):e:void 0});break;case"DOMNodeRemoved":this.addTransientObserver(a.target);case"DOMNodeInserted":var h,i,d=a.relatedNode,m=a.target;"DOMNodeInserted"===a.type?(h=[m],i=[]):(h=[],i=[m]);var n=m.previousSibling,o=m.nextSibling,e=j("childList",d);e.addedNodes=h,e.removedNodes=i,e.previousSibling=n,e.nextSibling=o,f(d,function(a){return a.childList?e:void 0})}l()}},a.JsMutationObserver=g}(this),!window.MutationObserver&&(window.MutationObserver=window.WebKitMutationObserver||window.JsMutationObserver,!MutationObserver))throw new Error("no mutation observer support");!function(a){function b(a,c,d){var e=a.firstElementChild;if(!e)for(e=a.firstChild;e&&e.nodeType!==Node.ELEMENT_NODE;)e=e.nextSibling;for(;e;)c(e,d)!==!0&&b(e,c,d),e=e.nextElementSibling;return null}function c(a,b){for(var c=a.webkitShadowRoot;c;)d(c,b),c=c.olderShadowRoot}function d(a,d){b(a,function(a){return d(a)?!0:(c(a,d),void 0)}),c(a,d)}function e(a){return h(a)?(i(a),!0):(j(a),void 0)}function f(a){d(a,function(a){return e(a)?!0:void 0})}function g(a){return e(a)||f(a)}function h(b){if(!b.__upgraded__&&b.nodeType===Node.ELEMENT_NODE){var c=b.getAttribute("is")||b.localName,d=a.registry[c];if(d)return logFlags.dom&&console.group("upgrade:",b.localName),a.upgrade(b),logFlags.dom&&console.groupEnd(),!0}}function i(a){j(a),m(a)&&d(a,function(a){j(a)})}function j(a){(a.enteredDocumentCallback||a.__upgraded__&&logFlags.dom)&&(logFlags.dom&&console.group("inserted:",a.localName),m(a)&&(a.__inserted=(a.__inserted||0)+1,a.__inserted<1&&(a.__inserted=1),a.__inserted>1?logFlags.dom&&console.warn("inserted:",a.localName,"insert/remove count:",a.__inserted):a.enteredDocumentCallback&&(logFlags.dom&&console.log("inserted:",a.localName),a.enteredDocumentCallback())),logFlags.dom&&console.groupEnd())}function k(a){l(a),d(a,function(a){l(a)})}function l(a){(a.leftDocumentCallback||a.__upgraded__&&logFlags.dom)&&(logFlags.dom&&console.log("removed:",a.localName),m(a)||(a.__inserted=(a.__inserted||0)-1,a.__inserted>0&&(a.__inserted=0),a.__inserted<0?logFlags.dom&&console.warn("removed:",a.localName,"insert/remove count:",a.__inserted):a.leftDocumentCallback&&a.leftDocumentCallback()))}function m(a){for(var b=a;b;){if(b==a.ownerDocument)return!0;b=b.parentNode||b.host}}function n(a){if(a.webkitShadowRoot&&!a.webkitShadowRoot.__watched){logFlags.dom&&console.log("watching shadow-root for: ",a.localName);for(var b=a.webkitShadowRoot;b;)o(b),b=b.olderShadowRoot}}function o(a){a.__watched||(t(a),a.__watched=!0)}function p(a){n(a),d(a,function(){n(a)})}function q(a){switch(a.localName){case"style":case"script":case"template":case void 0:return!0}}function r(a){if(logFlags.dom){var b=a[0];if(b&&"childList"===b.type&&b.addedNodes&&b.addedNodes){for(var c=b.addedNodes[0];c&&c!==document&&!c.host;)c=c.parentNode;var d=c&&(c.URL||c._URL||c.host&&c.host.localName)||"";d=d.split("/?").shift().split("/").pop()}console.group("mutations (%d) [%s]",a.length,d||"")}a.forEach(function(a){"childList"===a.type&&(x(a.addedNodes,function(a){q(a)||g(a)}),x(a.removedNodes,function(a){q(a)||k(a)}))}),logFlags.dom&&console.groupEnd()}function s(){r(w.takeRecords())}function t(a){w.observe(a,{childList:!0,subtree:!0})}function u(a){t(a)}function v(a){logFlags.dom&&console.group("upgradeDocument: ",(a.URL||a._URL||"").split("/").pop()),g(a),logFlags.dom&&console.groupEnd()}var w=new MutationObserver(r),x=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.watchShadow=n,a.watchAllShadows=p,a.upgradeAll=g,a.upgradeSubtree=f,a.observeDocument=u,a.upgradeDocument=v,a.takeRecords=s}(window.CustomElements),function(a){function b(b,f){var g=f||{};if(!b)throw new Error("Name argument must not be empty");if(g.name=b,!g.prototype)throw new Error("Options missing required prototype property");return g.lifecycle=g.lifecycle||{},g.ancestry=c(g.extends),d(g),e(g),k(g.prototype),m(b,g),g.ctor=n(g),g.ctor.prototype=g.prototype,g.prototype.constructor=g.ctor,a.ready&&a.upgradeAll(document),g.ctor}function c(a){var b=v[a];return b?c(b.extends).concat([b]):[]}function d(a){for(var b,c=a.extends,d=0;b=a.ancestry[d];d++)c=b.is&&b.tag;a.tag=c||a.name,c&&(a.is=a.name)}function e(a){if(!Object.__proto__){var b=HTMLElement.prototype;if(a.is){var c=document.createElement(a.tag);b=Object.getPrototypeOf(c)}for(var d,e=a.prototype;e&&e!==b;){var d=Object.getPrototypeOf(e);e.__proto__=d,e=d}}a.native=b}function f(a){return g(w(a.tag),a)}function g(b,c){return c.is&&b.setAttribute("is",c.is),h(b,c),b.__upgraded__=!0,a.upgradeSubtree(b),j(b),b}function h(a,b){Object.__proto__?a.__proto__=b.prototype:(i(a,b.prototype,b.native),a.__proto__=b.prototype)}function i(a,b,c){for(var d={},e=b;e!==c&&e!==HTMLUnknownElement.prototype;){for(var f,g=Object.getOwnPropertyNames(e),h=0;f=g[h];h++)d[f]||(Object.defineProperty(a,f,Object.getOwnPropertyDescriptor(e,f)),d[f]=1);e=Object.getPrototypeOf(e)}}function j(a){a.createdCallback&&a.createdCallback()}function k(a){var b=a.setAttribute;a.setAttribute=function(a,c){l.call(this,a,c,b)};var c=a.removeAttribute;a.removeAttribute=function(a,b){l.call(this,a,b,c)}}function l(a,b,c){var d=this.getAttribute(a);c.apply(this,arguments),this.attributeChangedCallback&&this.getAttribute(a)!==d&&this.attributeChangedCallback(a,d)}function m(a,b){if(v[a])throw new Error("Cannot register a tag more than once");v[a]=b}function n(a){return function(){return f(a)}}function o(a,b){var c=v[b||a];return c?new c.ctor:w(a)}function p(a){if(!a.__upgraded__&&a.nodeType===Node.ELEMENT_NODE){var b=a.getAttribute("is")||a.localName,c=v[b];return c&&g(a,c)}}function q(b){var c=x.call(this,b);return a.upgradeAll(c),c}a||(a=window.CustomElements={flags:{}});var r=a.flags,s=Boolean(document.webkitRegister||document.register),t=!r.register&&s;if(t){document.register=document.register||document.webkitRegister;var u=function(){};a.registry={},a.upgradeElement=u,a.watchShadow=u,a.watchAllShadows=u,a.upgrade=u,a.upgradeAll=u,a.upgradeSubtree=u,a.observeDocument=u,a.upgradeDocument=u,a.takeRecords=u}else{var v={},w=document.createElement.bind(document),x=Node.prototype.cloneNode;document.register=b,document.createElement=o,Node.prototype.cloneNode=q,a.registry=v,a.upgrade=p}a.hasNative=s,a.useNative=t}(window.CustomElements),function(){function a(a){return"link"===a.localName&&a.getAttribute("rel")===b}var b=window.HTMLImports?HTMLImports.IMPORT_LINK_TYPE:"none",c={selectors:["link[rel="+b+"]"],map:{link:"parseLink"},parse:function(a){if(!a.__parsed){a.__parsed=!0;var b=a.querySelectorAll(c.selectors);d(b,function(a){c[c.map[a.localName]](a)}),CustomElements.upgradeDocument(a),CustomElements.observeDocument(a)}},parseLink:function(b){a(b)&&this.parseImport(b)},parseImport:function(a){a.content&&c.parse(a.content)}},d=Array.prototype.forEach.call.bind(Array.prototype.forEach);CustomElements.parser=c}(),function(){function a(){setTimeout(function(){CustomElements.parser.parse(document),CustomElements.upgradeDocument(document),CustomElements.ready=!0,CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.body.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))},0)}if("function"!=typeof window.CustomEvent&&(window.CustomEvent=function(a){var b=document.createEvent("HTMLEvents");return b.initEvent(a,!0,!0),b}),"complete"===document.readyState)a();else{var b=window.HTMLImports?"HTMLImportsLoaded":"DOMContentLoaded";window.addEventListener(b,a)}}();
diff --git a/pkg/custom_element/lib/custom_element.dart b/pkg/custom_element/lib/custom_element.dart
index 16978ae..4121dbf 100644
--- a/pkg/custom_element/lib/custom_element.dart
+++ b/pkg/custom_element/lib/custom_element.dart
@@ -313,6 +313,8 @@
     host.innerHtml = v;
   }
 
+  InputMethodContext get inputMethodContext => host.inputMethodContext;
+
   bool get isContentEditable => host.isContentEditable;
 
   String get lang => host.lang;
@@ -338,7 +340,8 @@
 
   void click() { host.click(); }
 
-  InputMethodContext getInputContext() => host.getInputContext();
+  List<Node> getDestinationInsertionPoints() =>
+    host.getDestinationInsertionPoints();
 
   Element insertAdjacentElement(String where, Element element) =>
     host.insertAdjacentElement(where, element);
diff --git a/pkg/docgen/README.md b/pkg/docgen/README.md
index 24ba58a..66d0a46 100644
--- a/pkg/docgen/README.md
+++ b/pkg/docgen/README.md
@@ -32,19 +32,21 @@
 
 - `-h`, `--help` Prints help and usage information.
 - `-v`, `--verbose` Output more logging information.
-- `-j`, `--[no-]json` Outputs to JSON. Files are outputted to YAML by default.
+- `-j`, `--[no-]json` Outputs to JSON. Files are outputted to YAML by default. 
+If `--append` is used, it takes the file-format of the previous run stated in 
+library_list.json ignoring the flag.
 - `--include-private` Flag to include private declarations.
 - `--include-sdk` Flag to parse SDK Library files imported.
 - `--parse-sdk` Parses the SDK libraries only. (Ignores the path passed in.)
 - `--package-root` Sets the package root of the library being analyzed.
-- `--append` Appends to the docs folder, library_list.txt, and index.txt.
+- `--append` Appends to the docs folder, library_list.json, and index.txt.
 - `--introduction` Adds the provided markdown text file as the introduction
 for the outputted documentation.
 
 
 ###### Output Directory
 Documented libraries will be located at bin/docs in either YAML or JSON format 
-depending on options specified. There will also be a library_list.txt, 
+depending on options specified. There will also be a library_list.json, 
 containing a list of all the libraries inside the docs folder. 
 
 To get more information on how to use the outputted documentation with 
diff --git a/pkg/docgen/bin/docgen.dart b/pkg/docgen/bin/docgen.dart
index ca4f780..293f3cf 100644
--- a/pkg/docgen/bin/docgen.dart
+++ b/pkg/docgen/bin/docgen.dart
@@ -49,7 +49,9 @@
         if (verbose) Logger.root.level = Level.FINEST;
       });
   parser.addFlag('json', abbr: 'j', 
-      help: 'Outputs to JSON. Files are outputted to YAML by default.', 
+      help: 'Outputs to JSON. Files are outputted to YAML by default. ' 
+        'If --append is used, it takes the file-format of the previous '
+        'run stated in library_list.json ignoring the flag.', 
       negatable: true);
   parser.addFlag('include-private', 
       help: 'Flag to include private declarations.', negatable: false);
@@ -61,7 +63,7 @@
   parser.addOption('package-root', 
       help: 'Sets the package root of the library being analyzed.');
   parser.addFlag('append', 
-      help: 'Append to the docs folder, library_list.txt and index.txt', 
+      help: 'Append to the docs folder, library_list.json and index.txt', 
       defaultsTo: false, negatable: false);
   parser.addOption('introduction', 
       help: 'Adds the provided markdown text file as the introduction' 
diff --git a/pkg/docgen/lib/dart2yaml.dart b/pkg/docgen/lib/dart2yaml.dart
index 57ca7fe..343b61f 100644
--- a/pkg/docgen/lib/dart2yaml.dart
+++ b/pkg/docgen/lib/dart2yaml.dart
@@ -7,6 +7,8 @@
  */
 library dart2yaml;
 
+import 'dart:collection';
+
 /**
  * Gets a String representing the input Map in YAML format.
  */
@@ -26,10 +28,11 @@
  */
 void _addLevel(StringBuffer yaml, Map documentData, int level,
                {bool isList: false}) {
-  // Since the ordering of the keys could be non-deterministic, the keys
-  // are sorted to ensure consistency in the output.
+  // The order of the keys could be nondeterministic, but it is insufficient 
+  // to just sort the keys no matter what, as their order could be significant
+  // (i.e. parameters to a method). The order of the keys should be enforced
+  // by the caller of this function.
   var keys = documentData.keys.toList();
-  keys.sort();
   keys.forEach((key) {
     _calcSpaces(level, yaml);
     // Only the first entry of the map should be preceeded with a '-' since
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index a51ab86..6faca3f5 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -244,26 +244,44 @@
   if (parseSdk) entityMap['dart.core.Object'].subclasses.clear();
 
   var filteredEntities = entityMap.values.where(_isVisible);
+  
+  // Outputs a JSON file with all libraries and their preview comments. 
+  // This will help the viewer know what libraries are available to read in.
+  var libraryMap;
+  if (append) {
+    var docsDir = listDir('docs');
+    if (!docsDir.contains('docs/library_list.json')) {
+      throw new StateError('No library_list.json');
+    }
+    libraryMap = parse(new File('docs/library_list.json').readAsStringSync());
+    libraryMap['libraries'].addAll(filteredEntities
+        .where((e) => e is Library)
+        .map((e) => e.previewMap));
+    if (introduction.isNotEmpty) {
+      var intro = libraryMap['introduction'];
+      if (intro.isNotEmpty) intro += '<br/><br/>';
+      intro += markdown.markdownToHtml(
+          new File(introduction).readAsStringSync(), 
+              linkResolver: linkResolver, inlineSyntaxes: markdownSyntaxes);
+      libraryMap['introduction'] = intro;
+    }
+    outputToYaml = libraryMap['filetype'] == 'yaml';
+  } else {
+    libraryMap = {
+      'libraries' : filteredEntities.where((e) => 
+          e is Library).map((e) => e.previewMap).toList(),
+      'introduction' : introduction == '' ? 
+          '' : markdown.markdownToHtml(new File(introduction)
+              .readAsStringSync(), linkResolver: linkResolver, 
+                  inlineSyntaxes: markdownSyntaxes), 
+      'filetype' : outputToYaml ? 'yaml' : 'json'
+    };
+  }
+  _writeToFile(stringify(libraryMap), 'library_list.json');
   // Output libraries and classes to file after all information is generated.
   filteredEntities.where((e) => e is Class || e is Library).forEach((output) {
     _writeIndexableToFile(output, outputToYaml);
   });
-  // Outputs a YAML or JSON file with all libraries and their preview comments 
-  // after creating all libraries. This will help the viewer know what 
-  // libraries are available to read in.
-  var libraryMap = {
-    'libraries' : filteredEntities.where((e) => 
-        e is Library).map((e) => e.previewMap).toList(),
-    'introduction' : introduction == '' ? 
-        '' : markdown.markdownToHtml(new File(introduction).readAsStringSync(),
-            linkResolver: linkResolver, inlineSyntaxes: markdownSyntaxes)
-  };
-  if (outputToYaml) {
-    _writeToFile(getYamlString(libraryMap), 'library_list.yaml', 
-        append: append);
-  } else {
-    _writeToFile(stringify(libraryMap), 'library_list.json', append: append);
-  }
   // Outputs all the qualified names documented with their type.
   // This will help generate search results.
   _writeToFile(filteredEntities.map((e) => 
diff --git a/pkg/intl/lib/generate_localized.dart b/pkg/intl/lib/generate_localized.dart
index 9516372..6477023 100644
--- a/pkg/intl/lib/generate_localized.dart
+++ b/pkg/intl/lib/generate_localized.dart
@@ -215,7 +215,8 @@
 Future initializeMessages(String localeName) {
   initializeInternalMessageLookup(() => new CompositeMessageLookup());
   messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
-  return deferredLibraries[localeName].load();
+  var lib = deferredLibraries[localeName];                                                           
+  return lib == null ? new Future.value(false) : lib.load();     
 }
 
 MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
diff --git a/pkg/intl/test/message_extraction/sample_with_messages.dart b/pkg/intl/test/message_extraction/sample_with_messages.dart
index 292273c..753f39c 100644
--- a/pkg/intl/test/message_extraction/sample_with_messages.dart
+++ b/pkg/intl/test/message_extraction/sample_with_messages.dart
@@ -178,6 +178,8 @@
   var fr = new Intl("fr");
   var english = new Intl("en_US");
   var de = new Intl("de_DE");
+  // Throw in an initialize of a null locale to make sure it doesn't throw.
+  initializeMessages(null);
   initializeMessages(fr.locale).then((_) => printStuff(fr));
   initializeMessages(de.locale).then((_) => printStuff(de));
   printStuff(english);
diff --git a/pkg/meta/lib/meta.dart b/pkg/meta/lib/meta.dart
index c86e377..9960d59 100644
--- a/pkg/meta/lib/meta.dart
+++ b/pkg/meta/lib/meta.dart
@@ -46,3 +46,18 @@
 class _Override {
   const _Override();
 }
+
+/**
+ * An annotation used to mark a class that should be considered to implement
+ * every possible getter, setter and method. Tools can use this annotation to
+ * suppress warnings when there is no explicit implementation of a referenced
+ * member. Tools should provide a hint if this annotation is applied to a class
+ * that does not implement or inherit an implementation of the method
+ * [:noSuchMethod:] (other than the implementation in [Object]). Note that
+ * classes are not affected by the use of this annotation on a supertype.
+ */
+const proxy = const _Proxy();
+
+class _Proxy {
+  const _Proxy();
+}
\ No newline at end of file
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 39486e0..f41776a 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -8,9 +8,12 @@
 */packages/*/*: Skip
 */*/packages/*/*: Skip
 */*/*/packages/*/*: Skip
+*/*/*/*/packages/*/*: Skip
 
 # Skip non-test files ending with "_test".
 scheduled_test/lib/*: Skip
+polymer/lib/*: Skip
+polymer/example/*: Skip
 
 scheduled_test/test/scheduled_server_test: Pass, Fail, Slow, Crash # Issue 9231, 9582
 scheduled_test/test/scheduled_process_test: Pass, Slow # Issue 9231
@@ -20,7 +23,6 @@
 
 [ $compiler == dart2js && $runtime == d8 ]
 unmodifiable_collection/test/unmodifiable_collection_test: Pass, Fail # Issue 12429
-csslib/test/declaration_test: Pass, Crash # V8 issue 2846
 
 [ $compiler == dart2js ]
 analyzer_experimental/test/generated/ast_test: Fail #Issue 12341
@@ -28,7 +30,7 @@
 [ $compiler == dart2js && $checked && $runtime == ie9 ]
 crypto/test/base64_test: Timeout # Issue 12486
 
-[ $compiler == dart2js && ($runtime == d8 || $runtime == drt) ]
+[ $compiler == dart2js && $runtime == drt ]
 crypto/test/hmac_sha256_test: Pass, Fail # v8 bug: Issue 12293
 crypto/test/sha1_test: Pass, Fail # v8 bug: Issue 12293
 crypto/test/sha256_test: Pass, Fail # v8 bug: Issue 12293
@@ -87,6 +89,8 @@
 observe/test/observe_test: Fail # Issue 11970
 observe/test/path_observer_test: Fail  # Issue 11970
 mdv/test/binding_syntax_test: Fail # Issue 11970
+polymer_expressions/test/eval_test: Fail # Issue 12578
+polymer_expressions/test/syntax_test: Fail # Issue 12578
 serialization/test/serialization_test: Fail # Issue 6490
 serialization/test/no_library_test: Fail # Issue 6490
 
@@ -109,7 +113,6 @@
 csslib/test/var_test: Fail # looking for VM-specific stack traces, issue 12469
 
 [ $compiler == dart2js && $runtime == drt ]
-third_party/html5lib/test/parser_feature_test: Fail # issue 12466
 csslib: Pass, Fail # issue 12466
 
 [ $browser ]
@@ -138,6 +141,7 @@
 oauth2/test/handle_access_token_response_test: Fail, OK # Uses dart:io.
 observe/test/transform_test: Fail, OK # Uses dart:io.
 path/test/io_test: Fail, OK # Uses dart:io.
+polymer/test/*: Fail, OK # Uses dart:io.
 watcher/test/*: Fail, OK # Uses dart:io.
 
 scheduled_test/test/descriptor/async_test: Fail # http://dartbug.com/8440
@@ -179,9 +183,6 @@
 # not minified.
 unittest/test/*_minified_test: Skip # DO NOT COPY THIS UNLESS YOU WORK ON DART2JS
 
-[ $compiler == none && $runtime == drt ]
-dartdoc/test/dartdoc_test: Skip # See dartbug.com/4541.
-
 [ $arch == arm ]
 *: Skip
 
diff --git a/pkg/polymer/README.md b/pkg/polymer/README.md
new file mode 100644
index 0000000..d4d177f0b
--- /dev/null
+++ b/pkg/polymer/README.md
@@ -0,0 +1,85 @@
+Polymer.dart
+============
+
+Polymer is a new type of library for the web, built on top of Web Components,
+and designed to leverage the evolving web platform on modern browsers.
+
+Polymer.dart is a Dart port of Polymer created and maintained by the Dart team.
+The Dart team is collaborating with the Polymer team to ensure that polymer.dart
+elements and polyfills are fully compatible with Polymer.
+
+For more information about Polymer, see <http://www.polymer-project.org/>.
+For more information about Dart, see <http://www.dartlang.org/>.
+
+Try It Now
+-----------
+Add the polymer.dart package to your pubspec.yaml file:
+
+```yaml
+dependencies:
+  polymer: any
+```
+
+Instead of using `any`, we recommend using version ranges to avoid getting your
+project broken on each release. Using a version range lets you upgrade your
+package at your own pace. You can find the latest version number at
+<https://pub.dartlang.org/packages/polymer>.
+
+
+Learn More
+----------
+
+**Note**: these documents are currently out of date.
+
+* [Read an overview][overview]
+* [Setup your tools][tools]
+* [Browse the features][features]
+* [Dive into the specification][spec]
+
+See our [TodoMVC][] example by opening up the Dart Editor's Welcome Page and
+selecting "TodoMVC".
+
+Running Tests
+-------------
+
+Dependencies are installed using the [Pub Package Manager][pub].
+```bash
+pub install
+
+# Run command line tests and automated end-to-end tests. It needs two
+# executables on your path: `dart` and `content_shell` (see below
+# for links to download `content_shell`)
+test/run.sh
+```
+Note: to run browser tests you will need to have [content_shell][cs],
+which can be downloaded prebuilt for [Ubuntu Lucid][cs_lucid],
+[Windows][cs_win], or [Mac][cs_mac]. You can also build it from the
+[Dartium and content_shell sources][dartium_src].
+
+For Linux users all the necessary fonts must be installed see
+<https://code.google.com/p/chromium/wiki/LayoutTestsLinux>.
+
+Contacting Us
+-------------
+
+Please file issues in our [Issue Tracker][issues] or contact us on the
+[Dart Web UI mailing list][mailinglist].
+
+We also have the [Web UI development list][devlist] for discussions about
+internals of the code, code reviews, etc.
+
+[wc]: http://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html
+[pub]: http://www.dartlang.org/docs/pub-package-manager/
+[cs]: http://www.chromium.org/developers/testing/webkit-layout-tests
+[cs_lucid]: http://gsdview.appspot.com/dartium-archive/continuous/drt-lucid64.zip
+[cs_mac]: http://gsdview.appspot.com/dartium-archive/continuous/drt-mac.zip
+[cs_win]: http://gsdview.appspot.com/dartium-archive/continuous/drt-win.zip
+[dartium_src]: http://code.google.com/p/dart/wiki/BuildingDartium
+[TodoMVC]: http://addyosmani.github.com/todomvc/
+[issues]: http://dartbug.com/new
+[mailinglist]: https://groups.google.com/a/dartlang.org/forum/?fromgroups#!forum/web-ui
+[devlist]: https://groups.google.com/a/dartlang.org/forum/?fromgroups#!forum/web-ui-dev
+[overview]: http://www.dartlang.org/articles/dart-web-components/
+[tools]: https://www.dartlang.org/articles/dart-web-components/tools.html
+[spec]: https://www.dartlang.org/articles/dart-web-components/spec.html
+[features]: https://www.dartlang.org/articles/dart-web-components/summary.html
diff --git a/pkg/polymer/bin/dwc.dart b/pkg/polymer/bin/dwc.dart
new file mode 100755
index 0000000..3d3a0a2
--- /dev/null
+++ b/pkg/polymer/bin/dwc.dart
@@ -0,0 +1,8 @@
+#!/usr/bin/env dart
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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:polymer/dwc.dart' as dwc;
+
+void main() => dwc.main();
diff --git a/pkg/polymer/build.dart b/pkg/polymer/build.dart
new file mode 100755
index 0000000..5e863b8
--- /dev/null
+++ b/pkg/polymer/build.dart
@@ -0,0 +1,17 @@
+#!/usr/bin/env dart
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/** Build logic that lets the Dart editor build examples in the background. */
+library build;
+import 'package:polymer/component_build.dart';
+import 'dart:io';
+
+void main() {
+  var args = new Options().arguments.toList()..addAll(['--', '--deploy']);
+  build(args, [
+    'example/component/news/web/index.html',
+    'example/scoped_style/index.html',
+    '../../samples/third_party/todomvc/web/index.html']);
+}
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
new file mode 100644
index 0000000..f5907ed
--- /dev/null
+++ b/pkg/polymer/example/component/news/test/expected/news_index_test.html.txt
@@ -0,0 +1,85 @@
+Content-Type: text/plain
+<html><head><style>template { display: none; }</style>
+  <title>Simple Web Components Example</title>
+  
+  <script src="../../packages/polymer/testing/testing.js"></script>
+<style>template,
+thead[template],
+tbody[template],
+tfoot[template],
+th[template],
+tr[template],
+td[template],
+caption[template],
+colgroup[template],
+col[template],
+option[template] {
+  display: none;
+}</style></head>
+<body><polymer-element name="x-news" extends="ul">
+    <template>
+        <style scoped="">
+            div.breaking {
+                color: Red;
+                font-size: 20px;
+                border: 1px dashed Purple;
+            }
+            div.other {
+                padding: 2px 0 0 0;
+                border: 1px solid Cyan;
+            }
+        </style>
+        <div class="breaking">
+            <h2>Breaking Stories</h2>
+            <ul>
+                <content select=".breaking"></content>
+            </ul>
+        </div>
+        <div class="other">
+            <h2>Other News</h2>
+            <ul>
+                <content></content>
+            </ul>
+        </div>
+    </template>
+    
+</polymer-element>
+
+<h1>Simple Web Components Example</h1>
+<ul is="x-news"><shadow-root>
+        <style scoped="">
+            div.breaking {
+                color: Red;
+                font-size: 20px;
+                border: 1px dashed Purple;
+            }
+            div.other {
+                padding: 2px 0 0 0;
+                border: 1px solid Cyan;
+            }
+        </style>
+        <div class="breaking">
+            <h2>Breaking Stories</h2>
+            <ul>
+                <content select=".breaking"></content>
+            </ul>
+        </div>
+        <div class="other">
+            <h2>Other News</h2>
+            <ul>
+                <content></content>
+            </ul>
+        </div>
+    </shadow-root>
+    <li><a href="//example.com/stories/1">A story</a></li>
+    <li><a href="//example.com/stories/2">Another story</a></li>
+    <li class="breaking"><a href="//example.com/stories/3">Also a story</a></li>
+    <li><a href="//example.com/stories/4">Yet another story</a></li>
+    <li><a href="//example.com/stories/4">Awesome story</a></li>
+    <li class="breaking"><a href="//example.com/stories/5">Horrible story</a></li>
+</ul>
+
+
+
+<script type="text/javascript" src="packages/shadow_dom/shadow_dom.debug.js"></script>
+<script type="application/dart" src="news_index_test.html_bootstrap.dart"></script></body></html>
diff --git a/pkg/polymer/example/component/news/test/news_index_test.html b/pkg/polymer/example/component/news/test/news_index_test.html
new file mode 100644
index 0000000..95bfadd
--- /dev/null
+++ b/pkg/polymer/example/component/news/test/news_index_test.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!--
+This example is from
+https://github.com/dglazkov/Web-Components-Polyfill/blob/master/samples/news
+-->
+<html>
+<head>
+  <title>Simple Web Components Example</title>
+  <link rel="import" href="../web/news-component.html">
+  <script src="packages/polymer/testing/testing.js"></script>
+</head>
+<body>
+<h1>Simple Web Components Example</h1>
+<ul is="x-news">
+    <li><a href="//example.com/stories/1">A story</a></li>
+    <li><a href="//example.com/stories/2">Another story</a></li>
+    <li class="breaking"><a href="//example.com/stories/3">Also a story</a></li>
+    <li><a href="//example.com/stories/4">Yet another story</a></li>
+    <li><a href="//example.com/stories/4">Awesome story</a></li>
+    <li class="breaking"><a href="//example.com/stories/5">Horrible story</a></li>
+</ul>
+<script type="application/dart">
+import 'dart:html';
+main() {
+  window.postMessage('done', '*');
+}
+</script>
+</body>
+</html>
diff --git a/pkg/polymer/example/component/news/test/test.dart b/pkg/polymer/example/component/news/test/test.dart
new file mode 100755
index 0000000..a4c98a0
--- /dev/null
+++ b/pkg/polymer/example/component/news/test/test.dart
@@ -0,0 +1,14 @@
+#!/usr/bin/env dart
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'package:polymer/testing/content_shell_test.dart';
+import 'package:unittest/compact_vm_config.dart';
+
+void main() {
+  useCompactVMConfiguration();
+  // Base directory, input, expected, output:
+  renderTests('..', '.', 'expected', 'out');
+}
diff --git a/pkg/polymer/example/component/news/web/index.html b/pkg/polymer/example/component/news/web/index.html
new file mode 100644
index 0000000..3354d9b
--- /dev/null
+++ b/pkg/polymer/example/component/news/web/index.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!--
+This example is from
+https://github.com/dglazkov/Web-Components-Polyfill/blob/master/samples/news
+-->
+<html>
+<head>
+    <title>Simple Web Components Example</title>
+    <link rel="import" href="news-component.html">
+    <script src='packages/polymer/boot.js'></script>
+</head>
+<body>
+<h1>Simple Web Components Example</h1>
+<ul is="x-news">
+    <li><a href="//example.com/stories/1">A story</a></li>
+    <li><a href="//example.com/stories/2">Another story</a></li>
+    <li class="breaking"><a href="//example.com/stories/3">Also a story</a></li>
+    <li><a href="//example.com/stories/4">Yet another story</a></li>
+    <li><a href="//example.com/stories/4">Awesome story</a></li>
+    <li class="breaking"><a href="//example.com/stories/5">Horrible story</a></li>
+</ul>
+  <script type="application/dart">main() {}</script>
+</body>
+</html>
diff --git a/pkg/polymer/example/component/news/web/news-component.html b/pkg/polymer/example/component/news/web/news-component.html
new file mode 100644
index 0000000..8e604d2
--- /dev/null
+++ b/pkg/polymer/example/component/news/web/news-component.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<!--
+This example is from
+https://github.com/dglazkov/Web-Components-Polyfill/blob/master/samples/news
+-->
+<html>
+<head>
+    <title>News Component</title>
+</head>
+<body>
+<polymer-element name="x-news" extends="ul">
+    <template>
+        <style scoped>
+            div.breaking {
+                color: Red;
+                font-size: 20px;
+                border: 1px dashed Purple;
+            }
+            div.other {
+                padding: 2px 0 0 0;
+                border: 1px solid Cyan;
+            }
+        </style>
+        <div class="breaking">
+            <h2>Breaking Stories</h2>
+            <ul>
+                <content select=".breaking"></content>
+            </ul>
+        </div>
+        <div class="other">
+            <h2>Other News</h2>
+            <ul>
+                <content></content>
+            </ul>
+        </div>
+    </template>
+    <script type="application/dart">
+      import 'package:polymer/polymer.dart';
+
+      class XNews extends PolymerElement {}
+
+      @initMethod
+      _init() {
+        registerPolymerElement('x-news', () => new XNews());
+      }
+    </script>
+</polymer-element>
+</body>
+</html>
diff --git a/pkg/polymer/example/scoped_style/index.html b/pkg/polymer/example/scoped_style/index.html
new file mode 100644
index 0000000..bc81e7a
--- /dev/null
+++ b/pkg/polymer/example/scoped_style/index.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Simple CSS Test</title>
+    <link rel="import" href="my_test.html">
+    <script src='packages/polymer/boot.js'></script>
+</head>
+<body>
+<style>
+  p { color: black;}
+</style>
+<p>outside of element, should be black</p>
+
+<my-test></my-test>
+</body>
+</html>
diff --git a/pkg/polymer/example/scoped_style/my_test.html b/pkg/polymer/example/scoped_style/my_test.html
new file mode 100644
index 0000000..2713a3f
--- /dev/null
+++ b/pkg/polymer/example/scoped_style/my_test.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Test Compopnent</title>
+</head>
+<body>
+<polymer-element name="my-test">
+  <template>
+    <style>
+      p { color: red;}
+    </style>
+    <p>Inside element, should be red</p>
+  </template>
+  <script type="application/dart">
+    import 'package:polymer/polymer.dart';
+
+    @CustomTag('my-test')
+    class MyTest extends PolymerElement {}
+  </script>
+</polymer-element>
+</body>
+</html>
diff --git a/pkg/polymer/lib/boot.js b/pkg/polymer/lib/boot.js
new file mode 100644
index 0000000..84bb489
--- /dev/null
+++ b/pkg/polymer/lib/boot.js
@@ -0,0 +1,158 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This script dynamically prepares a set of files to run polymer.dart. It uses
+// the html_import polyfill to search for all imported files, then
+// it inlines all <polymer-element> definitions on the top-level page (needed by
+// registerPolymerElement), and it removes script tags that appear inside
+// those tags. It finally rewrites the main entrypoint to call an initialization
+// function on each of the declared <polymer-elements>.
+//
+// This script is needed only when running polymer.dart in Dartium. It should be
+// removed by the polymer deployment commands.
+
+// As an example, given an input of this form:
+//   <polymer-element name="c1">
+//      <template></template>
+//      <script type="application/dart" src="url0.dart"></script>
+//   </polymer-element>
+//   <element name="c2">
+//      <template></template>
+//      <script type="application/dart">main() => { print('body2'); }</script>
+//   </element>
+//   <c1></c1>
+//   <c2></c2>
+//   <script type="application/dart" src="url2.dart"></script>
+//   <script src="packages/polymer/boot.js"></script>
+//
+// This script will simplifies the page as follows:
+//   <polymer-element name="c1">
+//      <template></template>
+//   </polymer-element>
+//   <polymer-element name="c2">
+//      <template></template>
+//   </polymer-element>
+//   <c1></c1>
+//   <c2></c2>
+//   <script type="application/dart">
+//     import 'url0.dart' as i0;
+//     import "data:application/dart;base64,CiAgICBtYWluKCkgewogICAgICBwcmludCgnYm9keTInKTsKICAgIH0KICAgIA==" as i1;
+//     import 'url2.dart' as i2;
+//     ...
+//     main() {
+//       // code that checks which libraries have a 'main' and invokes them.
+//       // practically equivalent to: i0._init(); i1._init(); i2.main();
+//     }
+//   </script>
+
+
+(function() {
+  // Only run in Dartium.
+  if (!navigator.webkitStartDart) {
+    // TODO(sigmund): rephrase when we split build.dart in two: analysis vs
+    // deploy pieces.
+    console.warn('boot.js only works in Dartium. Run the build.dart' +
+      ' tool to compile a depolyable JavaScript version')
+    return;
+  }
+  document.write(
+    '<script src="packages/html_import/html_import.min.js"></script>');
+
+  // Extract a Dart import URL from a script tag, which is the 'src' attribute
+  // of the script tag, or a data-url with the script contents for inlined code.
+  function getScriptUrl(script) {
+    var url = script.src;
+    if (url) {
+      // Normalize package: urls
+      var index = url.indexOf('packages/');
+      if (index == 0 || (index > 0 && url[index - 1] == '/')) {
+        url = "package:" + url.slice(index + 9);
+      }
+      return url;
+    } else {
+      // TODO(sigmund): investigate how to eliminate the warning in Dartium
+      // (changing to text/javascript hides the warning, but seems wrong).
+      return "data:application/dart;base64," + window.btoa(script.textContent);
+    }
+  }
+
+  // Moves <polymer-elements> from imported documents into the top-level page.
+  function inlinePolymerElements(content, ref, seen) {
+    if (!seen) seen = {};
+    var links = content.querySelectorAll('link[rel="import"]');
+    for (var i = 0; i < links.length; i++) {
+      var link = links[i].import;
+      if (seen[link.href]) continue;
+      seen[link.href] = link;
+      inlinePolymerElements(link.content, ref, seen);
+    }
+
+    if (content != document) { // no need to do anything for the top-level page
+      var elements = content.querySelectorAll('polymer-element');
+      for (var i = 0; i < elements.length; i++)  {
+        document.body.insertBefore(elements[i], ref);
+      }
+    }
+  }
+
+  // Creates a Dart program that imports [urls] and passes them to initPolymer
+  // (which in turn will invoke their main function, their methods marked with
+  // @initMethod, and register any custom tag labeled with @CustomTag).
+  function createMain(urls, mainUrl) {
+    var imports = Array(urls.length + 1);
+    for (var i = 0; i < urls.length; ++i) {
+      imports[i] = 'import "' + urls[i] + '" as i' + i + ';';
+    }
+    imports[urls.length] = 'import "package:polymer/polymer.dart" as polymer;';
+    var arg = urls.length == 0 ? '[]' :
+        ('[\n      "' + urls.join('",\n      "') + '"\n     ]');
+    return (imports.join('\n') +
+        '\n\nmain() {\n' +
+        '  polymer.initPolymer(' + arg + ');\n' +
+        '}\n');
+  }
+
+  // Finds all top-level <script> tags, and <script> tags in custom elements
+  // and merges them into a single entrypoint.
+  function mergeScripts() {
+    var scripts = document.getElementsByTagName("script");
+    var length = scripts.length;
+
+    var urls = [];
+    var toRemove = [];
+
+    // Collect the information we need to replace the script tags
+    for (var i = 0; i < length; ++i) {
+      var script = scripts[i];
+      if (script.type == "application/dart") {
+        urls.push(getScriptUrl(script));
+        toRemove.push(script);
+      }
+    }
+
+    toRemove.forEach(function (s) { s.parentNode.removeChild(s); });
+
+    // Append a new script tag that initializes everything.
+    var newScript = document.createElement('script');
+    newScript.type = "application/dart";
+    newScript.textContent = createMain(urls);
+    document.body.appendChild(newScript);
+  }
+
+  var alreadyRan = false;
+  window.addEventListener('HTMLImportsLoaded', function (e) {
+    if (alreadyRan) {
+      console.warn('HTMLImportsLoaded fired again.');
+      return;
+    }
+    alreadyRan = true;
+    var ref = document.body.children[0];
+    inlinePolymerElements(document, ref);
+    mergeScripts();
+    if (!navigator.webkitStartDart()) {
+      document.body.innerHTML = 'This build has expired. Please download a ' +
+          'new Dartium at http://www.dartlang.org/dartium/index.html';
+    }
+  });
+})();
diff --git a/pkg/polymer/lib/component_build.dart b/pkg/polymer/lib/component_build.dart
new file mode 100644
index 0000000..316124e
--- /dev/null
+++ b/pkg/polymer/lib/component_build.dart
@@ -0,0 +1,166 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Common logic to make it easy to create a `build.dart` for your project.
+ *
+ * The `build.dart` script is invoked automatically by the Editor whenever a
+ * file in the project changes. It must be placed in the root of a project
+ * (where pubspec.yaml lives) and should be named exactly 'build.dart'.
+ *
+ * A common `build.dart` would look as follows:
+ *
+ *     import 'dart:io';
+ *     import 'package:polymer/component_build.dart';
+ *
+ *     main() => build(new Options().arguments, ['web/index.html']);
+ */
+library build_utils;
+
+import 'dart:async';
+import 'dart:io';
+import 'dart:json' as json;
+import 'package:args/args.dart';
+
+import 'dwc.dart' as dwc;
+import 'src/utils.dart';
+import 'src/compiler_options.dart';
+
+/**
+ * Set up 'build.dart' to compile with the dart web components compiler every
+ * [entryPoints] listed. On clean commands, the directory where [entryPoints]
+ * live will be scanned for generated files to delete them.
+ */
+// TODO(jmesserly): we need a better way to automatically detect input files
+Future<List<dwc.CompilerResult>> build(List<String> arguments,
+    List<String> entryPoints,
+    {bool printTime: true, bool shouldPrint: true}) {
+  bool useColors = stdioType(stdout) == StdioType.TERMINAL;
+  return asyncTime('Total time', () {
+    var args = _processArgs(arguments);
+    var tasks = new FutureGroup();
+    var lastTask = new Future.value(null);
+    tasks.add(lastTask);
+
+    var changedFiles = args["changed"];
+    var removedFiles = args["removed"];
+    var cleanBuild = args["clean"];
+    var machineFormat = args["machine"];
+    // Also trigger a full build if the script was run from the command line
+    // with no arguments
+    var fullBuild = args["full"] || (!machineFormat && changedFiles.isEmpty &&
+        removedFiles.isEmpty && !cleanBuild);
+
+    var options = CompilerOptions.parse(args.rest, checkUsage: false);
+
+    // [outputOnlyDirs] contains directories known to only have output files.
+    // When outputDir is not specified, we create a new directory which only
+    // contains output files. If options.outputDir is specified, we don't know
+    // if the output directory may also have input files. In which case,
+    // [_handleCleanCommand] and [_isInputFile] are more conservative.
+    //
+    // TODO(sigmund): get rid of this. Instead, use the compiler to understand
+    // which files are input or output files.
+    var outputOnlyDirs = options.outputDir == null ? []
+        : entryPoints.map((e) => _outDir(e)).toList();
+
+    if (cleanBuild) {
+      _handleCleanCommand(outputOnlyDirs);
+    } else if (fullBuild
+        || changedFiles.any((f) => _isInputFile(f, outputOnlyDirs))
+        || removedFiles.any((f) => _isInputFile(f, outputOnlyDirs))) {
+      for (var file in entryPoints) {
+        var dwcArgs = new List.from(args.rest);
+        if (machineFormat) dwcArgs.add('--json_format');
+        if (!useColors) dwcArgs.add('--no-colors');
+        // We'll set 'out/' as the out folder, unless an output directory was
+        // already specified in the command line.
+        if (options.outputDir == null) dwcArgs.addAll(['-o', _outDir(file)]);
+        dwcArgs.add(file);
+        // Chain tasks to that we run one at a time.
+        lastTask = lastTask.then((_) => dwc.run(dwcArgs, printTime: printTime,
+            shouldPrint: shouldPrint));
+        if (machineFormat) {
+          lastTask = lastTask.then((res) {
+            appendMessage(Map jsonMessage) {
+              var message = json.stringify([jsonMessage]);
+              if (shouldPrint) print(message);
+              res.messages.add(message);
+            }
+            // Print for the Editor messages about mappings and generated files
+            res.outputs.forEach((out, input) {
+              if (out.endsWith(".html") && input != null) {
+                appendMessage({
+                  "method": "mapping",
+                  "params": {"from": input, "to": out},
+                });
+              }
+              appendMessage({"method": "generated", "params": {"file": out}});
+            });
+            return res;
+          });
+        }
+        tasks.add(lastTask);
+      }
+    }
+    return tasks.future.then((r) => r.where((v) => v != null));
+  }, printTime: printTime, useColors: useColors);
+}
+
+String _outDir(String file) => path.join(path.dirname(file), 'out');
+
+/** Tell whether [filePath] is a generated file. */
+bool _isGeneratedFile(String filePath, List<String> outputOnlyDirs) {
+  var dirPrefix = path.dirname(filePath);
+  for (var outDir in outputOnlyDirs) {
+    if (dirPrefix.startsWith(outDir)) return true;
+  }
+  return path.basename(filePath).startsWith('_');
+}
+
+/** Tell whether [filePath] is an input file. */
+bool _isInputFile(String filePath, List<String> outputOnlyDirs) {
+  var ext = path.extension(filePath);
+  return (ext == '.dart' || ext == '.html') &&
+      !_isGeneratedFile(filePath, outputOnlyDirs);
+}
+
+/**
+ * Delete all generated files. Currently we only delete files under directories
+ * that are known to contain only generated code.
+ */
+void _handleCleanCommand(List<String> outputOnlyDirs) {
+  for (var dirPath in outputOnlyDirs) {
+    var dir = new Directory(dirPath);
+    if (!dir.existsSync()) continue;
+    for (var f in dir.listSync(recursive: false)) {
+      if (f is File && _isGeneratedFile(f.path, outputOnlyDirs)) f.deleteSync();
+    }
+  }
+}
+
+/** Process the command-line arguments. */
+ArgResults _processArgs(List<String> arguments) {
+  var parser = new ArgParser()
+    ..addOption("changed", help: "the file has changed since the last build",
+        allowMultiple: true)
+    ..addOption("removed", help: "the file was removed since the last build",
+        allowMultiple: true)
+    ..addFlag("clean", negatable: false, help: "remove any build artifacts")
+    ..addFlag("full", negatable: false, help: "perform a full build")
+    ..addFlag("machine", negatable: false,
+        help: "produce warnings in a machine parseable format")
+    ..addFlag("help", abbr: 'h',
+        negatable: false, help: "displays this help and exit");
+  var args = parser.parse(arguments);
+  if (args["help"]) {
+    print('A build script that invokes the web-ui compiler (dwc).');
+    print('Usage: dart build.dart [options] [-- [dwc-options]]');
+    print('\nThese are valid options expected by build.dart:');
+    print(parser.getUsage());
+    print('\nThese are valid options expected by dwc:');
+    dwc.run(['-h']).then((_) => exit(0));
+  }
+  return args;
+}
diff --git a/pkg/polymer/lib/dwc.dart b/pkg/polymer/lib/dwc.dart
new file mode 100755
index 0000000..b70f29b
--- /dev/null
+++ b/pkg/polymer/lib/dwc.dart
@@ -0,0 +1,198 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/** The entry point to the compiler. Used to implement `bin/dwc.dart`. */
+library dwc;
+
+import 'dart:async';
+import 'dart:io';
+import 'package:logging/logging.dart' show Level;
+
+import 'src/compiler.dart';
+import 'src/file_system.dart';
+import 'src/file_system/console.dart';
+import 'src/files.dart';
+import 'src/messages.dart';
+import 'src/compiler_options.dart';
+import 'src/utils.dart';
+
+FileSystem _fileSystem;
+
+void main() {
+  run(new Options().arguments).then((result) {
+    exit(result.success ? 0 : 1);
+  });
+}
+
+/** Contains the result of a compiler run. */
+class CompilerResult {
+  final bool success;
+
+  /** Map of output path to source, if there is one */
+  final Map<String, String> outputs;
+
+  /** List of files read during compilation */
+  final List<String> inputs;
+
+  final List<String> messages;
+  String bootstrapFile;
+
+  CompilerResult([this.success = true,
+                  this.outputs,
+                  this.inputs,
+                  this.messages = const [],
+                  this.bootstrapFile]);
+
+  factory CompilerResult._(bool success,
+      List<String> messages, List<OutputFile> outputs, List<SourceFile> files) {
+    var file;
+    var outs = new Map<String, String>();
+    for (var out in outputs) {
+      if (path.basename(out.path).endsWith('_bootstrap.dart')) {
+        file = out.path;
+      }
+      outs[out.path] = out.source;
+    }
+    var inputs = files.map((f) => f.path).toList();
+    return new CompilerResult(success, outs, inputs, messages, file);
+  }
+}
+
+/**
+ * Runs the web components compiler with the command-line options in [args].
+ * See [CompilerOptions] for the definition of valid arguments.
+ */
+// TODO(jmesserly): fix this to return a proper exit code
+// TODO(justinfagnani): return messages in the result
+Future<CompilerResult> run(List<String> args, {bool printTime,
+    bool shouldPrint: true}) {
+  var options = CompilerOptions.parse(args);
+  if (options == null) return new Future.value(new CompilerResult());
+  if (printTime == null) printTime = options.verbose;
+
+  _fileSystem = new ConsoleFileSystem();
+  var messages = new Messages(options: options, shouldPrint: shouldPrint);
+
+  return asyncTime('Total time spent on ${options.inputFile}', () {
+    var compiler = new Compiler(_fileSystem, options, messages);
+    var res;
+    return compiler.run()
+      .then((_) {
+        var success = messages.messages.every((m) => m.level != Level.SEVERE);
+        var msgs = options.jsonFormat
+            ? messages.messages.map((m) => m.toJson())
+            : messages.messages.map((m) => m.toString());
+        res = new CompilerResult._(success, msgs.toList(),
+            compiler.output, compiler.files);
+      })
+      .then((_) => _symlinkPubPackages(res, options, messages))
+      .then((_) => _emitFiles(compiler.output, options.clean))
+      .then((_) => res);
+  }, printTime: printTime, useColors: options.useColors);
+}
+
+Future _emitFiles(List<OutputFile> outputs, bool clean) {
+  outputs.forEach((f) => _writeFile(f.path, f.contents, clean));
+  return _fileSystem.flush();
+}
+
+void _writeFile(String filePath, String contents, bool clean) {
+  if (clean) {
+    File fileOut = new File(filePath);
+    if (fileOut.existsSync()) {
+      fileOut.deleteSync();
+    }
+  } else {
+    _createIfNeeded(path.dirname(filePath));
+    _fileSystem.writeString(filePath, contents);
+  }
+}
+
+void _createIfNeeded(String outdir) {
+  if (outdir.isEmpty) return;
+  var outDirectory = new Directory(outdir);
+  if (!outDirectory.existsSync()) {
+    _createIfNeeded(path.dirname(outdir));
+    outDirectory.createSync();
+  }
+}
+
+/**
+ * Creates a symlink to the pub packages directory in the output location. The
+ * returned future completes when the symlink was created (or immediately if it
+ * already exists).
+ */
+Future _symlinkPubPackages(CompilerResult result, CompilerOptions options,
+    Messages messages) {
+  if (options.outputDir == null || result.bootstrapFile == null
+      || options.packageRoot != null) {
+    // We don't need to copy the packages directory if the output was generated
+    // in-place where the input lives, if the compiler was called without an
+    // entry-point file, or if the compiler was called with a package-root
+    // option.
+    return new Future.value(null);
+  }
+
+  var linkDir = path.dirname(result.bootstrapFile);
+  _createIfNeeded(linkDir);
+  var linkPath = path.join(linkDir, 'packages');
+  // A resolved symlink works like a directory
+  // TODO(sigmund): replace this with something smarter once we have good
+  // symlink support in dart:io
+  if (new Directory(linkPath).existsSync()) {
+    // Packages directory already exists.
+    return new Future.value(null);
+  }
+
+  // A broken symlink works like a file
+  var toFile = new File(linkPath);
+  if (toFile.existsSync()) {
+    toFile.deleteSync();
+  }
+
+  var targetPath = path.join(path.dirname(options.inputFile), 'packages');
+  // [fullPathSync] will canonicalize the path, resolving any symlinks.
+  // TODO(sigmund): once it's possible in dart:io, we just want to use a full
+  // path, but not necessarily resolve symlinks.
+  var target = new File(targetPath).fullPathSync().toString();
+  return createSymlink(target, linkPath, messages: messages);
+}
+
+
+// TODO(jmesserly): this code was taken from Pub's io library.
+// Added error handling and don't return the file result, to match the code
+// we had previously. Also "target" and "link" only accept strings. And inlined
+// the relevant parts of runProcess. Note that it uses "cmd" to get the path
+// on Windows.
+/**
+ * Creates a new symlink that creates an alias of [target] at [link], both of
+ * which can be a [String], [File], or [Directory]. Returns a [Future] which
+ * completes to the symlink file (i.e. [link]).
+ */
+Future createSymlink(String target, String link, {Messages messages: null}) {
+  messages = messages == null? new Messages.silent() : messages;
+  var command = 'ln';
+  var args = ['-s', target, link];
+
+  if (Platform.operatingSystem == 'windows') {
+    // Call mklink on Windows to create an NTFS junction point. Only works on
+    // Vista or later. (Junction points are available earlier, but the "mklink"
+    // command is not.) I'm using a junction point (/j) here instead of a soft
+    // link (/d) because the latter requires some privilege shenanigans that
+    // I'm not sure how to specify from the command line.
+    command = 'cmd';
+    args = ['/c', 'mklink', '/j', link, target];
+  }
+
+  return Process.run(command, args).then((result) {
+    if (result.exitCode != 0) {
+      var details = 'subprocess stdout:\n${result.stdout}\n'
+                    'subprocess stderr:\n${result.stderr}';
+      messages.error(
+        'unable to create symlink\n target: $target\n link:$link\n$details',
+        null);
+    }
+    return null;
+  });
+}
diff --git a/pkg/polymer/lib/observe.dart b/pkg/polymer/lib/observe.dart
new file mode 100644
index 0000000..0a02a90
--- /dev/null
+++ b/pkg/polymer/lib/observe.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 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.
+
+/**
+ * Helpers for observable objects.
+ * Intended for use with `package:observe`.
+ */
+library polymer.observe;
+
+import 'dart:async';
+import 'package:observe/observe.dart';
+
+const _VALUE = const Symbol('value');
+
+/**
+ * Forwards an observable property from one object to another. For example:
+ *
+ *     class MyModel extends ObservableBase {
+ *       StreamSubscription _sub;
+ *       MyOtherModel _otherModel;
+ *
+ *       MyModel() {
+ *         ...
+ *         _sub = bindProperty(_otherModel, const Symbol('value'),
+ *             () => notifyProperty(this, const Symbol('prop'));
+ *       }
+ *
+ *       String get prop => _otherModel.value;
+ *       set prop(String value) { _otherModel.value = value; }
+ *     }
+ *
+ * See also [notifyProperty].
+ */
+StreamSubscription bindProperty(Observable source, Symbol sourceName,
+    void callback()) {
+  return source.changes.listen((records) {
+    for (var record in records) {
+      if (record.changes(sourceName)) {
+        callback();
+      }
+    }
+  });
+}
+
+/**
+ * Notify the property change. Shorthand for:
+ *
+ *     target.notifyChange(new PropertyChangeRecord(targetName));
+ */
+void notifyProperty(Observable target, Symbol targetName) {
+  target.notifyChange(new PropertyChangeRecord(targetName));
+}
+
+
+// Inspired by ArrayReduction at:
+// https://raw.github.com/rafaelw/ChangeSummary/master/util/array_reduction.js
+// The main difference is we support anything on the rich Dart Iterable API.
+
+/**
+ * Observes a path starting from each item in the list.
+ */
+class ListPathObserver<E, P> extends ChangeNotifierBase {
+  final ObservableList<E> list;
+  final String _itemPath;
+  final List<PathObserver> _observers = <PathObserver>[];
+  final List<StreamSubscription> _subs = <StreamSubscription>[];
+  StreamSubscription _sub;
+  bool _scheduled = false;
+  Iterable<P> _value;
+
+  ListPathObserver(this.list, String path)
+      : _itemPath = path {
+
+    _sub = list.changes.listen((records) {
+      for (var record in records) {
+        if (record is ListChangeRecord) {
+          _observeItems(record.addedCount - record.removedCount);
+        }
+      }
+      _scheduleReduce(null);
+    });
+
+    _observeItems(list.length);
+    _reduce();
+  }
+
+  Iterable<P> get value => _value;
+
+  void dispose() {
+    if (_sub != null) _sub.cancel();
+    _subs.forEach((s) => s.cancel());
+    _subs.clear();
+  }
+
+  void _reduce() {
+    _scheduled = false;
+    _value = _observers.map((o) => o.value);
+    notifyChange(new PropertyChangeRecord(_VALUE));
+  }
+
+  void _scheduleReduce(_) {
+    if (_scheduled) return;
+    _scheduled = true;
+    runAsync(_reduce);
+  }
+
+  void _observeItems(int lengthAdjust) {
+    if (lengthAdjust > 0) {
+      for (int i = 0; i < lengthAdjust; i++) {
+        int len = _observers.length;
+        var pathObs = new PathObserver(list, '$len.$_itemPath');
+        _subs.add(pathObs.changes.listen(_scheduleReduce));
+        _observers.add(pathObs);
+      }
+    } else if (lengthAdjust < 0) {
+      for (int i = 0; i < -lengthAdjust; i++) {
+        _subs.removeLast().cancel();
+      }
+      int len = _observers.length;
+      _observers.removeRange(len + lengthAdjust, len);
+    }
+  }
+}
diff --git a/pkg/polymer/lib/observe_html.dart b/pkg/polymer/lib/observe_html.dart
new file mode 100644
index 0000000..7280b0e
--- /dev/null
+++ b/pkg/polymer/lib/observe_html.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.
+
+// TODO(jmesserly): can we handle this more elegantly?
+// In general, it seems like we want a convenient way to take a Stream plus a
+// getter and convert this into an Observable.
+
+/** Helpers for exposing dart:html as observable data. */
+library polymer.observe_html;
+
+import 'dart:html';
+import 'package:observe/observe.dart';
+
+/** An observable version of [window.location.hash]. */
+final ObservableLocationHash windowLocation = new ObservableLocationHash._();
+
+class ObservableLocationHash extends ChangeNotifierBase {
+  ObservableLocationHash._() {
+    // listen on changes to #hash in the URL
+    // Note: listen on both popState and hashChange, because IE9 doesn't support
+    // history API. See http://dartbug.com/5483
+    // TODO(jmesserly): only listen to these if someone is listening to our
+    // changes.
+    window.onHashChange.listen(_notifyHashChange);
+    window.onPopState.listen(_notifyHashChange);
+  }
+
+  String get hash => window.location.hash;
+
+  /**
+   * Pushes a new URL state, similar to the affect of clicking a link.
+   * Has no effect if the [value] already equals [window.location.hash].
+   */
+  void set hash(String value) {
+    if (value == hash) return;
+
+    window.history.pushState(null, '', value);
+    _notifyHashChange(null);
+  }
+
+  void _notifyHashChange(_) {
+    notifyChange(new PropertyChangeRecord(const Symbol('hash')));
+  }
+}
+
+/** Add or remove CSS class [className] based on the [value]. */
+void updateCssClass(Element element, String className, bool value) {
+  if (value == true) {
+    element.classes.add(className);
+  } else {
+    element.classes.remove(className);
+  }
+}
+
+/** Bind a CSS class to the observable [object] and property [path]. */
+PathObserver bindCssClass(Element element, String className,
+    Observable object, String path) {
+
+  return new PathObserver(object, path)..bindSync((value) {
+    updateCssClass(element, className, value);
+  });
+}
diff --git a/pkg/polymer/lib/polymer.dart b/pkg/polymer/lib/polymer.dart
new file mode 100644
index 0000000..575619b
--- /dev/null
+++ b/pkg/polymer/lib/polymer.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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 exports all of the commonly used functions and types for
+ * building UI's.
+ *
+ * See this article for more information:
+ * <http://www.dartlang.org/articles/dart-web-components/>.
+ */
+library polymer;
+
+import 'dart:async';
+import 'dart:mirrors';
+
+import 'package:mdv/mdv.dart' as mdv;
+import 'package:observe/src/microtask.dart';
+import 'package:path/path.dart' as path;
+import 'polymer_element.dart' show registerPolymerElement;
+
+export 'package:custom_element/custom_element.dart';
+export 'package:observe/observe.dart';
+export 'package:observe/src/microtask.dart';
+
+export 'observe.dart';
+export 'observe_html.dart';
+export 'polymer_element.dart';
+export 'safe_html.dart';
+
+
+/** Annotation used to automatically register polymer elements. */
+class CustomTag {
+  final String tagName;
+  const CustomTag(this.tagName);
+}
+
+/**
+ * Metadata used to label static or top-level methods that are called
+ * automatically when loading the library of a custom element.
+ */
+const initMethod = const _InitMethodAnnotation();
+
+/**
+ * Initializes a polymer application as follows:
+ *   * set up up polling for observable changes
+ *   *  initialize MDV
+ *   *  for each library in [libraries], register custom elements labeled with
+ *      [CustomTag] and invoke the initialization method on it.
+ *
+ * The initialization on each library is either a method named `main` or
+ * a top-level function and annotated with [initMethod].
+ *
+ * The urls in [libraries] can be absolute or relative to [srcUrl].
+ */
+void initPolymer(List<String> libraries, [String srcUrl]) {
+  wrapMicrotask(() {
+    // DOM events don't yet go through microtasks, so we catch those here.
+    new Timer.periodic(new Duration(milliseconds: 125),
+        (_) => performMicrotaskCheckpoint());
+
+    // TODO(jmesserly): mdv should use initMdv instead of mdv.initialize.
+    mdv.initialize();
+    for (var lib in libraries) {
+      _loadLibrary(lib, srcUrl);
+    }
+  })();
+}
+
+/** All libraries in the current isolate. */
+final _libs = currentMirrorSystem().libraries;
+
+/**
+ * Reads the library at [uriString] (which can be an absolute URI or a relative
+ * URI from [srcUrl]), and:
+ *
+ *   * If present, invokes `main`.
+ *
+ *   * If present, invokes any top-level and static functions marked
+ *     with the [initMethod] annotation (in the order they appear).
+ *
+ *   * Registers any [PolymerElement] that is marked with the [CustomTag]
+ *     annotation.
+ */
+void _loadLibrary(String uriString, [String srcUrl]) {
+  var uri = Uri.parse(uriString);
+  if (uri.scheme == '' && srcUrl != null) {
+    uri = Uri.parse(path.normalize(path.join(path.dirname(srcUrl), uriString)));
+  }
+  var lib = _libs[uri];
+  if (lib == null) {
+    print('warning: $uri library not found');
+    return;
+  }
+
+  // Invoke `main`, if present.
+  if (lib.functions[const Symbol('main')] != null) {
+    lib.invoke(const Symbol('main'), const []);
+  }
+
+  // Search top-level functions marked with @initMethod
+  for (var f in lib.functions.values) {
+    _maybeInvoke(lib, f);
+  }
+
+  for (var c in lib.classes.values) {
+    // Search for @CustomTag on classes
+    for (var m in c.metadata) {
+      var meta = m.reflectee;
+      if (meta is CustomTag) {
+        registerPolymerElement(meta.tagName,
+            () => c.newInstance(const Symbol(''), const []).reflectee);
+      }
+    }
+
+    // TODO(sigmund): check also static methods marked with @initMethod.
+    // This is blocked on two bugs:
+    //  - dartbug.com/12133 (static methods are incorrectly listed as top-level
+    //    in dart2js, so they end up being called twice)
+    //  - dartbug.com/12134 (sometimes "method.metadata" throws an exception,
+    //    we could wrap and hide those exceptions, but it's not ideal).
+  }
+}
+
+void _maybeInvoke(ObjectMirror obj, MethodMirror method) {
+  var annotationFound = false;
+  for (var meta in method.metadata) {
+    if (identical(meta.reflectee, initMethod)) {
+      annotationFound = true;
+      break;
+    }
+  }
+  if (!annotationFound) return;
+  if (!method.isStatic) {
+    print("warning: methods marked with @initMethod should be static,"
+        " ${method.simpleName} is not.");
+    return;
+  }
+  if (!method.parameters.where((p) => !p.isOptional).isEmpty) {
+    print("warning: methods marked with @initMethod should take no "
+        "arguments, ${method.simpleName} expects some.");
+    return;
+  }
+  obj.invoke(method.simpleName, const []);
+}
+
+class _InitMethodAnnotation {
+  const _InitMethodAnnotation();
+}
diff --git a/pkg/polymer/lib/polymer_element.dart b/pkg/polymer/lib/polymer_element.dart
new file mode 100644
index 0000000..297625e
--- /dev/null
+++ b/pkg/polymer/lib/polymer_element.dart
@@ -0,0 +1,566 @@
+// Copyright (c) 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 polymer.polymer_element;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:mirrors';
+import 'dart:js' as dartJs;
+
+import 'package:custom_element/custom_element.dart';
+import 'package:js/js.dart' as js;
+import 'package:mdv/mdv.dart' show NodeBinding;
+import 'package:observe/observe.dart';
+import 'package:observe/src/microtask.dart';
+import 'package:polymer_expressions/polymer_expressions.dart';
+
+import 'src/utils_observe.dart' show toCamelCase, toHyphenedName;
+
+/**
+ * Registers a [PolymerElement]. This is similar to [registerCustomElement]
+ * but it is designed to work with the `<element>` element and adds additional
+ * features.
+ */
+void registerPolymerElement(String localName, PolymerElement create()) {
+  registerCustomElement(localName, () => create().._initialize(localName));
+}
+
+/**
+ * *Warning*: many features of this class are not fully implemented.
+ *
+ * The base class for Polymer elements. It provides convience features on top
+ * of the custom elements web standard.
+ *
+ * Currently it supports publishing attributes via:
+ *
+ *     <element name="..." attributes="foo, bar, baz">
+ *
+ * Any attribute published this way can be used in a data binding expression,
+ * and it should contain a corresponding DOM field.
+ *
+ * *Warning*: due to dart2js mirror limititations, the mapping from HTML
+ * attribute to element property is a conversion from `dash-separated-words`
+ * to camelCase, rather than searching for a property with the same name.
+ */
+// TODO(jmesserly): fix the dash-separated-words issue. Polymer uses lowercase.
+class PolymerElement extends CustomElement with _EventsMixin {
+  // This is a partial port of:
+  // https://github.com/Polymer/polymer/blob/stable/src/attrs.js
+  // https://github.com/Polymer/polymer/blob/stable/src/bindProperties.js
+  // https://github.com/Polymer/polymer/blob/7936ff8/src/declaration/events.js
+  // https://github.com/Polymer/polymer/blob/7936ff8/src/instance/events.js
+  // TODO(jmesserly): we still need to port more of the functionality
+
+  /// The one syntax to rule them all.
+  static BindingDelegate _polymerSyntax = new PolymerExpressions();
+  // TODO(sigmund): delete. The next line is only added to avoid warnings from
+  // the analyzer (see http://dartbug.com/11672)
+  Element get host => super.host;
+
+  bool get applyAuthorStyles => false;
+  bool get resetStyleInheritance => false;
+
+  /**
+   * The declaration of this polymer-element, used to extract template contents
+   * and other information.
+   */
+  static Map<String, Element> _declarations = {};
+  static Element getDeclaration(String localName) {
+    if (localName == null) return null;
+    var element = _declarations[localName];
+    if (element == null) {
+      element = document.query('polymer-element[name="$localName"]');
+      _declarations[localName] = element;
+    }
+    return element;
+  }
+
+  Map<String, PathObserver> _publishedAttrs;
+  Map<String, StreamSubscription> _bindings;
+  final List<String> _localNames = [];
+
+  void _initialize(String localName) {
+    if (localName == null) return;
+
+    var declaration = getDeclaration(localName);
+    if (declaration == null) return;
+
+    if (declaration.attributes['extends'] != null) {
+      var base = declaration.attributes['extends'];
+      // Skip normal tags, only initialize parent custom elements.
+      if (base.contains('-')) _initialize(base);
+    }
+
+    _parseHostEvents(declaration);
+    _parseLocalEvents(declaration);
+    _publishAttributes(declaration);
+    _localNames.add(localName);
+  }
+
+  void _publishAttributes(elementElement) {
+    _bindings = {};
+    _publishedAttrs = {};
+
+    var attrs = elementElement.attributes['attributes'];
+    if (attrs != null) {
+      // attributes='a b c' or attributes='a,b,c'
+      for (var name in attrs.split(attrs.contains(',') ? ',' : ' ')) {
+        name = name.trim();
+
+        // TODO(jmesserly): PathObserver is overkill here; it helps avoid
+        // "new Symbol" and other mirrors-related warnings.
+        _publishedAttrs[name] = new PathObserver(this, toCamelCase(name));
+      }
+    }
+  }
+
+  void created() {
+    // TODO(jmesserly): this breaks until we get some kind of type conversion.
+    // _publishedAttrs.forEach((name, propObserver) {
+    // var value = attributes[name];
+    //   if (value != null) propObserver.value = value;
+    // });
+    _initShadowRoot();
+    _addHostListeners();
+  }
+
+  /**
+   * Creates the document fragment to use for each instance of the custom
+   * element, given the `<template>` node. By default this is equivalent to:
+   *
+   *     template.createInstance(this, polymerSyntax);
+   *
+   * Where polymerSyntax is a singleton `PolymerExpressions` instance from the
+   * [polymer_expressions](https://pub.dartlang.org/packages/polymer_expressions)
+   * package.
+   *
+   * You can override this method to change the instantiation behavior of the
+   * template, for example to use a different data-binding syntax.
+   */
+  DocumentFragment instanceTemplate(Element template) =>
+      template.createInstance(this, _polymerSyntax);
+
+  void _initShadowRoot() {
+    for (var localName in _localNames) {
+      var declaration = getDeclaration(localName);
+      var root = createShadowRoot(localName);
+      _addInstanceListeners(root, localName);
+
+      root.applyAuthorStyles = applyAuthorStyles;
+      root.resetStyleInheritance = resetStyleInheritance;
+
+      var templateNode = declaration.children.firstWhere(
+          (n) => n.localName == 'template', orElse: () => null);
+      if (templateNode == null) return;
+
+      // Create the contents of the element's ShadowRoot, and add them.
+      root.nodes.add(instanceTemplate(templateNode));
+
+      var extendsName = declaration.attributes['extends'];
+      _shimCss(root, localName, extendsName);
+    }
+  }
+
+  NodeBinding createBinding(String name, model, String path) {
+    var propObserver = _publishedAttrs[name];
+    if (propObserver != null) {
+      return new _PolymerBinding(this, name, model, path, propObserver);
+    }
+    return super.createBinding(name, model, path);
+  }
+
+  /**
+   * Using Polymer's platform/src/ShadowCSS.js passing the style tag's content.
+   */
+  void _shimCss(ShadowRoot root, String localName, String extendsName) {
+    // 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
+    //              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; }
+
+    var platform = js.context["Platform"];
+    if (platform == null) return;
+    var shadowCss = platform.ShadowCSS;
+    if (shadowCss == null) return;
+
+    // TODO(terry): Remove calls to shimShadowDOMStyling2 and replace with
+    //              shimShadowDOMStyling when we support unwrapping dart:html
+    //              Element to a JS DOM node.
+    var shimShadowDOMStyling2 = shadowCss.shimShadowDOMStyling2;
+    if (shimShadowDOMStyling2 == null) return;
+    var style = root.query('style');
+    if (style == null) return;
+    var scopedCSS = shimShadowDOMStyling2(style.text, localName);
+
+    // TODO(terry): Remove when shimShadowDOMStyling is called we don't need to
+    //              replace original CSS with scoped CSS shimShadowDOMStyling
+    //              does that.
+    style.text = scopedCSS;
+  }
+}
+
+class _PolymerBinding extends NodeBinding {
+  final PathObserver _publishedAttr;
+
+  _PolymerBinding(node, property, model, path, PathObserver this._publishedAttr)
+      : super(node, property, model, path);
+
+  void boundValueChanged(newValue) {
+    _publishedAttr.value = newValue;
+  }
+}
+
+/**
+ * Polymer features to handle the syntactic sugar on-* to declare to
+ * automatically map event handlers to instance methods of the [PolymerElement].
+ * This mixin is a port of:
+ * https://github.com/Polymer/polymer/blob/7936ff8/src/declaration/events.js
+ * https://github.com/Polymer/polymer/blob/7936ff8/src/instance/events.js
+ */
+abstract class _EventsMixin {
+  // TODO(sigmund): implement the Dart equivalent of 'inheritDelegates'
+  // Notes about differences in the implementation below:
+  //  - _templateDelegates: polymer stores the template delegates directly on
+  //    the template node (see in parseLocalEvents: 't.delegates = {}'). Here we
+  //    simply use a separate map, where keys are the name of the
+  //    custom-element.
+  //  - _listenLocal we return true/false and propagate that up, JS
+  //    implementation does't forward the return value.
+  //  - we don't keep the side-table (weak hash map) of unhandled events (see
+  //    handleIfNotHandled)
+  //  - we don't use event.type to dispatch events, instead we save the event
+  //    name with the event listeners. We do so to avoid translating back and
+  //    forth between Dom and Dart event names.
+
+  // ---------------------------------------------------------------------------
+  // The following section was ported from:
+  // https://github.com/Polymer/polymer/blob/7936ff8/src/declaration/events.js
+  // ---------------------------------------------------------------------------
+
+  /** Maps event names and their associated method in the element class. */
+  final Map<String, String> _delegates = {};
+
+  /** Expected events per element node. */
+  // TODO(sigmund): investigate whether we need more than 1 set of local events
+  // per element (why does the js implementation stores 1 per template node?)
+  final Map<String, Set<String>> _templateDelegates =
+      new Map<String, Set<String>>();
+
+  /** [host] is needed by this mixin, but not defined here. */
+  Element get host;
+
+  /** Attribute prefix used for declarative event handlers. */
+  static const _eventPrefix = 'on-';
+
+  /** Whether an attribute declares an event. */
+  static bool _isEvent(String attr) => attr.startsWith(_eventPrefix);
+
+  /** Extracts events from the element tag attributes. */
+  void _parseHostEvents(elementElement) {
+    for (var attr in elementElement.attributes.keys.where(_isEvent)) {
+      _delegates[toCamelCase(attr)] = elementElement.attributes[attr];
+    }
+  }
+
+  /** Extracts events under the element's <template>. */
+  void _parseLocalEvents(elementElement) {
+    var name = elementElement.attributes["name"];
+    if (name == null) return;
+    var events = null;
+    for (var template in elementElement.queryAll('template')) {
+      var content = template.content;
+      if (content != null) {
+        for (var child in content.children) {
+          events = _accumulateEvents(child, events);
+        }
+      }
+    }
+    if (events != null) {
+      _templateDelegates[name] = events;
+    }
+  }
+
+  /** Returns all events names listened by [element] and it's children. */
+  static Set<String> _accumulateEvents(Element element, [Set<String> events]) {
+    events = events == null ? new Set<String>() : events;
+
+    // from: accumulateAttributeEvents, accumulateEvent
+    events.addAll(element.attributes.keys.where(_isEvent).map(toCamelCase));
+
+    // from: accumulateChildEvents
+    for (var child in element.children) {
+      _accumulateEvents(child, events);
+    }
+
+    // from: accumulateTemplatedEvents
+    if (element.isTemplate) {
+      var content = element.content;
+      if (content != null) {
+        for (var child in content.children) {
+          _accumulateEvents(child, events);
+        }
+      }
+    }
+    return events;
+  }
+
+  // ---------------------------------------------------------------------------
+  // The following section was ported from:
+  // https://github.com/Polymer/polymer/blob/7936ff8/src/instance/events.js
+  // ---------------------------------------------------------------------------
+
+  /** Attaches event listeners on the [host] element. */
+  void _addHostListeners() {
+    for (var eventName in _delegates.keys) {
+      _addNodeListener(host, eventName,
+          (e) => _hostEventListener(eventName, e));
+    }
+  }
+
+  void _addNodeListener(node, String onEvent, Function listener) {
+    // If [node] is an element (typically when listening for host events) we
+    // use directly the '.onFoo' event stream of the element instance.
+    if (node is Element) {
+      reflect(node).getField(new Symbol(onEvent)).reflectee.listen(listener);
+      return;
+    }
+
+    // When [node] is not an element, most commonly when [node] is the
+    // shadow-root of the polymer-element, we find the appropriate static event
+    // stream providers and attach it to [node].
+    var eventProvider = _eventStreamProviders[onEvent];
+    if (eventProvider != null) {
+      eventProvider.forTarget(node).listen(listener);
+      return;
+    }
+
+    // When no provider is available, mainly because of custom-events, we use
+    // the underlying event listeners from the DOM.
+    var eventName = onEvent.substring(2).toLowerCase(); // onOneTwo => onetwo
+    // Most events names in Dart match those in JS in lowercase except for some
+    // few events listed in this map. We expect these cases to be handled above,
+    // but just in case we include them as a safety net here.
+    var jsNameFixes = const {
+      'animationend': 'webkitAnimationEnd',
+      'animationiteration': 'webkitAnimationIteration',
+      'animationstart': 'webkitAnimationStart',
+      'doubleclick': 'dblclick',
+      'fullscreenchange': 'webkitfullscreenchange',
+      'fullscreenerror': 'webkitfullscreenerror',
+      'keyadded': 'webkitkeyadded',
+      'keyerror': 'webkitkeyerror',
+      'keymessage': 'webkitkeymessage',
+      'needkey': 'webkitneedkey',
+      'speechchange': 'webkitSpeechChange',
+    };
+    var fixedName = jsNameFixes[eventName];
+    node.on[fixedName != null ? fixedName : eventName].listen(listener);
+  }
+
+  void _addInstanceListeners(ShadowRoot root, String elementName) {
+    var events = _templateDelegates[elementName];
+    if (events == null) return;
+    for (var eventName in events) {
+      _addNodeListener(root, eventName,
+          (e) => _instanceEventListener(eventName, e));
+    }
+  }
+
+  void _hostEventListener(String eventName, Event event) {
+    var method = _delegates[eventName];
+    if (event.bubbles && method != null) {
+      _dispatchMethod(this, method, event, host);
+    }
+  }
+
+  void _dispatchMethod(Object receiver, String methodName, Event event,
+      Node target) {
+    var detail = event is CustomEvent ? (event as CustomEvent).detail : null;
+    var args = [event, detail, target];
+
+    var method = new Symbol(methodName);
+    // TODO(sigmund): consider making event listeners list all arguments
+    // explicitly. Unless VM mirrors are optimized first, this reflectClass call
+    // will be expensive once custom elements extend directly from Element (see
+    // dartbug.com/11108).
+    var methodDecl = reflectClass(receiver.runtimeType).methods[method];
+    if (methodDecl != null) {
+      // This will either truncate the argument list or extend it with extra
+      // null arguments, so it will match the signature.
+      // TODO(sigmund): consider accepting optional arguments when we can tell
+      // them appart from named arguments (see http://dartbug.com/11334)
+      args.length = methodDecl.parameters.where((p) => !p.isOptional).length;
+    }
+    reflect(receiver).invoke(method, args);
+    performMicrotaskCheckpoint();
+  }
+
+  bool _instanceEventListener(String eventName, Event event) {
+    if (event.bubbles) {
+      if (event.path == null || !ShadowRoot.supported) {
+        return _listenLocalNoEventPath(eventName, event);
+      } else {
+        return _listenLocal(eventName, event);
+      }
+    }
+    return false;
+  }
+
+  bool _listenLocal(String eventName, Event event) {
+    var controller = null;
+    for (var target in event.path) {
+      // if we hit host, stop
+      if (target == host) return true;
+
+      // find a controller for the target, unless we already found `host`
+      // as a controller
+      controller = (controller == host) ? controller : _findController(target);
+
+      // if we have a controller, dispatch the event, and stop if the handler
+      // returns true
+      if (controller != null
+          && handleEvent(controller, eventName, event, target)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  // TODO(sorvell): remove when ShadowDOM polyfill supports event path.
+  // Note that _findController will not return the expected controller when the
+  // event target is a distributed node.  This is because we cannot traverse
+  // from a composed node to a node in shadowRoot.
+  // This will be addressed via an event path api
+  // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21066
+  bool _listenLocalNoEventPath(String eventName, Event event) {
+    var target = event.target;
+    var controller = null;
+    while (target != null && target != host) {
+      controller = (controller == host) ? controller : _findController(target);
+      if (controller != null
+          && handleEvent(controller, eventName, event, target)) {
+        return true;
+      }
+      target = target.parent;
+    }
+    return false;
+  }
+
+  // TODO(sigmund): investigate if this implementation is correct. Polymer looks
+  // up the shadow-root that contains [node] and uses a weak-hashmap to find the
+  // host associated with that root. This implementation assumes that the
+  // [node] is under [host]'s shadow-root.
+  Element _findController(Node node) => host.xtag;
+
+  bool handleEvent(
+      Element controller, String eventName, Event event, Element element) {
+    // Note: local events are listened only in the shadow root. This dynamic
+    // lookup is used to distinguish determine whether the target actually has a
+    // listener, and if so, to determine lazily what's the target method.
+    var methodName = element.attributes[toHyphenedName(eventName)];
+    if (methodName != null) {
+      _dispatchMethod(controller, methodName, event, element);
+    }
+    return event.bubbles;
+  }
+}
+
+
+/** Event stream providers per event name. */
+// TODO(sigmund): after dartbug.com/11108 is fixed, consider eliminating this
+// table and using reflection instead.
+const Map<String, EventStreamProvider> _eventStreamProviders = const {
+  'onMouseWheel': Element.mouseWheelEvent,
+  'onTransitionEnd': Element.transitionEndEvent,
+  'onAbort': Element.abortEvent,
+  'onBeforeCopy': Element.beforeCopyEvent,
+  'onBeforeCut': Element.beforeCutEvent,
+  'onBeforePaste': Element.beforePasteEvent,
+  'onBlur': Element.blurEvent,
+  'onChange': Element.changeEvent,
+  'onClick': Element.clickEvent,
+  'onContextMenu': Element.contextMenuEvent,
+  'onCopy': Element.copyEvent,
+  'onCut': Element.cutEvent,
+  'onDoubleClick': Element.doubleClickEvent,
+  'onDrag': Element.dragEvent,
+  'onDragEnd': Element.dragEndEvent,
+  'onDragEnter': Element.dragEnterEvent,
+  'onDragLeave': Element.dragLeaveEvent,
+  'onDragOver': Element.dragOverEvent,
+  'onDragStart': Element.dragStartEvent,
+  'onDrop': Element.dropEvent,
+  'onError': Element.errorEvent,
+  'onFocus': Element.focusEvent,
+  'onInput': Element.inputEvent,
+  'onInvalid': Element.invalidEvent,
+  'onKeyDown': Element.keyDownEvent,
+  'onKeyPress': Element.keyPressEvent,
+  'onKeyUp': Element.keyUpEvent,
+  'onLoad': Element.loadEvent,
+  'onMouseDown': Element.mouseDownEvent,
+  'onMouseMove': Element.mouseMoveEvent,
+  'onMouseOut': Element.mouseOutEvent,
+  'onMouseOver': Element.mouseOverEvent,
+  'onMouseUp': Element.mouseUpEvent,
+  'onPaste': Element.pasteEvent,
+  'onReset': Element.resetEvent,
+  'onScroll': Element.scrollEvent,
+  'onSearch': Element.searchEvent,
+  'onSelect': Element.selectEvent,
+  'onSelectStart': Element.selectStartEvent,
+  'onSubmit': Element.submitEvent,
+  'onTouchCancel': Element.touchCancelEvent,
+  'onTouchEnd': Element.touchEndEvent,
+  'onTouchEnter': Element.touchEnterEvent,
+  'onTouchLeave': Element.touchLeaveEvent,
+  'onTouchMove': Element.touchMoveEvent,
+  'onTouchStart': Element.touchStartEvent,
+  'onFullscreenChange': Element.fullscreenChangeEvent,
+  'onFullscreenError': Element.fullscreenErrorEvent,
+  'onAutocomplete': FormElement.autocompleteEvent,
+  'onAutocompleteError': FormElement.autocompleteErrorEvent,
+  'onSpeechChange': InputElement.speechChangeEvent,
+  'onCanPlay': MediaElement.canPlayEvent,
+  'onCanPlayThrough': MediaElement.canPlayThroughEvent,
+  'onDurationChange': MediaElement.durationChangeEvent,
+  'onEmptied': MediaElement.emptiedEvent,
+  'onEnded': MediaElement.endedEvent,
+  'onLoadStart': MediaElement.loadStartEvent,
+  'onLoadedData': MediaElement.loadedDataEvent,
+  'onLoadedMetadata': MediaElement.loadedMetadataEvent,
+  'onPause': MediaElement.pauseEvent,
+  'onPlay': MediaElement.playEvent,
+  'onPlaying': MediaElement.playingEvent,
+  'onProgress': MediaElement.progressEvent,
+  'onRateChange': MediaElement.rateChangeEvent,
+  'onSeeked': MediaElement.seekedEvent,
+  'onSeeking': MediaElement.seekingEvent,
+  'onShow': MediaElement.showEvent,
+  'onStalled': MediaElement.stalledEvent,
+  'onSuspend': MediaElement.suspendEvent,
+  'onTimeUpdate': MediaElement.timeUpdateEvent,
+  'onVolumeChange': MediaElement.volumeChangeEvent,
+  'onWaiting': MediaElement.waitingEvent,
+  'onKeyAdded': MediaElement.keyAddedEvent,
+  'onKeyError': MediaElement.keyErrorEvent,
+  'onKeyMessage': MediaElement.keyMessageEvent,
+  'onNeedKey': MediaElement.needKeyEvent,
+  'onWebGlContextLost': CanvasElement.webGlContextLostEvent,
+  'onWebGlContextRestored': CanvasElement.webGlContextRestoredEvent,
+  'onPointerLockChange': Document.pointerLockChangeEvent,
+  'onPointerLockError': Document.pointerLockErrorEvent,
+  'onReadyStateChange': Document.readyStateChangeEvent,
+  'onSelectionChange': Document.selectionChangeEvent,
+  'onSecurityPolicyViolation': Document.securityPolicyViolationEvent,
+};
diff --git a/pkg/polymer/lib/safe_html.dart b/pkg/polymer/lib/safe_html.dart
new file mode 100644
index 0000000..c15dd5c
--- /dev/null
+++ b/pkg/polymer/lib/safe_html.dart
@@ -0,0 +1,39 @@
+// 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.
+
+// TODO(sigmund): move this library to a shared package? or make part of
+// dart:html?
+library polymer.safe_html;
+
+/** Declares a string that is a well-formed HTML fragment. */
+class SafeHtml {
+
+  /** Underlying html string. */
+  final String _html;
+
+  // TODO(sigmund): provide a constructor that does html validation
+  SafeHtml.unsafe(this._html);
+
+  String toString() => _html;
+
+  operator ==(other) => other is SafeHtml && _html == other._html;
+  int get hashCode => _html.hashCode;
+}
+
+/**
+ * Declares a string that is safe to use in a Uri attribute, such as `<a href=`,
+ * to avoid cross-site scripting (XSS) attacks.
+ */
+class SafeUri {
+  final String _uri;
+
+  // TODO(sigmund): provide a constructor that takes or creates a Uri and
+  // validates that it is safe (not a javascript: scheme, for example)
+  SafeUri.unsafe(this._uri);
+
+  String toString() => _uri;
+
+  operator ==(other) => other is SafeUri && _uri == other._uri;
+  int get hashCode => _uri.hashCode;
+}
diff --git a/pkg/polymer/lib/src/analyzer.dart b/pkg/polymer/lib/src/analyzer.dart
new file mode 100644
index 0000000..193e139
--- /dev/null
+++ b/pkg/polymer/lib/src/analyzer.dart
@@ -0,0 +1,566 @@
+// Copyright (c) 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 the template compilation that concerns with extracting information
+ * from the HTML parse tree.
+ */
+library analyzer;
+
+import 'package:html5lib/dom.dart';
+import 'package:html5lib/dom_parsing.dart';
+import 'package:source_maps/span.dart' hide SourceFile;
+
+import 'custom_tag_name.dart';
+import 'dart_parser.dart' show parseDartCode;
+import 'files.dart';
+import 'info.dart';
+import 'messages.dart';
+import 'summary.dart';
+
+/**
+ * Finds custom elements in this file and the list of referenced files with
+ * component declarations. This is the first pass of analysis on a file.
+ *
+ * Adds emitted error/warning messages to [messages], if [messages] is
+ * supplied.
+ */
+FileInfo analyzeDefinitions(GlobalInfo global, UrlInfo inputUrl,
+    Document document, String packageRoot,
+    Messages messages, {bool isEntryPoint: false}) {
+  var result = new FileInfo(inputUrl, isEntryPoint);
+  var loader = new _ElementLoader(global, result, packageRoot, messages);
+  loader.visit(document);
+  return result;
+}
+
+/**
+ *  Extract relevant information from all files found from the root document.
+ *
+ *  Adds emitted error/warning messages to [messages], if [messages] is
+ *  supplied.
+ */
+void analyzeFile(SourceFile file, Map<String, FileInfo> info,
+                 Iterator<int> uniqueIds, GlobalInfo global,
+                 Messages messages, emulateScopedCss) {
+  var fileInfo = info[file.path];
+  var analyzer = new _Analyzer(fileInfo, uniqueIds, global, messages,
+      emulateScopedCss);
+  analyzer._normalize(fileInfo, info);
+  analyzer.visit(file.document);
+}
+
+
+/** A visitor that walks the HTML to extract all the relevant information. */
+class _Analyzer extends TreeVisitor {
+  final FileInfo _fileInfo;
+  LibraryInfo _currentInfo;
+  Iterator<int> _uniqueIds;
+  GlobalInfo _global;
+  Messages _messages;
+
+  int _generatedClassNumber = 0;
+
+  /**
+   * Whether to keep indentation spaces. Break lines and indentation spaces
+   * within templates are preserved in HTML. When users specify the attribute
+   * 'indentation="remove"' on a template tag, we'll trim those indentation
+   * spaces that occur within that tag and its decendants. If any decendant
+   * specifies 'indentation="preserve"', then we'll switch back to the normal
+   * behavior.
+   */
+  bool _keepIndentationSpaces = true;
+
+  final bool _emulateScopedCss;
+
+  _Analyzer(this._fileInfo, this._uniqueIds, this._global, this._messages,
+      this._emulateScopedCss) {
+    _currentInfo = _fileInfo;
+  }
+
+  void visitElement(Element node) {
+    if (node.tagName == 'script') {
+      // We already extracted script tags in previous phase.
+      return;
+    }
+
+    if (node.tagName == 'style') {
+      // We've already parsed the CSS.
+      // If this is a component remove the style node.
+      if (_currentInfo is ComponentInfo && _emulateScopedCss) node.remove();
+      return;
+    }
+
+    _bindCustomElement(node);
+
+    var lastInfo = _currentInfo;
+    if (node.tagName == 'polymer-element') {
+      // If element is invalid _ElementLoader already reported an error, but
+      // we skip the body of the element here.
+      var name = node.attributes['name'];
+      if (name == null) return;
+
+      ComponentInfo component = _fileInfo.components[name];
+      if (component == null) return;
+
+      _analyzeComponent(component);
+
+      _currentInfo = component;
+
+      // Remove the <element> tag from the tree
+      node.remove();
+    }
+
+    node.attributes.forEach((name, value) {
+      if (name.startsWith('on')) {
+        _validateEventHandler(node, name, value);
+      } else  if (name == 'pseudo' && _currentInfo is ComponentInfo) {
+        // Any component's custom pseudo-element(s) defined?
+        _processPseudoAttribute(node, value.split(' '));
+      }
+    });
+
+    var keepSpaces = _keepIndentationSpaces;
+    if (node.tagName == 'template' &&
+        node.attributes.containsKey('indentation')) {
+      var value = node.attributes['indentation'];
+      if (value != 'remove' && value != 'preserve') {
+        _messages.warning(
+            "Invalid value for 'indentation' ($value). By default we preserve "
+            "the indentation. Valid values are either 'remove' or 'preserve'.",
+            node.sourceSpan);
+      }
+      _keepIndentationSpaces = value != 'remove';
+    }
+
+    // Invoke super to visit children.
+    super.visitElement(node);
+
+    _keepIndentationSpaces = keepSpaces;
+    _currentInfo = lastInfo;
+
+    if (node.tagName == 'body' || node.parent == null) {
+      _fileInfo.body = node;
+    }
+  }
+
+  void _analyzeComponent(ComponentInfo component) {
+    var baseTag = component.extendsTag;
+    component.extendsComponent = baseTag == null ? null
+        : _fileInfo.components[baseTag];
+    if (component.extendsComponent == null && isCustomTag(baseTag)) {
+      _messages.warning(
+          'custom element with tag name ${component.extendsTag} not found.',
+          component.element.sourceSpan);
+    }
+
+    // Now that the component's code has been loaded, we can validate that the
+    // class exists.
+    component.findClassDeclaration(_messages);
+  }
+
+  void _bindCustomElement(Element node) {
+    // <fancy-button>
+    var component = _fileInfo.components[node.tagName];
+    if (component == null) {
+      // TODO(jmesserly): warn for unknown element tags?
+
+      // <button is="fancy-button">
+      var componentName = node.attributes['is'];
+      if (componentName != null) {
+        component = _fileInfo.components[componentName];
+      } else if (isCustomTag(node.tagName)) {
+        componentName = node.tagName;
+      }
+      if (component == null && componentName != null &&
+          componentName != 'polymer-element') {
+        _messages.warning(
+            'custom element with tag name $componentName not found.',
+            node.sourceSpan);
+      }
+    }
+
+    if (component != null) {
+      if (!component.hasConflict) {
+        _currentInfo.usedComponents[component] = true;
+      }
+
+      var baseTag = component.baseExtendsTag;
+      var nodeTag = node.tagName;
+      var hasIsAttribute = node.attributes.containsKey('is');
+
+      if (baseTag != null && !hasIsAttribute) {
+        _messages.warning(
+            'custom element "${component.tagName}" extends from "$baseTag", but'
+            ' this tag will not include the default properties of "$baseTag". '
+            'To fix this, either write this tag as <$baseTag '
+            'is="${component.tagName}"> or remove the "extends" attribute from '
+            'the custom element declaration.', node.sourceSpan);
+      } else if (hasIsAttribute) {
+        if (baseTag == null) {
+          _messages.warning(
+              'custom element "${component.tagName}" doesn\'t declare any type '
+              'extensions. To fix this, either rewrite this tag as '
+              '<${component.tagName}> or add \'extends="$nodeTag"\' to '
+              'the custom element declaration.', node.sourceSpan);
+        } else if (baseTag != nodeTag) {
+          _messages.warning(
+              'custom element "${component.tagName}" extends from "$baseTag". '
+              'Did you mean to write <$baseTag is="${component.tagName}">?',
+              node.sourceSpan);
+        }
+      }
+    }
+  }
+
+  void _processPseudoAttribute(Node node, List<String> values) {
+    List mangledValues = [];
+    for (var pseudoElement in values) {
+      if (_global.pseudoElements.containsKey(pseudoElement)) continue;
+
+      _uniqueIds.moveNext();
+      var newValue = "${pseudoElement}_${_uniqueIds.current}";
+      _global.pseudoElements[pseudoElement] = newValue;
+      // Mangled name of pseudo-element.
+      mangledValues.add(newValue);
+
+      if (!pseudoElement.startsWith('x-')) {
+        // TODO(terry): The name must start with x- otherwise it's not a custom
+        //              pseudo-element.  May want to relax since components no
+        //              longer need to start with x-.  See isse #509 on
+        //              pseudo-element prefix.
+        _messages.warning("Custom pseudo-element must be prefixed with 'x-'.",
+            node.sourceSpan);
+      }
+    }
+
+    // Update the pseudo attribute with the new mangled names.
+    node.attributes['pseudo'] = mangledValues.join(' ');
+  }
+
+  /**
+   * Support for inline event handlers that take expressions.
+   * For example: `on-double-click=myHandler($event, todo)`.
+   */
+  void _validateEventHandler(Element node, String name, String value) {
+    if (!name.startsWith('on-')) {
+      // TODO(jmesserly): do we need an option to suppress this warning?
+      _messages.warning('Event handler $name will be interpreted as an inline '
+          'JavaScript event handler. Use the form '
+          'on-event-name="handlerName" if you want a Dart handler '
+          'that will automatically update the UI based on model changes.',
+          node.sourceSpan);
+    }
+
+    if (value.contains('.') || value.contains('(')) {
+      // TODO(sigmund): should we allow more if we use fancy-syntax?
+      _messages.warning('Invalid event handler body "$value". Declare a method '
+          'in your custom element "void handlerName(event, detail, target)" '
+          'and use the form on-event-name="handlerName".',
+          node.sourceSpan);
+    }
+  }
+
+  /**
+   * Normalizes references in [info]. On the [analyzeDefinitions] phase, the
+   * analyzer extracted names of files and components. Here we link those names
+   * to actual info classes. In particular:
+   *   * we initialize the [FileInfo.components] map in [info] by importing all
+   *     [declaredComponents],
+   *   * we scan all [info.componentLinks] and import their
+   *     [info.declaredComponents], using [files] to map the href to the file
+   *     info. Names in [info] will shadow names from imported files.
+   *   * we fill [LibraryInfo.externalCode] on each component declared in
+   *     [info].
+   */
+  void _normalize(FileInfo info, Map<String, FileInfo> files) {
+    _attachExtenalScript(info, files);
+
+    for (var component in info.declaredComponents) {
+      _addComponent(info, component);
+      _attachExtenalScript(component, files);
+    }
+
+    for (var link in info.componentLinks) {
+      var file = files[link.resolvedPath];
+      // We already issued an error for missing files.
+      if (file == null) continue;
+      file.declaredComponents.forEach((c) => _addComponent(info, c));
+    }
+  }
+
+  /**
+   * Stores a direct reference in [info] to a dart source file that was loaded
+   * in a script tag with the 'src' attribute.
+   */
+  void _attachExtenalScript(LibraryInfo info, Map<String, FileInfo> files) {
+    var externalFile = info.externalFile;
+    if (externalFile != null) {
+      info.externalCode = files[externalFile.resolvedPath];
+      if (info.externalCode != null) info.externalCode.htmlFile = info;
+    }
+  }
+
+  /** Adds a component's tag name to the names in scope for [fileInfo]. */
+  void _addComponent(FileInfo fileInfo, ComponentSummary component) {
+    var existing = fileInfo.components[component.tagName];
+    if (existing != null) {
+      if (existing == component) {
+        // This is the same exact component as the existing one.
+        return;
+      }
+
+      if (existing is ComponentInfo && component is! ComponentInfo) {
+        // Components declared in [fileInfo] shadow component names declared in
+        // imported files.
+        return;
+      }
+
+      if (existing.hasConflict) {
+        // No need to report a second error for the same name.
+        return;
+      }
+
+      existing.hasConflict = true;
+
+      if (component is ComponentInfo) {
+        _messages.error('duplicate custom element definition for '
+            '"${component.tagName}".', existing.sourceSpan);
+        _messages.error('duplicate custom element definition for '
+            '"${component.tagName}" (second location).', component.sourceSpan);
+      } else {
+        _messages.error('imported duplicate custom element definitions '
+            'for "${component.tagName}".', existing.sourceSpan);
+        _messages.error('imported duplicate custom element definitions '
+            'for "${component.tagName}" (second location).',
+            component.sourceSpan);
+      }
+    } else {
+      fileInfo.components[component.tagName] = component;
+    }
+  }
+}
+
+/** A visitor that finds `<link rel="import">` and `<element>` tags.  */
+class _ElementLoader extends TreeVisitor {
+  final GlobalInfo _global;
+  final FileInfo _fileInfo;
+  LibraryInfo _currentInfo;
+  String _packageRoot;
+  bool _inHead = false;
+  Messages _messages;
+
+  /**
+   * Adds emitted warning/error messages to [_messages]. [_messages]
+   * must not be null.
+   */
+  _ElementLoader(this._global, this._fileInfo, this._packageRoot,
+      this._messages) {
+    _currentInfo = _fileInfo;
+  }
+
+  void visitElement(Element node) {
+    switch (node.tagName) {
+      case 'link': visitLinkElement(node); break;
+      case 'element':
+        _messages.warning('<element> elements are not supported, use'
+            ' <polymer-element> instead', node.sourceSpan);
+        break;
+      case 'polymer-element':
+         visitElementElement(node);
+         break;
+      case 'script': visitScriptElement(node); break;
+      case 'head':
+        var savedInHead = _inHead;
+        _inHead = true;
+        super.visitElement(node);
+        _inHead = savedInHead;
+        break;
+      default: super.visitElement(node); break;
+    }
+  }
+
+  /**
+   * Process `link rel="import"` as specified in:
+   * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/components/index.html#link-type-component>
+   */
+  void visitLinkElement(Element node) {
+    var rel = node.attributes['rel'];
+    if (rel != 'component' && rel != 'components' &&
+        rel != 'import' && rel != 'stylesheet') return;
+
+    if (!_inHead) {
+      _messages.warning('link rel="$rel" only valid in '
+          'head.', node.sourceSpan);
+      return;
+    }
+
+    if (rel == 'component' || rel == 'components') {
+      _messages.warning('import syntax is changing, use '
+          'rel="import" instead of rel="$rel".', node.sourceSpan);
+    }
+
+    var href = node.attributes['href'];
+    if (href == null || href == '') {
+      _messages.warning('link rel="$rel" missing href.',
+          node.sourceSpan);
+      return;
+    }
+
+    bool isStyleSheet = rel == 'stylesheet';
+    var urlInfo = UrlInfo.resolve(href, _fileInfo.inputUrl, node.sourceSpan,
+        _packageRoot, _messages, ignoreAbsolute: isStyleSheet);
+    if (urlInfo == null) return;
+    if (isStyleSheet) {
+      _fileInfo.styleSheetHrefs.add(urlInfo);
+    } else {
+      _fileInfo.componentLinks.add(urlInfo);
+    }
+  }
+
+  void visitElementElement(Element node) {
+    // TODO(jmesserly): what do we do in this case? It seems like an <element>
+    // inside a Shadow DOM should be scoped to that <template> tag, and not
+    // visible from the outside.
+    if (_currentInfo is ComponentInfo) {
+      _messages.error('Nested component definitions are not yet supported.',
+          node.sourceSpan);
+      return;
+    }
+
+    var tagName = node.attributes['name'];
+    var extendsTag = node.attributes['extends'];
+
+    if (tagName == null) {
+      _messages.error('Missing tag name of the component. Please include an '
+          'attribute like \'name="your-tag-name"\'.',
+          node.sourceSpan);
+      return;
+    }
+
+    var component = new ComponentInfo(node, _fileInfo, tagName, extendsTag);
+    _fileInfo.declaredComponents.add(component);
+    _addComponent(component);
+
+    var lastInfo = _currentInfo;
+    _currentInfo = component;
+    super.visitElement(node);
+    _currentInfo = lastInfo;
+  }
+
+  /** Adds a component's tag name to the global list. */
+  void _addComponent(ComponentInfo component) {
+    var existing = _global.components[component.tagName];
+    if (existing != null) {
+      if (existing.hasConflict) {
+        // No need to report a second error for the same name.
+        return;
+      }
+
+      existing.hasConflict = true;
+
+      _messages.error('duplicate custom element definition for '
+          '"${component.tagName}".', existing.sourceSpan);
+      _messages.error('duplicate custom element definition for '
+          '"${component.tagName}" (second location).', component.sourceSpan);
+    } else {
+      _global.components[component.tagName] = component;
+    }
+  }
+
+  void visitScriptElement(Element node) {
+    var scriptType = node.attributes['type'];
+    var src = node.attributes["src"];
+
+    if (scriptType == null) {
+      // Note: in html5 leaving off type= is fine, but it defaults to
+      // text/javascript. Because this might be a common error, we warn about it
+      // in two cases:
+      //   * an inline script tag in a web component
+      //   * a script src= if the src file ends in .dart (component or not)
+      //
+      // The hope is that neither of these cases should break existing valid
+      // code, but that they'll help component authors avoid having their Dart
+      // code accidentally interpreted as JavaScript by the browser.
+      if (src == null && _currentInfo is ComponentInfo) {
+        _messages.warning('script tag in component with no type will '
+            'be treated as JavaScript. Did you forget type="application/dart"?',
+            node.sourceSpan);
+      }
+      if (src != null && src.endsWith('.dart')) {
+        _messages.warning('script tag with .dart source file but no type will '
+            'be treated as JavaScript. Did you forget type="application/dart"?',
+            node.sourceSpan);
+      }
+      return;
+    }
+
+    if (scriptType != 'application/dart') {
+      if (_currentInfo is ComponentInfo) {
+        // TODO(jmesserly): this warning should not be here, but our compiler
+        // does the wrong thing and it could cause surprising behavior, so let
+        // the user know! See issue #340 for more info.
+        // What we should be doing: leave JS component untouched by compiler.
+        _messages.warning('our custom element implementation does not support '
+            'JavaScript components yet. If this is affecting you please let us '
+            'know at https://github.com/dart-lang/web-ui/issues/340.',
+            node.sourceSpan);
+      }
+
+      return;
+    }
+
+    if (src != null) {
+      if (!src.endsWith('.dart')) {
+        _messages.warning('"application/dart" scripts should '
+            'use the .dart file extension.',
+            node.sourceSpan);
+      }
+
+      if (node.innerHtml.trim() != '') {
+        _messages.error('script tag has "src" attribute and also has script '
+            'text.', node.sourceSpan);
+      }
+
+      if (_currentInfo.codeAttached) {
+        _tooManyScriptsError(node);
+      } else {
+        _currentInfo.externalFile = UrlInfo.resolve(src, _fileInfo.inputUrl,
+            node.sourceSpan, _packageRoot, _messages);
+      }
+      return;
+    }
+
+    if (node.nodes.length == 0) return;
+
+    // I don't think the html5 parser will emit a tree with more than
+    // one child of <script>
+    assert(node.nodes.length == 1);
+    Text text = node.nodes[0];
+
+    if (_currentInfo.codeAttached) {
+      _tooManyScriptsError(node);
+    } else if (_currentInfo == _fileInfo && !_fileInfo.isEntryPoint) {
+      _messages.warning('top-level dart code is ignored on '
+          ' HTML pages that define components, but are not the entry HTML '
+          'file.', node.sourceSpan);
+    } else {
+      _currentInfo.inlinedCode = parseDartCode(
+          _currentInfo.dartCodeUrl.resolvedPath, text.value,
+          text.sourceSpan.start);
+      if (_currentInfo.userCode.partOf != null) {
+        _messages.error('expected a library, not a part.',
+            node.sourceSpan);
+      }
+    }
+  }
+
+  void _tooManyScriptsError(Node node) {
+    var location = _currentInfo is ComponentInfo ?
+        'a custom element declaration' : 'the top-level HTML page';
+
+    _messages.error('there should be only one dart script tag in $location.',
+        node.sourceSpan);
+  }
+}
diff --git a/pkg/polymer/lib/src/compiler.dart b/pkg/polymer/lib/src/compiler.dart
new file mode 100644
index 0000000..5e2c98f
--- /dev/null
+++ b/pkg/polymer/lib/src/compiler.dart
@@ -0,0 +1,770 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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 compiler;
+
+import 'dart:async';
+import 'dart:collection' show SplayTreeMap;
+import 'dart:json' as json;
+
+import 'package:analyzer_experimental/src/generated/ast.dart' show Directive, UriBasedDirective;
+import 'package:csslib/visitor.dart' show StyleSheet, treeToDebugString;
+import 'package:html5lib/dom.dart';
+import 'package:html5lib/parser.dart';
+import 'package:observe/transform.dart' show transformObservables;
+import 'package:source_maps/span.dart' show Span;
+import 'package:source_maps/refactor.dart' show TextEditTransaction;
+import 'package:source_maps/printer.dart';
+
+import 'analyzer.dart';
+import 'css_analyzer.dart' show analyzeCss, findUrlsImported,
+       findImportsInStyleSheet, parseCss;
+import 'css_emitters.dart' show rewriteCssUris,
+       emitComponentStyleSheet, emitOriginalCss, emitStyleSheet;
+import 'dart_parser.dart';
+import 'emitters.dart';
+import 'file_system.dart';
+import 'files.dart';
+import 'info.dart';
+import 'messages.dart';
+import 'compiler_options.dart';
+import 'paths.dart';
+import 'utils.dart';
+
+/**
+ * Parses an HTML file [contents] and returns a DOM-like tree.
+ * Note that [contents] will be a [String] if coming from a browser-based
+ * [FileSystem], or it will be a [List<int>] if running on the command line.
+ *
+ * Adds emitted error/warning to [messages], if [messages] is supplied.
+ */
+Document parseHtml(contents, String sourcePath, Messages messages) {
+  var parser = new HtmlParser(contents, generateSpans: true,
+      sourceUrl: sourcePath);
+  var document = parser.parse();
+
+  // Note: errors aren't fatal in HTML (unless strict mode is on).
+  // So just print them as warnings.
+  for (var e in parser.errors) {
+    messages.warning(e.message, e.span);
+  }
+  return document;
+}
+
+/** Compiles an application written with Dart web components. */
+class Compiler {
+  final FileSystem fileSystem;
+  final CompilerOptions options;
+  final List<SourceFile> files = <SourceFile>[];
+  final List<OutputFile> output = <OutputFile>[];
+
+  String _mainPath;
+  String _resetCssFile;
+  StyleSheet _cssResetStyleSheet;
+  PathMapper _pathMapper;
+  Messages _messages;
+
+  FutureGroup _tasks;
+  Set _processed;
+
+  /** Information about source [files] given their href. */
+  final Map<String, FileInfo> info = new SplayTreeMap<String, FileInfo>();
+  final _edits = new Map<DartCodeInfo, TextEditTransaction>();
+
+  final GlobalInfo global = new GlobalInfo();
+
+  /** Creates a compiler with [options] using [fileSystem]. */
+  Compiler(this.fileSystem, this.options, this._messages) {
+    _mainPath = options.inputFile;
+    var mainDir = path.dirname(_mainPath);
+    var baseDir = options.baseDir != null ? options.baseDir : mainDir;
+    var outputDir = options.outputDir != null ? options.outputDir : mainDir;
+    var packageRoot = options.packageRoot != null ? options.packageRoot
+        : path.join(path.dirname(_mainPath), 'packages');
+
+    if (options.resetCssFile != null) {
+      _resetCssFile = options.resetCssFile;
+      if (path.isRelative(_resetCssFile)) {
+        // If CSS reset file path is relative from our current path.
+        _resetCssFile = path.resolve(_resetCssFile);
+      }
+    }
+
+    // Normalize paths - all should be relative or absolute paths.
+    if (path.isAbsolute(_mainPath) || path.isAbsolute(baseDir) ||
+        path.isAbsolute(outputDir) || path.isAbsolute(packageRoot)) {
+      if (path.isRelative(_mainPath)) _mainPath = path.resolve(_mainPath);
+      if (path.isRelative(baseDir)) baseDir = path.resolve(baseDir);
+      if (path.isRelative(outputDir)) outputDir = path.resolve(outputDir);
+      if (path.isRelative(packageRoot)) {
+        packageRoot = path.resolve(packageRoot);
+      }
+    }
+    _pathMapper = new PathMapper(
+        baseDir, outputDir, packageRoot, options.forceMangle,
+        options.rewriteUrls);
+  }
+
+  /** Compile the application starting from the given input file. */
+  Future run() {
+    if (path.basename(_mainPath).endsWith('.dart')) {
+      _messages.error("Please provide an HTML file as your entry point.",
+          null);
+      return new Future.value(null);
+    }
+    return _parseAndDiscover(_mainPath).then((_) {
+      _analyze();
+
+      // Analyze all CSS files.
+      _time('Analyzed Style Sheets', '', () =>
+          analyzeCss(_pathMapper.packageRoot, files, info,
+              global.pseudoElements, _messages,
+              warningsAsErrors: options.warningsAsErrors));
+
+      // TODO(jmesserly): need to go through our errors, and figure out if some
+      // of them should be warnings instead.
+      if (_messages.hasErrors || options.analysisOnly) return;
+      _transformDart();
+      _emit();
+    });
+  }
+
+  /**
+   * Asynchronously parse [inputFile] and transitively discover web components
+   * to load and parse. Returns a future that completes when all files are
+   * processed.
+   */
+  Future _parseAndDiscover(String inputFile) {
+    _tasks = new FutureGroup();
+    _processed = new Set();
+    _processed.add(inputFile);
+    _tasks.add(_parseHtmlFile(new UrlInfo(inputFile, inputFile, null)));
+    return _tasks.future;
+  }
+
+  void _processHtmlFile(UrlInfo inputUrl, SourceFile file) {
+    if (file == null) return;
+
+    bool isEntryPoint = _processed.length == 1;
+
+    files.add(file);
+
+    var fileInfo = _time('Analyzed definitions', inputUrl.url, () {
+      return analyzeDefinitions(global, inputUrl, file.document,
+        _pathMapper.packageRoot, _messages, isEntryPoint: isEntryPoint);
+    });
+    info[inputUrl.resolvedPath] = fileInfo;
+
+    if (isEntryPoint && _resetCssFile != null) {
+      _processed.add(_resetCssFile);
+      _tasks.add(_parseCssFile(new UrlInfo(_resetCssFile, _resetCssFile,
+          null)));
+    }
+
+    _setOutputFilenames(fileInfo);
+    _processImports(fileInfo);
+
+    // Load component files referenced by [file].
+    for (var link in fileInfo.componentLinks) {
+      _loadFile(link, _parseHtmlFile);
+    }
+
+    // Load stylesheet files referenced by [file].
+    for (var link in fileInfo.styleSheetHrefs) {
+      _loadFile(link, _parseCssFile);
+    }
+
+    // Load .dart files being referenced in the page.
+    _loadFile(fileInfo.externalFile, _parseDartFile);
+
+    // Process any @imports inside of a <style> tag.
+    var urlInfos = findUrlsImported(fileInfo, fileInfo.inputUrl,
+        _pathMapper.packageRoot, file.document, _messages, options);
+    for (var urlInfo in urlInfos) {
+      _loadFile(urlInfo, _parseCssFile);
+    }
+
+    // Load .dart files being referenced in components.
+    for (var component in fileInfo.declaredComponents) {
+      if (component.externalFile != null) {
+        _loadFile(component.externalFile, _parseDartFile);
+      } else if (component.userCode != null) {
+        _processImports(component);
+      }
+
+      // Process any @imports inside of the <style> tag in a component.
+      var urlInfos = findUrlsImported(component,
+          component.declaringFile.inputUrl, _pathMapper.packageRoot,
+          component.element, _messages, options);
+      for (var urlInfo in urlInfos) {
+        _loadFile(urlInfo, _parseCssFile);
+      }
+    }
+  }
+
+  /**
+   * Helper function to load [urlInfo] and parse it using [loadAndParse] if it
+   * hasn't been loaded before.
+   */
+  void _loadFile(UrlInfo urlInfo, Future loadAndParse(UrlInfo inputUrl)) {
+    if (urlInfo == null) return;
+    var resolvedPath = urlInfo.resolvedPath;
+    if (!_processed.contains(resolvedPath)) {
+      _processed.add(resolvedPath);
+      _tasks.add(loadAndParse(urlInfo));
+    }
+  }
+
+  void _setOutputFilenames(FileInfo fileInfo) {
+    var filePath = fileInfo.dartCodeUrl.resolvedPath;
+    fileInfo.outputFilename = _pathMapper.mangle(path.basename(filePath),
+        '.dart', path.extension(filePath) == '.html');
+    for (var component in fileInfo.declaredComponents) {
+      var externalFile = component.externalFile;
+      var name = null;
+      if (externalFile != null) {
+        name = _pathMapper.mangle(
+            path.basename(externalFile.resolvedPath), '.dart');
+      } else {
+        var declaringFile = component.declaringFile;
+        var prefix = path.basename(declaringFile.inputUrl.resolvedPath);
+        if (declaringFile.declaredComponents.length == 1
+            && !declaringFile.codeAttached && !declaringFile.isEntryPoint) {
+          name = _pathMapper.mangle(prefix, '.dart', true);
+        } else {
+          var componentName = component.tagName.replaceAll('-', '_');
+          name = _pathMapper.mangle('${prefix}_$componentName', '.dart', true);
+        }
+      }
+      component.outputFilename = name;
+    }
+  }
+
+  /** Parse an HTML file. */
+  Future _parseHtmlFile(UrlInfo inputUrl) {
+    if (!_pathMapper.checkInputPath(inputUrl, _messages)) {
+      return new Future<SourceFile>.value(null);
+    }
+    var filePath = inputUrl.resolvedPath;
+    return fileSystem.readTextOrBytes(filePath)
+        .catchError((e) => _readError(e, inputUrl))
+        .then((source) {
+          if (source == null) return;
+          var file = new SourceFile(filePath);
+          file.document = _time('Parsed', filePath,
+              () => parseHtml(source, filePath, _messages));
+          _processHtmlFile(inputUrl, file);
+        });
+  }
+
+  /** Parse a Dart file. */
+  Future _parseDartFile(UrlInfo inputUrl) {
+    if (!_pathMapper.checkInputPath(inputUrl, _messages)) {
+      return new Future<SourceFile>.value(null);
+    }
+    var filePath = inputUrl.resolvedPath;
+    return fileSystem.readText(filePath)
+        .catchError((e) => _readError(e, inputUrl))
+        .then((code) {
+          if (code == null) return;
+          var file = new SourceFile(filePath, type: SourceFile.DART);
+          file.code = code;
+          _processDartFile(inputUrl, file);
+        });
+  }
+
+  /** Parse a stylesheet file. */
+  Future _parseCssFile(UrlInfo inputUrl) {
+    if (!options.emulateScopedCss ||
+        !_pathMapper.checkInputPath(inputUrl, _messages)) {
+      return new Future<SourceFile>.value(null);
+    }
+    var filePath = inputUrl.resolvedPath;
+    return fileSystem.readText(filePath)
+        .catchError((e) => _readError(e, inputUrl, isWarning: true))
+        .then((code) {
+          if (code == null) return;
+          var file = new SourceFile(filePath, type: SourceFile.STYLESHEET);
+          file.code = code;
+          _processCssFile(inputUrl, file);
+        });
+  }
+
+
+  SourceFile _readError(error, UrlInfo inputUrl, {isWarning: false}) {
+    var message = 'unable to open file "${inputUrl.resolvedPath}"';
+    if (options.verbose) {
+      message = '$message. original message:\n $error';
+    }
+    if (isWarning) {
+      _messages.warning(message, inputUrl.sourceSpan);
+    } else {
+      _messages.error(message, inputUrl.sourceSpan);
+    }
+    return null;
+  }
+
+  void _processDartFile(UrlInfo inputUrl, SourceFile dartFile) {
+    if (dartFile == null) return;
+
+    files.add(dartFile);
+
+    var resolvedPath = inputUrl.resolvedPath;
+    var fileInfo = new FileInfo(inputUrl);
+    info[resolvedPath] = fileInfo;
+    fileInfo.inlinedCode = parseDartCode(resolvedPath, dartFile.code);
+    fileInfo.outputFilename =
+        _pathMapper.mangle(path.basename(resolvedPath), '.dart', false);
+
+    _processImports(fileInfo);
+  }
+
+  void _processImports(LibraryInfo library) {
+    if (library.userCode == null) return;
+
+    for (var directive in library.userCode.directives) {
+      _loadFile(_getDirectiveUrlInfo(library, directive), _parseDartFile);
+    }
+  }
+
+  void _processCssFile(UrlInfo inputUrl, SourceFile cssFile) {
+    if (cssFile == null) return;
+
+    files.add(cssFile);
+
+    var fileInfo = new FileInfo(inputUrl);
+    info[inputUrl.resolvedPath] = fileInfo;
+
+    var styleSheet = parseCss(cssFile.code, _messages, options);
+    if (inputUrl.url == _resetCssFile) {
+      _cssResetStyleSheet = styleSheet;
+    } else if (styleSheet != null) {
+      _resolveStyleSheetImports(inputUrl, cssFile.path, styleSheet);
+      fileInfo.styleSheets.add(styleSheet);
+    }
+  }
+
+  /** Load and parse all style sheets referenced with an @imports. */
+  void _resolveStyleSheetImports(UrlInfo inputUrl, String processingFile,
+      StyleSheet styleSheet) {
+    var urlInfos = _time('CSS imports', processingFile, () =>
+        findImportsInStyleSheet(styleSheet, _pathMapper.packageRoot, inputUrl,
+            _messages));
+
+    for (var urlInfo in urlInfos) {
+      if (urlInfo == null) break;
+      // Load any @imported stylesheet files referenced in this style sheet.
+      _loadFile(urlInfo, _parseCssFile);
+    }
+  }
+
+  String _directiveUri(Directive directive) {
+    var uriDirective = (directive as UriBasedDirective).uri;
+    return (uriDirective as dynamic).value;
+  }
+
+  UrlInfo _getDirectiveUrlInfo(LibraryInfo library, Directive directive) {
+    var uri = _directiveUri(directive);
+    if (uri.startsWith('dart:')) return null;
+    if (uri.startsWith('package:') && uri.startsWith('package:polymer/')) {
+      // Don't process our own package -- we'll implement @observable manually.
+      return null;
+    }
+
+    var span = library.userCode.sourceFile.span(
+        directive.offset, directive.end);
+    return UrlInfo.resolve(uri, library.dartCodeUrl, span,
+        _pathMapper.packageRoot, _messages);
+  }
+
+  /**
+   * Transform Dart source code.
+   * Currently, the only transformation is [transformObservables].
+   * Calls _emitModifiedDartFiles to write the transformed files.
+   */
+  void _transformDart() {
+    var libraries = _findAllDartLibraries();
+
+    var transformed = [];
+    for (var lib in libraries) {
+      var userCode = lib.userCode;
+      var transaction = transformObservables(userCode.compilationUnit,
+          userCode.sourceFile, userCode.code, _messages);
+      if (transaction != null) {
+        _edits[lib.userCode] = transaction;
+        if (transaction.hasEdits) {
+          transformed.add(lib);
+        } else if (lib.htmlFile != null) {
+          // All web components will be transformed too. Track that.
+          transformed.add(lib);
+        }
+      }
+    }
+
+    _findModifiedDartFiles(libraries, transformed);
+
+    libraries.forEach(_fixImports);
+
+    _emitModifiedDartFiles(libraries);
+  }
+
+  /**
+   * Finds all Dart code libraries.
+   * Each library will have [LibraryInfo.inlinedCode] that is non-null.
+   * Also each inlinedCode will be unique.
+   */
+  List<LibraryInfo> _findAllDartLibraries() {
+    var libs = <LibraryInfo>[];
+    void _addLibrary(LibraryInfo lib) {
+      if (lib.inlinedCode != null) libs.add(lib);
+    }
+
+    for (var sourceFile in files) {
+      var file = info[sourceFile.path];
+      _addLibrary(file);
+      file.declaredComponents.forEach(_addLibrary);
+    }
+
+    // Assert that each file path is unique.
+    assert(_uniquePaths(libs));
+    return libs;
+  }
+
+  bool _uniquePaths(List<LibraryInfo> libs) {
+    var seen = new Set();
+    for (var lib in libs) {
+      if (seen.contains(lib.inlinedCode)) {
+        throw new StateError('internal error: '
+            'duplicate user code for ${lib.dartCodeUrl.resolvedPath}.'
+            ' Files were: $files');
+      }
+      seen.add(lib.inlinedCode);
+    }
+    return true;
+  }
+
+  /**
+   * Queue modified Dart files to be written.
+   * This will not write files that are handled by [WebComponentEmitter] and
+   * [EntryPointEmitter].
+   */
+  void _emitModifiedDartFiles(List<LibraryInfo> libraries) {
+    for (var lib in libraries) {
+      // Components will get emitted by WebComponentEmitter, and the
+      // entry point will get emitted by MainPageEmitter.
+      // So we only need to worry about other .dart files.
+      if (lib.modified && lib is FileInfo &&
+          lib.htmlFile == null && !lib.isEntryPoint) {
+        var transaction = _edits[lib.userCode];
+
+        // Save imports that were modified by _fixImports.
+        for (var d in lib.userCode.directives) {
+          transaction.edit(d.offset, d.end, d.toString());
+        }
+
+        if (!lib.userCode.isPart) {
+          var pos = lib.userCode.firstPartOffset;
+          // Note: we use a different prefix than "autogenerated" to make
+          // ChangeRecord unambiguous. Otherwise it would be imported by this
+          // and polymer, resulting in a collision.
+          // TODO(jmesserly): only generate this for libraries that need it.
+          transaction.edit(pos, pos, "\nimport "
+              "'package:observe/observe.dart' as __observe;\n");
+        }
+        _emitFileAndSourceMaps(lib, transaction.commit(), lib.dartCodeUrl);
+      }
+    }
+  }
+
+  /**
+   * This method computes which Dart files have been modified, starting
+   * from [transformed] and marking recursively through all files that import
+   * the modified files.
+   */
+  void _findModifiedDartFiles(List<LibraryInfo> libraries,
+      List<FileInfo> transformed) {
+
+    if (transformed.length == 0) return;
+
+    // Compute files that reference each file, then use this information to
+    // flip the modified bit transitively. This is a lot simpler than trying
+    // to compute it the other way because of circular references.
+    for (var lib in libraries) {
+      for (var directive in lib.userCode.directives) {
+        var importPath = _getDirectiveUrlInfo(lib, directive);
+        if (importPath == null) continue;
+
+        var importInfo = info[importPath.resolvedPath];
+        if (importInfo != null) {
+          importInfo.referencedBy.add(lib);
+        }
+      }
+    }
+
+    // Propegate the modified bit to anything that references a modified file.
+    void setModified(LibraryInfo library) {
+      if (library.modified) return;
+      library.modified = true;
+      library.referencedBy.forEach(setModified);
+    }
+    transformed.forEach(setModified);
+
+    for (var lib in libraries) {
+      // We don't need this anymore, so free it.
+      lib.referencedBy = null;
+    }
+  }
+
+  void _fixImports(LibraryInfo library) {
+    // Fix imports. Modified files must use the generated path, otherwise
+    // we need to make the path relative to the input.
+    for (var directive in library.userCode.directives) {
+      var importPath = _getDirectiveUrlInfo(library, directive);
+      if (importPath == null) continue;
+      var importInfo = info[importPath.resolvedPath];
+      if (importInfo == null) continue;
+
+      String newUri = null;
+      if (importInfo.modified) {
+        // Use the generated URI for this file.
+        newUri = _pathMapper.importUrlFor(library, importInfo);
+      } else if (options.rewriteUrls) {
+        // Get the relative path to the input file.
+        newUri = _pathMapper.transformUrl(
+            library.dartCodeUrl.resolvedPath, directive.uri.value);
+      }
+      if (newUri != null) {
+        directive.uri = createStringLiteral(newUri);
+      }
+    }
+  }
+
+  /** Run the analyzer on every input html file. */
+  void _analyze() {
+    var uniqueIds = new IntIterator();
+    for (var file in files) {
+      if (file.isHtml) {
+        _time('Analyzed contents', file.path, () =>
+            analyzeFile(file, info, uniqueIds, global, _messages,
+              options.emulateScopedCss));
+      }
+    }
+  }
+
+  /** Emit the generated code corresponding to each input file. */
+  void _emit() {
+    for (var file in files) {
+      if (file.isDart || file.isStyleSheet) continue;
+      _time('Codegen', file.path, () {
+        var fileInfo = info[file.path];
+        _emitComponents(fileInfo);
+      });
+    }
+
+    var entryPoint = files[0];
+    assert(info[entryPoint.path].isEntryPoint);
+    _emitMainDart(entryPoint);
+    _emitMainHtml(entryPoint);
+
+    assert(_unqiueOutputs());
+  }
+
+  bool _unqiueOutputs() {
+    var seen = new Set();
+    for (var file in output) {
+      if (seen.contains(file.path)) {
+        throw new StateError('internal error: '
+            'duplicate output file ${file.path}. Files were: $output');
+      }
+      seen.add(file.path);
+    }
+    return true;
+  }
+
+  /** Emit the main .dart file. */
+  void _emitMainDart(SourceFile file) {
+    var fileInfo = info[file.path];
+
+    var codeInfo = fileInfo.userCode;
+    if (codeInfo != null) {
+      var printer = new NestedPrinter(0);
+      if (codeInfo.libraryName == null) {
+        printer.addLine('library ${fileInfo.libraryName};');
+      }
+      printer.add(codeInfo.code);
+      _emitFileAndSourceMaps(fileInfo, printer, fileInfo.dartCodeUrl);
+    }
+  }
+
+  // TODO(jmesserly): refactor this out of Compiler.
+  /** Generate an html file with the (trimmed down) main html page. */
+  void _emitMainHtml(SourceFile file) {
+    var fileInfo = info[file.path];
+
+    var bootstrapName = '${path.basename(file.path)}_bootstrap.dart';
+    var bootstrapPath = path.join(path.dirname(file.path), bootstrapName);
+    var bootstrapOutPath = _pathMapper.outputPath(bootstrapPath, '');
+    var bootstrapOutName = path.basename(bootstrapOutPath);
+    var bootstrapInfo = new FileInfo(new UrlInfo('', bootstrapPath, null));
+    var printer = generateBootstrapCode(bootstrapInfo, fileInfo, global,
+        _pathMapper, options);
+    printer.build(bootstrapOutPath);
+    output.add(new OutputFile(
+          bootstrapOutPath, printer.text, source: file.path));
+
+    var document = file.document;
+    var hasCss = _emitAllCss();
+    transformMainHtml(document, fileInfo, _pathMapper, hasCss,
+        options.rewriteUrls, _messages, global, bootstrapOutName);
+    output.add(new OutputFile(_pathMapper.outputPath(file.path, '.html'),
+        document.outerHtml, source: file.path));
+  }
+
+  // TODO(jmesserly): refactor this and other CSS related transforms out of
+  // Compiler.
+  /**
+   * Generate an CSS file for all style sheets (main and components).
+   * Returns true if a file was generated, otherwise false.
+   */
+  bool _emitAllCss() {
+    if (!options.emulateScopedCss) return false;
+
+    var buff = new StringBuffer();
+
+    // Emit all linked style sheet files first.
+    for (var file in files) {
+      var css = new StringBuffer();
+      var fileInfo = info[file.path];
+      if (file.isStyleSheet) {
+        for (var styleSheet in fileInfo.styleSheets) {
+          // Translate any URIs in CSS.
+          rewriteCssUris(_pathMapper, fileInfo.inputUrl.resolvedPath,
+              options.rewriteUrls, styleSheet);
+          css.write(
+              '/* Auto-generated from style sheet href = ${file.path} */\n'
+              '/* DO NOT EDIT. */\n\n');
+          css.write(emitStyleSheet(styleSheet, fileInfo));
+          css.write('\n\n');
+        }
+
+        // Emit the linked style sheet in the output directory.
+        if (fileInfo.inputUrl.url != _resetCssFile) {
+          var outCss = _pathMapper.outputPath(fileInfo.inputUrl.resolvedPath,
+              '');
+          output.add(new OutputFile(outCss, css.toString()));
+        }
+      }
+    }
+
+    // Emit all CSS for each component (style scoped).
+    for (var file in files) {
+      if (file.isHtml) {
+        var fileInfo = info[file.path];
+        for (var component in fileInfo.declaredComponents) {
+          for (var styleSheet in component.styleSheets) {
+            // Translate any URIs in CSS.
+            rewriteCssUris(_pathMapper, fileInfo.inputUrl.resolvedPath,
+                options.rewriteUrls, styleSheet);
+
+            if (buff.isEmpty) {
+              buff.write(
+                  '/* Auto-generated from components style tags. */\n'
+                  '/* DO NOT EDIT. */\n\n');
+            }
+            buff.write(
+                '/* ==================================================== \n'
+                '   Component ${component.tagName} stylesheet \n'
+                '   ==================================================== */\n');
+
+            var tagName = component.tagName;
+            if (!component.hasAuthorStyles) {
+              if (_cssResetStyleSheet != null) {
+                // If component doesn't have apply-author-styles then we need to
+                // reset the CSS the styles for the component (if css-reset file
+                // option was passed).
+                buff.write('\n/* Start CSS Reset */\n');
+                var style;
+                if (options.emulateScopedCss) {
+                  style = emitComponentStyleSheet(_cssResetStyleSheet, tagName);
+                } else {
+                  style = emitOriginalCss(_cssResetStyleSheet);
+                }
+                buff.write(style);
+                buff.write('/* End CSS Reset */\n\n');
+              }
+            }
+            if (options.emulateScopedCss) {
+              buff.write(emitComponentStyleSheet(styleSheet, tagName));
+            } else {
+              buff.write(emitOriginalCss(styleSheet));
+            }
+            buff.write('\n\n');
+          }
+        }
+      }
+    }
+
+    if (buff.isEmpty) return false;
+
+    var cssPath = _pathMapper.outputPath(_mainPath, '.css', true);
+    output.add(new OutputFile(cssPath, buff.toString()));
+    return true;
+  }
+
+  /** Emits the Dart code for all components in [fileInfo]. */
+  void _emitComponents(FileInfo fileInfo) {
+    for (var component in fileInfo.declaredComponents) {
+      // TODO(terry): Handle more than one stylesheet per component
+      if (component.styleSheets.length > 1 && options.emulateScopedCss) {
+        var span = component.externalFile != null
+            ? component.externalFile.sourceSpan : null;
+        _messages.warning(
+            'Component has more than one stylesheet - first stylesheet used.',
+            span);
+      }
+      var printer = emitPolymerElement(
+          component, _pathMapper, _edits[component.userCode], options);
+      _emitFileAndSourceMaps(component, printer, component.externalFile);
+    }
+  }
+
+  /**
+   * Emits a file that was created using [NestedPrinter] and it's corresponding
+   * source map file.
+   */
+  void _emitFileAndSourceMaps(
+      LibraryInfo lib, NestedPrinter printer, UrlInfo dartCodeUrl) {
+    // Bail if we had an error generating the code for the file.
+    if (printer == null) return;
+
+    var libPath = _pathMapper.outputLibraryPath(lib);
+    var dir = path.dirname(libPath);
+    var filename = path.basename(libPath);
+    printer.add('\n//# sourceMappingURL=$filename.map');
+    printer.build(libPath);
+    var sourcePath = dartCodeUrl != null ? dartCodeUrl.resolvedPath : null;
+    output.add(new OutputFile(libPath, printer.text, source: sourcePath));
+    // Fix-up the paths in the source map file
+    var sourceMap = json.parse(printer.map);
+    var urls = sourceMap['sources'];
+    for (int i = 0; i < urls.length; i++) {
+      urls[i] = path.relative(urls[i], from: dir);
+    }
+    output.add(new OutputFile(path.join(dir, '$filename.map'),
+          json.stringify(sourceMap)));
+  }
+
+  _time(String logMessage, String filePath, callback(),
+      {bool printTime: false}) {
+    var message = new StringBuffer();
+    message.write(logMessage);
+    var filename = path.basename(filePath);
+    for (int i = (60 - logMessage.length - filename.length); i > 0 ; i--) {
+      message.write(' ');
+    }
+    message.write(filename);
+    return time(message.toString(), callback,
+        printTime: options.verbose || printTime);
+  }
+}
diff --git a/pkg/polymer/lib/src/compiler_options.dart b/pkg/polymer/lib/src/compiler_options.dart
new file mode 100644
index 0000000..4c1d317
--- /dev/null
+++ b/pkg/polymer/lib/src/compiler_options.dart
@@ -0,0 +1,148 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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 polymer.src.compiler_options;
+
+import 'package:args/args.dart';
+
+class CompilerOptions {
+  /** Report warnings as errors. */
+  final bool warningsAsErrors;
+
+  /** True to show informational messages. The `--verbose` flag. */
+  final bool verbose;
+
+  /** Remove any generated files. */
+  final bool clean;
+
+  /** Whether to use colors to print messages on the terminal. */
+  final bool useColors;
+
+  /** Force mangling any generated name (even when --out is provided). */
+  final bool forceMangle;
+
+  /** Generate component's dart code, but not the main entry point file. */
+  final bool componentsOnly;
+
+  /** File to process by the compiler. */
+  String inputFile;
+
+  /** Directory where all sources are found. */
+  final String baseDir;
+
+  /** Directory where all output will be generated. */
+  final String outputDir;
+
+  /** Directory where to look for 'package:' imports. */
+  final String packageRoot;
+
+  /**
+   * Adjust resource URLs in the output HTML to point back to the original
+   * location in the file system. Commonly this is enabled during development,
+   * but disabled for deployment.
+   */
+  final bool rewriteUrls;
+
+  /**
+   * Whether to print error messages using the json format understood by the
+   * Dart editor.
+   */
+  final bool jsonFormat;
+
+  /** Emulate scoped styles using a CSS polyfill. */
+  final bool emulateScopedCss;
+
+  /** Use CSS file for CSS Reset. */
+  final String resetCssFile;
+
+  /** Whether to analyze the input for warnings without generating any code. */
+  final bool analysisOnly;
+
+  // We could make this faster, if it ever matters.
+  factory CompilerOptions() => parse(['']);
+
+  CompilerOptions.fromArgs(ArgResults args)
+    : warningsAsErrors = args['warnings_as_errors'],
+      verbose = args['verbose'],
+      clean = args['clean'],
+      useColors = args['colors'],
+      baseDir = args['basedir'],
+      outputDir = args['out'],
+      packageRoot = args['package-root'],
+      rewriteUrls = args['rewrite-urls'],
+      forceMangle = args['unique_output_filenames'],
+      jsonFormat = args['json_format'],
+      componentsOnly = args['components_only'],
+      emulateScopedCss = args['scoped-css'],
+      resetCssFile = args['css-reset'],
+      analysisOnly = !args['deploy'],
+      inputFile = args.rest.length > 0 ? args.rest[0] : null;
+
+  /**
+   * Returns the compiler options parsed from [arguments]. Set [checkUsage] to
+   * false to suppress checking of correct usage or printing help messages.
+   */
+  // TODO(sigmund): convert all flags to use dashes instead of underscores
+  static CompilerOptions parse(List<String> arguments,
+      {bool checkUsage: true}) {
+    var parser = new ArgParser()
+      ..addFlag('verbose', abbr: 'v')
+      ..addFlag('clean', help: 'Remove all generated files',
+          defaultsTo: false, negatable: false)
+      ..addFlag('warnings_as_errors', abbr: 'e',
+          help: 'Warnings handled as errors',
+          defaultsTo: false, negatable: false)
+      ..addFlag('colors', help: 'Display errors/warnings in colored text',
+          defaultsTo: true)
+      ..addFlag('rewrite-urls',
+          help: 'Adjust every resource url to point to the original location in'
+          ' the filesystem.\nThis on by default during development and can be'
+          ' disabled to make the generated code easier to deploy.',
+          defaultsTo: true)
+      ..addFlag('unique_output_filenames', abbr: 'u',
+          help: 'Use unique names for all generated files, so they will not '
+                'have the\nsame name as your input files, even if they are in a'
+                ' different directory',
+          defaultsTo: false, negatable: false)
+      ..addFlag('json_format',
+          help: 'Print error messsages in a json format easy to parse by tools,'
+                ' such as the Dart editor',
+          defaultsTo: false, negatable: false)
+      ..addFlag('components_only',
+          help: 'Generate only the code for component classes, do not generate '
+                'HTML files or the main bootstrap code.',
+          defaultsTo: false, negatable: false)
+      ..addFlag('scoped-css', help: 'Emulate scoped styles with CSS polyfill',
+          defaultsTo: false)
+      ..addOption('css-reset', abbr: 'r', help: 'CSS file used to reset CSS')
+      ..addFlag('deploy', help: 'Emit code used for deploying a polymer app,'
+          ' if false just show warnings and errors (default)',
+          defaultsTo: false, negatable: false)
+      ..addOption('out', abbr: 'o', help: 'Directory where to generate files'
+          ' (defaults to the same directory as the source file)')
+      ..addOption('basedir', help: 'Base directory where to find all source '
+          'files (defaults to the source file\'s directory)')
+      ..addOption('package-root', help: 'Where to find "package:" imports'
+          '(defaults to the "packages/" subdirectory next to the source file)')
+      ..addFlag('help', abbr: 'h', help: 'Displays this help message',
+          defaultsTo: false, negatable: false);
+    try {
+      var results = parser.parse(arguments);
+      if (checkUsage && (results['help'] || results.rest.length == 0)) {
+        showUsage(parser);
+        return null;
+      }
+      return new CompilerOptions.fromArgs(results);
+    } on FormatException catch (e) {
+      print(e.message);
+      showUsage(parser);
+      return null;
+    }
+  }
+
+  static showUsage(parser) {
+    print('Usage: dwc [options...] input.html');
+    print(parser.getUsage());
+  }
+}
diff --git a/pkg/polymer/lib/src/css_analyzer.dart b/pkg/polymer/lib/src/css_analyzer.dart
new file mode 100644
index 0000000..270af5d
--- /dev/null
+++ b/pkg/polymer/lib/src/css_analyzer.dart
@@ -0,0 +1,507 @@
+// Copyright (c) 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.
+
+/** Portion of the analyzer dealing with CSS sources. */
+library polymer.src.css_analyzer;
+
+import 'package:csslib/parser.dart' as css;
+import 'package:csslib/visitor.dart';
+import 'package:html5lib/dom.dart';
+import 'package:html5lib/dom_parsing.dart';
+
+import 'info.dart';
+import 'files.dart' show SourceFile;
+import 'messages.dart';
+import 'compiler_options.dart';
+
+void analyzeCss(String packageRoot, List<SourceFile> files,
+                Map<String, FileInfo> info, Map<String, String> pseudoElements,
+                Messages messages, {warningsAsErrors: false}) {
+  var analyzer = new _AnalyzerCss(packageRoot, info, pseudoElements, messages,
+      warningsAsErrors);
+  for (var file in files) analyzer.process(file);
+  analyzer.normalize();
+}
+
+class _AnalyzerCss {
+  final String packageRoot;
+  final Map<String, FileInfo> info;
+  final Map<String, String> _pseudoElements;
+  final Messages _messages;
+  final bool _warningsAsErrors;
+
+  Set<StyleSheet> allStyleSheets = new Set<StyleSheet>();
+
+  /**
+   * [_pseudoElements] list of known pseudo attributes found in HTML, any
+   * CSS pseudo-elements 'name::custom-element' is mapped to the manged name
+   * associated with the pseudo-element key.
+   */
+  _AnalyzerCss(this.packageRoot, this.info, this._pseudoElements,
+               this._messages, this._warningsAsErrors);
+
+  /**
+   * Run the analyzer on every file that is a style sheet or any component that
+   * has a style tag.
+   */
+  void process(SourceFile file) {
+    var fileInfo = info[file.path];
+    if (file.isStyleSheet || fileInfo.styleSheets.length > 0) {
+      var styleSheets = processVars(fileInfo);
+
+      // Add to list of all style sheets analyzed.
+      allStyleSheets.addAll(styleSheets);
+    }
+
+    // Process any components.
+    for (var component in fileInfo.declaredComponents) {
+      var all = processVars(component);
+
+      // Add to list of all style sheets analyzed.
+      allStyleSheets.addAll(all);
+    }
+
+    processCustomPseudoElements();
+  }
+
+  void normalize() {
+    // Remove all var definitions for all style sheets analyzed.
+    for (var tree in allStyleSheets) new _RemoveVarDefinitions().visitTree(tree);
+  }
+
+  List<StyleSheet> processVars(var libraryInfo) {
+    // Get list of all stylesheet(s) dependencies referenced from this file.
+    var styleSheets = _dependencies(libraryInfo).toList();
+
+    var errors = [];
+    css.analyze(styleSheets, errors: errors, options:
+      [_warningsAsErrors ? '--warnings_as_errors' : '', 'memory']);
+
+    // Print errors as warnings.
+    for (var e in errors) {
+      _messages.warning(e.message, e.span);
+    }
+
+    // Build list of all var definitions.
+    Map varDefs = new Map();
+    for (var tree in styleSheets) {
+      var allDefs = (new _VarDefinitions()..visitTree(tree)).found;
+      allDefs.forEach((key, value) {
+        varDefs[key] = value;
+      });
+    }
+
+    // Resolve all definitions to a non-VarUsage (terminal expression).
+    varDefs.forEach((key, value) {
+      for (var expr in (value.expression as Expressions).expressions) {
+        var def = _findTerminalVarDefinition(varDefs, value);
+        varDefs[key] = def;
+      }
+    });
+
+    // Resolve all var usages.
+    for (var tree in styleSheets) new _ResolveVarUsages(varDefs).visitTree(tree);
+
+    return styleSheets;
+  }
+
+  processCustomPseudoElements() {
+    var polyFiller = new _PseudoElementExpander(_pseudoElements);
+    for (var tree in allStyleSheets) {
+      polyFiller.visitTree(tree);
+    }
+  }
+
+  /**
+   * Given a component or file check if any stylesheets referenced.  If so then
+   * return a list of all referenced stylesheet dependencies (@imports or <link
+   * rel="stylesheet" ..>).
+   */
+  Set<StyleSheet> _dependencies(var libraryInfo, {Set<StyleSheet> seen}) {
+    if (seen == null) seen = new Set();
+
+    // Used to resolve all pathing information.
+    var inputUrl = libraryInfo is FileInfo
+        ? libraryInfo.inputUrl
+        : (libraryInfo as ComponentInfo).declaringFile.inputUrl;
+
+    for (var styleSheet in libraryInfo.styleSheets) {
+      if (!seen.contains(styleSheet)) {
+        // TODO(terry): VM uses expandos to implement hashes.  Currently, it's a
+        //              linear (not constant) time cost (see dartbug.com/5746).
+        //              If this bug isn't fixed and performance show's this a
+        //              a problem we'll need to implement our own hashCode or
+        //              use a different key for better perf.
+        // Add the stylesheet.
+        seen.add(styleSheet);
+
+        // Any other imports in this stylesheet?
+        var urlInfos = findImportsInStyleSheet(styleSheet, packageRoot,
+            inputUrl, _messages);
+
+        // Process other imports in this stylesheets.
+        for (var importSS in urlInfos) {
+          var importInfo = info[importSS.resolvedPath];
+          if (importInfo != null) {
+            // Add all known stylesheets processed.
+            seen.addAll(importInfo.styleSheets);
+            // Find dependencies for stylesheet referenced with a
+            // @import
+            for (var ss in importInfo.styleSheets) {
+              var urls = findImportsInStyleSheet(ss, packageRoot, inputUrl,
+                  _messages);
+              for (var url in urls) {
+                _dependencies(info[url.resolvedPath], seen: seen);
+              }
+            }
+          }
+        }
+      }
+    }
+
+    return seen;
+  }
+}
+
+/**
+ * Find var- definitions in a style sheet.
+ * [found] list of known definitions.
+ */
+class _VarDefinitions extends Visitor {
+  final Map<String, VarDefinition> found = new Map();
+
+  void visitTree(StyleSheet tree) {
+    visitStyleSheet(tree);
+  }
+
+  visitVarDefinition(VarDefinition node) {
+    // Replace with latest variable definition.
+    found[node.definedName] = node;
+    super.visitVarDefinition(node);
+  }
+
+  void visitVarDefinitionDirective(VarDefinitionDirective node) {
+    visitVarDefinition(node.def);
+  }
+}
+
+/**
+ * Resolve any CSS expression which contains a var() usage to the ultimate real
+ * CSS expression value e.g.,
+ *
+ *    var-one: var(two);
+ *    var-two: #ff00ff;
+ *
+ *    .test {
+ *      color: var(one);
+ *    }
+ *
+ * then .test's color would be #ff00ff
+ */
+class _ResolveVarUsages extends Visitor {
+  final Map<String, VarDefinition> varDefs;
+  bool inVarDefinition = false;
+  bool inUsage = false;
+  Expressions currentExpressions;
+
+  _ResolveVarUsages(this.varDefs);
+
+  void visitTree(StyleSheet tree) {
+    visitStyleSheet(tree);
+  }
+
+  void visitVarDefinition(VarDefinition varDef) {
+    inVarDefinition = true;
+    super.visitVarDefinition(varDef);
+    inVarDefinition = false;
+  }
+
+  void visitExpressions(Expressions node) {
+    currentExpressions = node;
+    super.visitExpressions(node);
+    currentExpressions = null;
+  }
+
+  void visitVarUsage(VarUsage node) {
+    // Don't process other var() inside of a varUsage.  That implies that the
+    // default is a var() too.  Also, don't process any var() inside of a
+    // varDefinition (they're just place holders until we've resolved all real
+    // usages.
+    if (!inUsage && !inVarDefinition && currentExpressions != null) {
+      var expressions = currentExpressions.expressions;
+      var index = expressions.indexOf(node);
+      assert(index >= 0);
+      var def = varDefs[node.name];
+      if (def != null) {
+        // Found a VarDefinition use it.
+        _resolveVarUsage(currentExpressions.expressions, index, def);
+      } else if (node.defaultValues.any((e) => e is VarUsage)) {
+        // Don't have a VarDefinition need to use default values resolve all
+        // default values.
+        var terminalDefaults = [];
+        for (var defaultValue in node.defaultValues) {
+          terminalDefaults.addAll(resolveUsageTerminal(defaultValue));
+        }
+        expressions.replaceRange(index, index + 1, terminalDefaults);
+      } else {
+        // No VarDefinition but default value is a terminal expression; use it.
+        expressions.replaceRange(index, index + 1, node.defaultValues);
+      }
+    }
+
+    inUsage = true;
+    super.visitVarUsage(node);
+    inUsage = false;
+  }
+
+  List<Expression> resolveUsageTerminal(VarUsage usage) {
+    var result = [];
+
+    var varDef = varDefs[usage.name];
+    var expressions;
+    if (varDef == null) {
+      // VarDefinition not found try the defaultValues.
+      expressions = usage.defaultValues;
+    } else {
+      // Use the VarDefinition found.
+      expressions = (varDef.expression as Expressions).expressions;
+    }
+
+    for (var expr in expressions) {
+      if (expr is VarUsage) {
+        // Get terminal value.
+        result.addAll(resolveUsageTerminal(expr));
+      }
+    }
+
+    // We're at a terminal just return the VarDefinition expression.
+    if (result.isEmpty && varDef != null) {
+      result = (varDef.expression as Expressions).expressions;
+    }
+
+    return result;
+  }
+
+  _resolveVarUsage(List<Expressions> expressions, int index,
+                   VarDefinition def) {
+    var defExpressions = (def.expression as Expressions).expressions;
+    expressions.replaceRange(index, index + 1, defExpressions);
+  }
+}
+
+/** Remove all var definitions. */
+class _RemoveVarDefinitions extends Visitor {
+  void visitTree(StyleSheet tree) {
+    visitStyleSheet(tree);
+  }
+
+  void visitStyleSheet(StyleSheet ss) {
+    ss.topLevels.removeWhere((e) => e is VarDefinitionDirective);
+    super.visitStyleSheet(ss);
+  }
+
+  void visitDeclarationGroup(DeclarationGroup node) {
+    node.declarations.removeWhere((e) => e is VarDefinition);
+    super.visitDeclarationGroup(node);
+  }
+}
+
+/**
+ * Process all selectors looking for a pseudo-element in a selector.  If the
+ * name is found in our list of known pseudo-elements.  Known pseudo-elements
+ * are built when parsing a component looking for an attribute named "pseudo".
+ * The value of the pseudo attribute is the name of the custom pseudo-element.
+ * The name is mangled so Dart/JS can't directly access the pseudo-element only
+ * CSS can access a custom pseudo-element (and see issue #510, querying needs
+ * access to custom pseudo-elements).
+ *
+ * Change the custom pseudo-element to be a child of the pseudo attribute's
+ * mangled custom pseudo element name. e.g,
+ *
+ *    .test::x-box
+ *
+ * would become:
+ *
+ *    .test > *[pseudo="x-box_2"]
+ */
+class _PseudoElementExpander extends Visitor {
+  final Map<String, String> _pseudoElements;
+
+  _PseudoElementExpander(this._pseudoElements);
+
+  void visitTree(StyleSheet tree) => visitStyleSheet(tree);
+
+  visitSelector(Selector node) {
+    var selectors = node.simpleSelectorSequences;
+    for (var index = 0; index < selectors.length; index++) {
+      var selector = selectors[index].simpleSelector;
+      if (selector is PseudoElementSelector) {
+        if (_pseudoElements.containsKey(selector.name)) {
+          // Pseudo Element is a custom element.
+          var mangledName = _pseudoElements[selector.name];
+
+          var span = selectors[index].span;
+
+          var attrSelector = new AttributeSelector(
+              new Identifier('pseudo', span), css.TokenKind.EQUALS,
+              mangledName, span);
+          // The wildcard * namespace selector.
+          var wildCard = new ElementSelector(new Wildcard(span), span);
+          selectors[index] = new SimpleSelectorSequence(wildCard, span,
+                  css.TokenKind.COMBINATOR_GREATER);
+          selectors.insert(++index,
+              new SimpleSelectorSequence(attrSelector, span));
+        }
+      }
+    }
+  }
+}
+
+List<UrlInfo> findImportsInStyleSheet(StyleSheet styleSheet,
+    String packageRoot, UrlInfo inputUrl, Messages messages) {
+  var visitor = new _CssImports(packageRoot, inputUrl, messages);
+  visitor.visitTree(styleSheet);
+  return visitor.urlInfos;
+}
+
+/**
+ * Find any imports in the style sheet; normalize the style sheet href and
+ * return a list of all fully qualified CSS files.
+ */
+class _CssImports extends Visitor {
+  final String packageRoot;
+
+  /** Input url of the css file, used to normalize relative import urls. */
+  final UrlInfo inputUrl;
+
+  /** List of all imported style sheets. */
+  final List<UrlInfo> urlInfos = [];
+
+  final Messages _messages;
+
+  _CssImports(this.packageRoot, this.inputUrl, this._messages);
+
+  void visitTree(StyleSheet tree) {
+    visitStyleSheet(tree);
+  }
+
+  void visitImportDirective(ImportDirective node) {
+    var urlInfo = UrlInfo.resolve(node.import, inputUrl,
+        node.span, packageRoot, _messages, ignoreAbsolute: true);
+    if (urlInfo == null) return;
+    urlInfos.add(urlInfo);
+  }
+}
+
+StyleSheet parseCss(String content, Messages messages,
+    CompilerOptions options) {
+  if (content.trim().isEmpty) return null;
+
+  var errors = [];
+
+  // TODO(terry): Add --checked when fully implemented and error handling.
+  var stylesheet = css.parse(content, errors: errors, options:
+      [options.warningsAsErrors ? '--warnings_as_errors' : '', 'memory']);
+
+  // Note: errors aren't fatal in HTML (unless strict mode is on).
+  // So just print them as warnings.
+  for (var e in errors) {
+    messages.warning(e.message, e.span);
+  }
+
+  return stylesheet;
+}
+
+/** Find terminal definition (non VarUsage implies real CSS value). */
+VarDefinition _findTerminalVarDefinition(Map<String, VarDefinition> varDefs,
+                                        VarDefinition varDef) {
+  var expressions = varDef.expression as Expressions;
+  for (var expr in expressions.expressions) {
+    if (expr is VarUsage) {
+      var usageName = (expr as VarUsage).name;
+      var foundDef = varDefs[usageName];
+
+      // If foundDef is unknown check if defaultValues; if it exist then resolve
+      // to terminal value.
+      if (foundDef == null) {
+        // We're either a VarUsage or terminal definition if in varDefs;
+        // either way replace VarUsage with it's default value because the
+        // VarDefinition isn't found.
+        var defaultValues = (expr as VarUsage).defaultValues;
+        var replaceExprs = expressions.expressions;
+        assert(replaceExprs.length == 1);
+        replaceExprs.replaceRange(0, 1, defaultValues);
+        return varDef;
+      }
+      if (foundDef is VarDefinition) {
+        return _findTerminalVarDefinition(varDefs, foundDef);
+      }
+    } else {
+      // Return real CSS property.
+      return varDef;
+    }
+  }
+
+  // Didn't point to a var definition that existed.
+  return varDef;
+}
+
+/**
+ * Find urls imported inside style tags under [info].  If [info] is a FileInfo
+ * then process only style tags in the body (don't process any style tags in a
+ * component).  If [info] is a ComponentInfo only process style tags inside of
+ * the element are processed.  For an [info] of type FileInfo [node] is the
+ * file's document and for an [info] of type ComponentInfo then [node] is the
+ * component's element tag.
+ */
+List<UrlInfo> findUrlsImported(LibraryInfo info, UrlInfo inputUrl,
+    String packageRoot, Node node, Messages messages, CompilerOptions options) {
+  // Process any @imports inside of the <style> tag.
+  var styleProcessor =
+      new _CssStyleTag(packageRoot, info, inputUrl, messages, options);
+  styleProcessor.visit(node);
+  return styleProcessor.imports;
+}
+
+/* Process CSS inside of a style tag. */
+class _CssStyleTag extends TreeVisitor {
+  final String _packageRoot;
+
+  /** Either a FileInfo or ComponentInfo. */
+  final LibraryInfo _info;
+  final Messages _messages;
+  final CompilerOptions _options;
+
+  /**
+   * Path of the declaring file, for a [_info] of type FileInfo it's the file's
+   * path for a type ComponentInfo it's the declaring file path.
+   */
+  final UrlInfo _inputUrl;
+
+  /** List of @imports found. */
+  List<UrlInfo> imports = [];
+
+  _CssStyleTag(this._packageRoot, this._info, this._inputUrl, this._messages,
+      this._options);
+
+  void visitElement(Element node) {
+    // Don't process any style tags inside of element if we're processing a
+    // FileInfo.  The style tags inside of a component defintion will be
+    // processed when _info is a ComponentInfo.
+    if (node.tagName == 'polymer-element' && _info is FileInfo) return;
+    if (node.tagName == 'style') {
+      // Parse the contents of the scoped style tag.
+      var styleSheet = parseCss(node.nodes.single.value, _messages, _options);
+      if (styleSheet != null) {
+        _info.styleSheets.add(styleSheet);
+
+        // Find all imports return list of @imports in this style tag.
+        var urlInfos = findImportsInStyleSheet(styleSheet, _packageRoot,
+            _inputUrl, _messages);
+        imports.addAll(urlInfos);
+      }
+    }
+    super.visitElement(node);
+  }
+}
diff --git a/pkg/polymer/lib/src/css_emitters.dart b/pkg/polymer/lib/src/css_emitters.dart
new file mode 100644
index 0000000..d1863f5
--- /dev/null
+++ b/pkg/polymer/lib/src/css_emitters.dart
@@ -0,0 +1,155 @@
+// Copyright (c) 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 polymer.src.css_emitters;
+
+import 'package:csslib/visitor.dart' show Visitor, CssPrinter, ElementSelector,
+       UriTerm, Selector, HostDirective, SimpleSelectorSequence, StyleSheet;
+
+import 'info.dart';
+import 'paths.dart' show PathMapper;
+import 'utils.dart';
+
+void rewriteCssUris(PathMapper pathMapper, String cssPath, bool rewriteUrls,
+    StyleSheet styleSheet) {
+  new _UriVisitor(pathMapper, cssPath, rewriteUrls).visitTree(styleSheet);
+}
+
+/** Compute each CSS URI resource relative from the generated CSS file. */
+class _UriVisitor extends Visitor {
+  /**
+   * Relative path from the output css file to the location of the original
+   * css file that contained the URI to each resource.
+   */
+  final String _pathToOriginalCss;
+
+  factory _UriVisitor(PathMapper pathMapper, String cssPath, bool rewriteUrl) {
+    var cssDir = path.dirname(cssPath);
+    var outCssDir = rewriteUrl ? pathMapper.outputDirPath(cssPath)
+        : path.dirname(cssPath);
+    return new _UriVisitor._internal(path.relative(cssDir, from: outCssDir));
+  }
+
+  _UriVisitor._internal(this._pathToOriginalCss);
+
+  void visitUriTerm(UriTerm node) {
+    // Don't touch URIs that have any scheme (http, etc.).
+    var uri = Uri.parse(node.text);
+    if (uri.host != '') return;
+    if (uri.scheme != '' && uri.scheme != 'package') return;
+
+    node.text = pathToUrl(
+        path.normalize(path.join(_pathToOriginalCss, node.text)));
+  }
+}
+
+
+/** Emit the contents of the style tag outside of a component. */
+String emitStyleSheet(StyleSheet ss, FileInfo file) =>
+  (new _CssEmitter(file.components.keys.toSet())
+      ..visitTree(ss, pretty: true)).toString();
+
+/** Emit a component's style tag content emulating scoped css. */
+String emitComponentStyleSheet(StyleSheet ss, String tagName) =>
+    (new _ComponentCssEmitter(tagName)..visitTree(ss, pretty: true)).toString();
+
+String emitOriginalCss(StyleSheet css) =>
+    (new CssPrinter()..visitTree(css)).toString();
+
+/** Only x-tag name element selectors are emitted as [is="x-"]. */
+class _CssEmitter extends CssPrinter {
+  final Set _componentsTag;
+  _CssEmitter(this._componentsTag);
+
+  void visitElementSelector(ElementSelector node) {
+    // If element selector is a component's tag name, then change selector to
+    // find element who's is attribute's the component's name.
+    if (_componentsTag.contains(node.name)) {
+      emit('[is="${node.name}"]');
+      return;
+    }
+    super.visitElementSelector(node);
+  }
+}
+
+/**
+ * Emits a css stylesheet applying rules to emulate scoped css. The rules adjust
+ * element selectors to include the component's tag name.
+ */
+class _ComponentCssEmitter extends CssPrinter {
+  final String _componentTagName;
+  bool _inHostDirective = false;
+  bool _selectorStartInHostDirective = false;
+
+  _ComponentCssEmitter(this._componentTagName);
+
+  /** Is the element selector an x-tag name. */
+  bool _isSelectorElementXTag(Selector node) {
+    if (node.simpleSelectorSequences.length > 0) {
+      var selector = node.simpleSelectorSequences[0].simpleSelector;
+      return selector is ElementSelector && selector.name == _componentTagName;
+    }
+    return false;
+  }
+
+  void visitSelector(Selector node) {
+    // If the selector starts with an x-tag name don't emit it twice.
+    if (!_isSelectorElementXTag(node)) {
+      if (_inHostDirective) {
+        // Style the element that's hosting the component, therefore don't emit
+        // the descendent combinator (first space after the [is="x-..."]).
+        emit('[is="$_componentTagName"]');
+        // Signal that first simpleSelector must be checked.
+        _selectorStartInHostDirective = true;
+      } else {
+        // Emit its scoped as a descendent (space at end).
+        emit('[is="$_componentTagName"] ');
+      }
+    }
+    super.visitSelector(node);
+  }
+
+  /**
+   * If first simple selector of a ruleset in a @host directive is a wildcard
+   * then don't emit the wildcard.
+   */
+  void visitSimpleSelectorSequence(SimpleSelectorSequence node) {
+    if (_selectorStartInHostDirective) {
+      _selectorStartInHostDirective = false;
+      if (node.simpleSelector.isWildcard) {
+        // Skip the wildcard if first item in the sequence.
+        return;
+      }
+      assert(node.isCombinatorNone);
+    }
+
+    super.visitSimpleSelectorSequence(node);
+  }
+
+  void visitElementSelector(ElementSelector node) {
+    // If element selector is the component's tag name, then change selector to
+    // find element who's is attribute is the component's name.
+    if (_componentTagName == node.name) {
+      emit('[is="$_componentTagName"]');
+      return;
+    }
+    super.visitElementSelector(node);
+  }
+
+  /**
+   * If we're polyfilling scoped styles the @host directive is stripped.  Any
+   * ruleset(s) processed in an @host will fixup the first selector.  See
+   * visitSelector and visitSimpleSelectorSequence in this class, they adjust
+   * the selectors so it styles the element hosting the compopnent.
+   */
+  void visitHostDirective(HostDirective node) {
+    _inHostDirective = true;
+    emit('/* @host */');
+    for (var ruleset in node.rulesets) {
+      ruleset.visit(this);
+    }
+    _inHostDirective = false;
+    emit('/* end of @host */\n');
+  }
+}
diff --git a/pkg/polymer/lib/src/custom_tag_name.dart b/pkg/polymer/lib/src/custom_tag_name.dart
new file mode 100644
index 0000000..637b937
--- /dev/null
+++ b/pkg/polymer/lib/src/custom_tag_name.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.
+
+library polymer.src.custom_tag_name;
+
+/**
+ * Returns true if this is a valid custom element name. See:
+ * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-custom-element-name>
+ */
+bool isCustomTag(String name) {
+  if (name == null || !name.contains('-')) return false;
+
+  // These names have meaning in SVG or MathML, so they aren't allowed as custom
+  // tags.
+  var invalidNames = const {
+    'annotation-xml': '',
+    'color-profile': '',
+    'font-face': '',
+    'font-face-src': '',
+    'font-face-uri': '',
+    'font-face-format': '',
+    'font-face-name': '',
+    'missing-glyph': '',
+  };
+  return !invalidNames.containsKey(name);
+}
diff --git a/pkg/polymer/lib/src/dart_parser.dart b/pkg/polymer/lib/src/dart_parser.dart
new file mode 100644
index 0000000..a2f44c3
--- /dev/null
+++ b/pkg/polymer/lib/src/dart_parser.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Parser for Dart code based on the experimental analyzer.
+ */
+library dart_parser;
+
+import 'package:analyzer_experimental/src/generated/ast.dart';
+import 'package:analyzer_experimental/src/generated/error.dart';
+import 'package:analyzer_experimental/src/generated/parser.dart';
+import 'package:analyzer_experimental/src/generated/scanner.dart';
+import 'package:source_maps/span.dart' show SourceFile, SourceFileSegment, Location;
+import 'utils.dart' show escapeDartString;
+
+/** Information extracted from a source Dart file. */
+class DartCodeInfo {
+
+  /** Library qualified identifier, if any. */
+  final String libraryName;
+
+  /** Library which the code is part-of, if any. */
+  final String partOf;
+
+  /** Declared imports, exports, and parts. */
+  final List<Directive> directives;
+
+  /** Source file representation used to compute source map information. */
+  final SourceFile sourceFile;
+
+  /** The parsed code. */
+  final CompilationUnit compilationUnit;
+
+  /** The full source code. */
+  final String code;
+
+  DartCodeInfo(this.libraryName, this.partOf, this.directives, code,
+      this.sourceFile, [compilationUnit])
+      : this.code = code,
+        this.compilationUnit = compilationUnit == null
+          ? _parseCompilationUnit(code) : compilationUnit;
+
+  bool get isPart =>
+      compilationUnit.directives.any((d) => d is PartOfDirective);
+
+  int get directivesEnd {
+    if (compilationUnit.directives.length == 0) return 0;
+    return compilationUnit.directives.last.end;
+  }
+
+  /**
+   * The position of the first "part" directive. If none is found,
+   * this behaves like [directivesEnd].
+   */
+  int get firstPartOffset {
+    for (var directive in compilationUnit.directives) {
+      if (directive is PartDirective) return directive.offset;
+    }
+    // No part directives, just return directives end.
+    return directivesEnd;
+  }
+
+  /** Gets the code after the [directives]. */
+  String codeAfterDirectives() => code.substring(directivesEnd);
+
+  ClassDeclaration findClass(String name) {
+    for (var decl in compilationUnit.declarations) {
+      if (decl is ClassDeclaration) {
+        if (decl.name.name == name) return decl;
+      }
+    }
+    return null;
+  }
+}
+
+SimpleStringLiteral createStringLiteral(String contents) {
+  var lexeme = "'${escapeDartString(contents)}'";
+  var token = new StringToken(TokenType.STRING, lexeme, null);
+  return new SimpleStringLiteral.full(token, contents);
+}
+
+
+/**
+ * Parse and extract top-level directives from [code].
+ *
+ */
+// TODO(sigmund): log emitted error/warning messages
+DartCodeInfo parseDartCode(String path, String code, [Location offset]) {
+  var unit = _parseCompilationUnit(code);
+
+  // Extract some information from the compilation unit.
+  String libraryName, partName;
+  var directives = [];
+  int directiveEnd = 0;
+  for (var directive in unit.directives) {
+    if (directive is LibraryDirective) {
+      libraryName = directive.name.name;
+    } else if (directive is PartOfDirective) {
+      partName = directive.libraryName.name;
+    } else {
+      assert(directive is UriBasedDirective);
+      // Normalize the library URI.
+      var uriNode = directive.uri;
+      if (uriNode is! SimpleStringLiteral) {
+        String uri = uriNode.accept(new ConstantEvaluator());
+        directive.uri = createStringLiteral(uri);
+      }
+      directives.add(directive);
+    }
+  }
+
+  var sourceFile = offset == null
+      ? new SourceFile.text(path, code)
+      : new SourceFileSegment(path, code, offset);
+
+  return new DartCodeInfo(libraryName, partName, directives, code,
+      sourceFile, unit);
+}
+
+CompilationUnit _parseCompilationUnit(String code) {
+  var errorListener = new _ErrorCollector();
+  var scanner = new StringScanner(null, code, errorListener);
+  var token = scanner.tokenize();
+  var parser = new Parser(null, errorListener);
+  return parser.parseCompilationUnit(token);
+}
+
+class _ErrorCollector extends AnalysisErrorListener {
+  final errors = new List<AnalysisError>();
+  onError(error) => errors.add(error);
+}
diff --git a/pkg/polymer/lib/src/emitters.dart b/pkg/polymer/lib/src/emitters.dart
new file mode 100644
index 0000000..dbd6816
--- /dev/null
+++ b/pkg/polymer/lib/src/emitters.dart
@@ -0,0 +1,249 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/** Collects several code emitters for the template tool. */
+library emitters;
+
+import 'package:html5lib/dom.dart';
+import 'package:html5lib/dom_parsing.dart' show TreeVisitor;
+import 'package:html5lib/parser.dart' show parseFragment;
+import 'package:source_maps/printer.dart';
+import 'package:source_maps/refactor.dart';
+
+import 'compiler_options.dart';
+import 'css_emitters.dart' show emitStyleSheet, emitOriginalCss;
+import 'html5_utils.dart';
+import 'info.dart' show ComponentInfo, FileInfo, GlobalInfo;
+import 'messages.dart';
+import 'paths.dart' show PathMapper;
+import 'utils.dart' show escapeDartString, path;
+
+/** Generates the class corresponding to a single web component. */
+NestedPrinter emitPolymerElement(ComponentInfo info, PathMapper pathMapper,
+    TextEditTransaction transaction, CompilerOptions options) {
+  if (info.classDeclaration == null) return null;
+
+  var codeInfo = info.userCode;
+  if (transaction == null) {
+    // TODO(sigmund): avoid emitting this file if we don't need to do any
+    // modifications (e.g. no @observable and not adding the libraryName).
+    transaction = new TextEditTransaction(codeInfo.code, codeInfo.sourceFile);
+  }
+  if (codeInfo.libraryName == null) {
+    // For deploy, we need to import the library associated with the component,
+    // so we need to ensure there is a library directive.
+    var libraryName = info.tagName.replaceAll(new RegExp('[-./]'), '_');
+    transaction.edit(0, 0, 'library $libraryName;');
+  }
+  return transaction.commit();
+}
+
+/** The code that will be used to bootstrap the application. */
+NestedPrinter generateBootstrapCode(
+    FileInfo info, FileInfo userMainInfo, GlobalInfo global,
+    PathMapper pathMapper, CompilerOptions options) {
+
+  var printer = new NestedPrinter(0)
+      ..addLine('library app_bootstrap;')
+      ..addLine('')
+      ..addLine("import 'package:polymer/polymer.dart';")
+      ..addLine("import 'dart:mirrors' show currentMirrorSystem;");
+
+  int i = 0;
+  for (var c in global.components.values) {
+    if (c.hasConflict) continue;
+    printer.addLine("import '${pathMapper.importUrlFor(info, c)}' as i$i;");
+    i++;
+  }
+  if (userMainInfo.userCode != null) {
+    printer..addLine("import '${pathMapper.importUrlFor(info, userMainInfo)}' "
+        "as i$i;\n");
+  }
+
+  printer..addLine('')
+      ..addLine('void main() {')
+      ..indent += 1
+      ..addLine("initPolymer([")
+      ..indent += 2;
+
+  for (var c in global.components.values) {
+    if (c.hasConflict) continue;
+    printer.addLine("'${pathMapper.importUrlFor(info, c)}',");
+  }
+
+  if (userMainInfo.userCode != null) {
+    printer.addLine("'${pathMapper.importUrlFor(info, userMainInfo)}',");
+  }
+
+  return printer
+      ..indent -= 1
+      ..addLine('],')
+      ..addLine(
+          "currentMirrorSystem().findLibrary(const Symbol('app_bootstrap'))")
+      ..indent += 2
+      ..addLine(".first.uri.toString());")
+      ..indent -= 4
+      ..addLine('}');
+}
+
+
+/**
+ * Rewrites attributes that contain relative URL (excluding src urls in script
+ * and link tags which are already rewritten by other parts of the compiler).
+*/
+class _AttributeUrlTransform extends TreeVisitor {
+  final String filePath;
+  final PathMapper pathMapper;
+
+  _AttributeUrlTransform(this.filePath, this.pathMapper);
+
+  visitElement(Element node) {
+    if (node.tagName == 'script') return;
+    if (node.tagName == 'link') return;
+
+    for (var key in node.attributes.keys) {
+      if (urlAttributes.contains(key)) {
+        node.attributes[key] =
+            pathMapper.transformUrl(filePath, node.attributes[key]);
+      }
+    }
+    super.visitElement(node);
+  }
+}
+
+final _shadowDomJS = new RegExp(r'shadowdom\..*\.js', caseSensitive: false);
+final _bootJS = new RegExp(r'.*/polymer/boot.js', caseSensitive: false);
+
+/** Trim down the html for the main html page. */
+void transformMainHtml(Document document, FileInfo fileInfo,
+    PathMapper pathMapper, bool hasCss, bool rewriteUrls,
+    Messages messages, GlobalInfo global, String bootstrapOutName) {
+  var filePath = fileInfo.inputUrl.resolvedPath;
+
+  var dartLoaderTag = null;
+  bool shadowDomFound = false;
+  for (var tag in document.queryAll('script')) {
+    var src = tag.attributes['src'];
+    if (src != null) {
+      var last = src.split('/').last;
+      if (last == 'dart.js' || last == 'testing.js') {
+        dartLoaderTag = tag;
+      } else if (_shadowDomJS.hasMatch(last)) {
+        shadowDomFound = true;
+      }
+    }
+    if (tag.attributes['type'] == 'application/dart') {
+      tag.remove();
+    } else if (src != null) {
+      if (_bootJS.hasMatch(src)) {
+        tag.remove();
+      } else if (rewriteUrls) {
+        tag.attributes["src"] = pathMapper.transformUrl(filePath, src);
+      }
+    }
+  }
+
+  for (var tag in document.queryAll('link')) {
+    var href = tag.attributes['href'];
+    var rel = tag.attributes['rel'];
+    if (rel == 'component' || rel == 'components' || rel == 'import') {
+      tag.remove();
+    } else if (href != null && rewriteUrls && !hasCss) {
+      // Only rewrite URL if rewrite on and we're not CSS polyfilling.
+      tag.attributes['href'] = pathMapper.transformUrl(filePath, href);
+    }
+  }
+
+  if (rewriteUrls) {
+    // Transform any element's attribute which is a relative URL.
+    new _AttributeUrlTransform(filePath, pathMapper).visit(document);
+  }
+
+  if (hasCss) {
+    var newCss = pathMapper.mangle(path.basename(filePath), '.css', true);
+    var linkElem = new Element.html(
+        '<link rel="stylesheet" type="text/css" href="$newCss">');
+    document.head.insertBefore(linkElem, null);
+  }
+
+  var styles = document.queryAll('style');
+  if (styles.length > 0) {
+    var allCss = new StringBuffer();
+    fileInfo.styleSheets.forEach((styleSheet) =>
+        allCss.write(emitStyleSheet(styleSheet, fileInfo)));
+    styles[0].nodes.clear();
+    styles[0].nodes.add(new Text(allCss.toString()));
+    for (var i = styles.length - 1; i > 0 ; i--) {
+      styles[i].remove();
+    }
+  }
+
+  // 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>'));
+
+  // Move all <element> declarations to the main HTML file
+  // TODO(sigmund): remove this once we have HTMLImports implemented.
+  for (var c in global.components.values) {
+    document.body.nodes.insert(0, new Text('\n'));
+    var fragment = c.element;
+    for (var tag in fragment.queryAll('script')) {
+      // TODO(sigmund): leave script tags around when we start using "boot.js"
+      if (tag.attributes['type'] == 'application/dart') {
+        tag.remove();
+      }
+    }
+    document.body.nodes.insert(0, fragment);
+  }
+
+  if (!shadowDomFound) {
+    // TODO(jmesserly): we probably shouldn't add this automatically.
+    document.body.nodes.add(parseFragment('<script type="text/javascript" '
+        'src="packages/shadow_dom/shadow_dom.debug.js"></script>\n'));
+
+    // JS interop code required for Polymer CSS shimming.
+    document.body.nodes.add(parseFragment('<script type="text/javascript" '
+        'src="packages/browser/interop.js"></script>\n'));
+  }
+
+  var bootstrapScript = parseFragment(
+        '<script type="application/dart" src="$bootstrapOutName"></script>');
+  if (dartLoaderTag == null) {
+    document.body.nodes.add(bootstrapScript);
+    // TODO(jmesserly): turn this warning on.
+    //messages.warning('Missing script to load Dart. '
+    //    'Please add this line to your HTML file: $dartLoader',
+    //    document.body.sourceSpan);
+    // TODO(sigmund): switch to 'boot.js'
+    document.body.nodes.add(parseFragment('<script type="text/javascript" '
+        'src="packages/browser/dart.js"></script>\n'));
+  } else if (dartLoaderTag.parent != document.body) {
+    document.body.nodes.add(bootstrapScript);
+  } else {
+    document.body.insertBefore(bootstrapScript, dartLoaderTag);
+  }
+
+  // Insert the "auto-generated" comment after the doctype, otherwise IE will
+  // go into quirks mode.
+  int commentIndex = 0;
+  DocumentType doctype =
+      document.nodes.firstWhere((n) => n is DocumentType, orElse: () => null);
+  if (doctype != null) {
+    commentIndex = document.nodes.indexOf(doctype) + 1;
+    // TODO(jmesserly): the html5lib parser emits a warning for missing
+    // doctype, but it allows you to put it after comments. Presumably they do
+    // this because some comments won't force IE into quirks mode (sigh). See
+    // this link for more info:
+    //     http://bugzilla.validator.nu/show_bug.cgi?id=836
+    // For simplicity we emit the warning always, like validator.nu does.
+    if (doctype.tagName != 'html' || commentIndex != 1) {
+      messages.warning('file should start with <!DOCTYPE html> '
+          'to avoid the possibility of it being parsed in quirks mode in IE. '
+          'See http://www.w3.org/TR/html5-diff/#doctype', doctype.sourceSpan);
+    }
+  }
+  document.nodes.insert(commentIndex, parseFragment(
+      '\n<!-- This file was auto-generated from $filePath. -->\n'));
+}
diff --git a/pkg/polymer/lib/src/file_system.dart b/pkg/polymer/lib/src/file_system.dart
new file mode 100644
index 0000000..c6af55c
--- /dev/null
+++ b/pkg/polymer/lib/src/file_system.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/** Abstraction for file systems and utility functions to manipulate paths. */
+library file_system;
+
+import 'dart:async';
+
+/**
+ * Abstraction around file system access to work in a variety of different
+ * environments.
+ */
+abstract class FileSystem {
+  /**
+   * Apply all pending writes.  Until this method is called, writeString is not
+   * guaranteed to have any observable impact.
+   */
+  Future flush();
+
+  /**
+   * Reads bytes if possible, but falls back to text if running in a browser.
+   * Return type is either [Future<List<int>>] or [Future<String>].
+   */
+  Future readTextOrBytes(String path);
+
+  /* Like [readTextOrBytes], but decodes bytes as UTF-8. Used for Dart code. */
+  Future<String> readText(String path);
+
+  /**
+   * Writes [text] to file at [path]. Call flush to insure that changes are
+   * visible.
+   */
+  void writeString(String path, String text);
+}
diff --git a/pkg/polymer/lib/src/file_system/console.dart b/pkg/polymer/lib/src/file_system/console.dart
new file mode 100644
index 0000000..6776745
--- /dev/null
+++ b/pkg/polymer/lib/src/file_system/console.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 console;
+
+import 'dart:async';
+import 'dart:io';
+import 'dart:utf';
+import 'package:polymer/src/file_system.dart';
+
+/** File system implementation for console VM (i.e. no browser). */
+class ConsoleFileSystem implements FileSystem {
+
+  /** Pending futures for file write requests. */
+  final _pending = <String, Future>{};
+
+  Future flush() => Future.wait(_pending.values.toList());
+
+  void writeString(String path, String text) {
+    if(!_pending.containsKey(path)) {
+      _pending[path] = new File(path).open(mode: FileMode.WRITE)
+          .then((file) => file.writeString(text))
+          .then((file) => file.close())
+          .whenComplete(() { _pending.remove(path); });
+    }
+  }
+
+  // TODO(jmesserly): even better would be to pass the RandomAccessFile directly
+  // to html5lib. This will require a further restructuring of FileSystem.
+  // Probably it just needs "readHtml" and "readText" methods.
+  Future<List<int>> readTextOrBytes(String path) {
+    return new File(path).open().then(
+        (file) => file.length().then((length) {
+      // TODO(jmesserly): is this guaranteed to read all of the bytes?
+      var buffer = new List<int>(length);
+      return file.readInto(buffer, 0, length)
+          .then((_) => file.close())
+          .then((_) => buffer);
+    }));
+  }
+
+  // TODO(jmesserly): do we support any encoding other than UTF-8 for Dart?
+  Future<String> readText(String path) {
+    return readTextOrBytes(path).then(decodeUtf8);
+  }
+}
diff --git a/pkg/polymer/lib/src/files.dart b/pkg/polymer/lib/src/files.dart
new file mode 100644
index 0000000..9fea763
--- /dev/null
+++ b/pkg/polymer/lib/src/files.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 files;
+
+import 'package:html5lib/dom.dart';
+
+/** An input file to process by the template compiler. */
+class SourceFile {
+  static const int HTML = 1;
+  static const int DART = 2;
+  static const int STYLESHEET = 3;
+
+  final String path;
+  final int type;
+
+  Document document;
+
+  /** Dart code or contents of a linked style sheet. */
+  String code;
+
+  SourceFile(this.path, {this.type: HTML});
+
+  bool get isDart => type == DART;
+  bool get isHtml => type == HTML;
+  bool get isStyleSheet => type == STYLESHEET;
+
+  String toString() => "#<SourceFile $path>";
+}
+
+/** An output file to generated by the template compiler. */
+class OutputFile {
+  final String path;
+  final String contents;
+
+  /**
+   * Path to the source file that was transformed into this OutputFile, `null`
+   * for files that are generated and do not correspond to an input
+   * [SourceFile].
+   */
+  final String source;
+
+  OutputFile(this.path, this.contents, {this.source});
+
+  String toString() => "#<OutputFile $path>";
+}
diff --git a/pkg/polymer/lib/src/html5_utils.dart b/pkg/polymer/lib/src/html5_utils.dart
new file mode 100644
index 0000000..391c12b
--- /dev/null
+++ b/pkg/polymer/lib/src/html5_utils.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// TODO(jmesserly): html5lib might be a better home for this.
+// But at the moment we only need it here.
+
+library html5_utils;
+
+/**
+ * HTML attributes that expect a URL value.
+ * <http://dev.w3.org/html5/spec/section-index.html#attributes-1>
+ *
+ * Every one of these attributes is a URL in every context where it is used in
+ * the DOM. The comments show every DOM element where an attribute can be used.
+ */
+const urlAttributes = const [
+  'action',     // in form
+  'background', // in body
+  'cite',       // in blockquote, del, ins, q
+  'data',       // in object
+  'formaction', // in button, input
+  'href',       // in a, area, link, base, command
+  'icon',       // in command
+  'manifest',   // in html
+  'poster',     // in video
+  'src',        // in audio, embed, iframe, img, input, script, source, track,
+                //    video
+];
diff --git a/pkg/polymer/lib/src/info.dart b/pkg/polymer/lib/src/info.dart
new file mode 100644
index 0000000..9a7b530
--- /dev/null
+++ b/pkg/polymer/lib/src/info.dart
@@ -0,0 +1,330 @@
+// Copyright (c) 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.
+
+/**
+ * Datatypes holding information extracted by the analyzer and used by later
+ * phases of the compiler.
+ */
+library polymer.src.info;
+
+import 'dart:collection' show SplayTreeMap, LinkedHashMap;
+
+import 'package:analyzer_experimental/src/generated/ast.dart';
+import 'package:csslib/visitor.dart';
+import 'package:html5lib/dom.dart';
+import 'package:source_maps/span.dart' show Span;
+
+import 'dart_parser.dart' show DartCodeInfo;
+import 'messages.dart';
+import 'summary.dart';
+import 'utils.dart';
+
+/**
+ * Information that is global. Roughly corresponds to `window` and `document`.
+ */
+class GlobalInfo {
+  /**
+   * Pseudo-element names exposed in a component via a pseudo attribute.
+   * The name is only available from CSS (not Dart code) so they're mangled.
+   * The same pseudo-element in different components maps to the same
+   * mangled name (as the pseudo-element is scoped inside of the component).
+   */
+  final Map<String, String> pseudoElements = <String, String>{};
+
+  /** All components declared in the application. */
+  final Map<String, ComponentInfo> components = new SplayTreeMap();
+}
+
+/**
+ * Information for any library-like input. We consider each HTML file a library,
+ * and each component declaration a library as well. Hence we use this as a base
+ * class for both [FileInfo] and [ComponentInfo]. Both HTML files and components
+ * can have .dart code provided by the user for top-level user scripts and
+ * component-level behavior code. This code can either be inlined in the HTML
+ * file or included in a script tag with the "src" attribute.
+ */
+abstract class LibraryInfo implements LibrarySummary {
+
+  /** Whether there is any code associated with the page/component. */
+  bool get codeAttached => inlinedCode != null || externalFile != null;
+
+  /**
+   * The actual inlined code. Use [userCode] if you want the code from this file
+   * or from an external file.
+   */
+  DartCodeInfo inlinedCode;
+
+  /**
+   * If this library's code was loaded using a script tag (e.g. in a component),
+   * [externalFile] has the path to such Dart file relative from the compiler's
+   * base directory.
+   */
+  UrlInfo externalFile;
+
+  /** Info asscociated with [externalFile], if any. */
+  FileInfo externalCode;
+
+  /**
+   * The inverse of [externalCode]. If this .dart file was imported via a script
+   * tag, this refers to the HTML file that imported it.
+   */
+  LibraryInfo htmlFile;
+
+  /** File where the top-level code was defined. */
+  UrlInfo get dartCodeUrl;
+
+  /**
+   * Name of the file that will hold any generated Dart code for this library
+   * unit. Note this is initialized after parsing.
+   */
+  String outputFilename;
+
+  /** Parsed cssSource. */
+  List<StyleSheet> styleSheets = [];
+
+  /** This is used in transforming Dart code to track modified files. */
+  bool modified = false;
+
+  /**
+   * This is used in transforming Dart code to compute files that reference
+   * [modified] files.
+   */
+  List<FileInfo> referencedBy = [];
+
+  /**
+   * Components used within this library unit. For [FileInfo] these are
+   * components used directly in the page. For [ComponentInfo] these are
+   * components used within their shadowed template.
+   */
+  final Map<ComponentSummary, bool> usedComponents =
+      new LinkedHashMap<ComponentSummary, bool>();
+
+  /**
+   * The actual code, either inlined or from an external file, or `null` if none
+   * was defined.
+   */
+  DartCodeInfo get userCode =>
+      externalCode != null ? externalCode.inlinedCode : inlinedCode;
+}
+
+/** Information extracted at the file-level. */
+class FileInfo extends LibraryInfo implements HtmlFileSummary {
+  /** Relative path to this file from the compiler's base directory. */
+  final UrlInfo inputUrl;
+
+  /**
+   * Whether this file should be treated as the entry point of the web app, i.e.
+   * the file users navigate to in their browser. This will be true if this file
+   * was passed in the command line to the dwc compiler, and the
+   * `--components_only` flag was omitted.
+   */
+  final bool isEntryPoint;
+
+  // TODO(terry): Ensure that that the libraryName is a valid identifier:
+  //              a..z || A..Z || _ [a..z || A..Z || 0..9 || _]*
+  String get libraryName =>
+      path.basename(inputUrl.resolvedPath).replaceAll('.', '_');
+
+  /** File where the top-level code was defined. */
+  UrlInfo get dartCodeUrl => externalFile != null ? externalFile : inputUrl;
+
+  /**
+   * All custom element definitions in this file. This may contain duplicates.
+   * Normally you should use [components] for lookup.
+   */
+  final List<ComponentInfo> declaredComponents = new List<ComponentInfo>();
+
+  /**
+   * All custom element definitions defined in this file or imported via
+   *`<link rel='components'>` tag. Maps from the tag name to the component
+   * information. This map is sorted by the tag name.
+   */
+  final Map<String, ComponentSummary> components =
+      new SplayTreeMap<String, ComponentSummary>();
+
+  /** Files imported with `<link rel="import">` */
+  final List<UrlInfo> componentLinks = <UrlInfo>[];
+
+  /** Files imported with `<link rel="stylesheet">` */
+  final List<UrlInfo> styleSheetHrefs = <UrlInfo>[];
+
+  /** Root is associated with the body node. */
+  Element body;
+
+  FileInfo(this.inputUrl, [this.isEntryPoint = false]);
+
+  /**
+   * Query for an [Element] matching the provided [tag], starting from the
+   * [body].
+   */
+  Element query(String tag) => body.query(tag);
+}
+
+
+/** Information about a web component definition declared locally. */
+// TODO(sigmund): use a mixin to pull in ComponentSummary.
+class ComponentInfo extends LibraryInfo implements ComponentSummary {
+  /** The file that declares this component. */
+  final FileInfo declaringFile;
+
+  /** The component tag name, defined with the `name` attribute on `element`. */
+  final String tagName;
+
+  /**
+   * The tag name that this component extends, defined with the `extends`
+   * attribute on `element`.
+   */
+  final String extendsTag;
+
+  /**
+   * The component info associated with the [extendsTag] name, if any.
+   * This will be `null` if the component extends a built-in HTML tag, or
+   * if the analyzer has not run yet.
+   */
+  ComponentSummary extendsComponent;
+
+  /** The Dart class containing the component's behavior. */
+  String className;
+
+  /** The Dart class declaration. */
+  ClassDeclaration get classDeclaration => _classDeclaration;
+  ClassDeclaration _classDeclaration;
+
+  /** The declaring `<element>` tag. */
+  final Node element;
+
+  /** File where this component was defined. */
+  UrlInfo get dartCodeUrl => externalFile != null
+      ? externalFile : declaringFile.inputUrl;
+
+  /**
+   * True if [tagName] was defined by more than one component. If this happened
+   * we will skip over the component.
+   */
+  bool hasConflict = false;
+
+  ComponentInfo(this.element, this.declaringFile, this.tagName,
+      this.extendsTag);
+
+  /**
+   * Gets the HTML tag extended by the base of the component hierarchy.
+   * Equivalent to [extendsTag] if this inherits directly from an HTML element,
+   * in other words, if [extendsComponent] is null.
+   */
+  String get baseExtendsTag =>
+      extendsComponent == null ? extendsTag : extendsComponent.baseExtendsTag;
+
+  Span get sourceSpan => element.sourceSpan;
+
+  /** Is apply-author-styles enabled. */
+  bool get hasAuthorStyles =>
+      element.attributes.containsKey('apply-author-styles');
+
+  /**
+   * Finds the declaring class, and initializes [className] and
+   * [classDeclaration]. Also [userCode] is generated if there was no script.
+   */
+  void findClassDeclaration(Messages messages) {
+    var constructor = element.attributes['constructor'];
+    className = constructor != null ? constructor :
+        toCamelCase(tagName, startUppercase: true);
+
+    // If we don't have any code, generate a small class definition, and
+    // pretend the user wrote it as inlined code.
+    if (userCode == null) {
+      var superclass = extendsComponent != null ? extendsComponent.className
+          : 'autogenerated.PolymerElement';
+      inlinedCode = new DartCodeInfo(null, null, [],
+          'class $className extends $superclass {\n}', null);
+    }
+
+    var code = userCode.code;
+    _classDeclaration = userCode.findClass(className);
+    if (_classDeclaration == null) {
+      // Check for deprecated x-tags implied constructor.
+      if (tagName.startsWith('x-') && constructor == null) {
+        var oldCtor = toCamelCase(tagName.substring(2), startUppercase: true);
+        _classDeclaration = userCode.findClass(oldCtor);
+        if (_classDeclaration != null) {
+          messages.warning('Implied constructor name for x-tags has changed to '
+              '"$className". You should rename your class or add a '
+              'constructor="$oldCtor" attribute to the element declaration. '
+              'Also custom tags are not required to start with "x-" if their '
+              'name has at least one dash.',
+              element.sourceSpan);
+          className = oldCtor;
+        }
+      }
+
+      if (_classDeclaration == null) {
+        messages.error('please provide a class definition '
+            'for $className:\n $code', element.sourceSpan);
+        return;
+      }
+    }
+  }
+
+  String toString() => '#<ComponentInfo $tagName '
+      '${inlinedCode != null ? "inline" : "from ${dartCodeUrl.resolvedPath}"}>';
+}
+
+
+/**
+ * Information extracted about a URL that refers to another file. This is
+ * mainly introduced to be able to trace back where URLs come from when
+ * reporting errors.
+ */
+class UrlInfo {
+  /** Original url. */
+  final String url;
+
+  /** Path that the URL points to. */
+  final String resolvedPath;
+
+  /** Original source location where the URL was extracted from. */
+  final Span sourceSpan;
+
+  UrlInfo(this.url, this.resolvedPath, this.sourceSpan);
+
+  /**
+   * Resolve a path from an [url] found in a file located at [inputUrl].
+   * Returns null for absolute [url]. Unless [ignoreAbsolute] is true, reports
+   * an error message if the url is an absolute url.
+   */
+  static UrlInfo resolve(String url, UrlInfo inputUrl, Span span,
+      String packageRoot, Messages messages, {bool ignoreAbsolute: false}) {
+
+    var uri = Uri.parse(url);
+    if (uri.host != '' || (uri.scheme != '' && uri.scheme != 'package')) {
+      if (!ignoreAbsolute) {
+        messages.error('absolute paths not allowed here: "$url"', span);
+      }
+      return null;
+    }
+
+    var target;
+    if (url.startsWith('package:')) {
+      target = path.join(packageRoot, url.substring(8));
+    } else if (path.isAbsolute(url)) {
+      if (!ignoreAbsolute) {
+        messages.error('absolute paths not allowed here: "$url"', span);
+      }
+      return null;
+    } else {
+      target = path.join(path.dirname(inputUrl.resolvedPath), url);
+      url = pathToUrl(path.normalize(path.join(
+          path.dirname(inputUrl.url), url)));
+    }
+    target = path.normalize(target);
+
+    return new UrlInfo(url, target, span);
+  }
+
+  bool operator ==(UrlInfo other) =>
+      url == other.url && resolvedPath == other.resolvedPath;
+
+  int get hashCode => resolvedPath.hashCode;
+
+  String toString() => "#<UrlInfo url: $url, resolvedPath: $resolvedPath>";
+}
diff --git a/pkg/polymer/lib/src/messages.dart b/pkg/polymer/lib/src/messages.dart
new file mode 100644
index 0000000..5dc6247
--- /dev/null
+++ b/pkg/polymer/lib/src/messages.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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 messages;
+
+import 'dart:json' as json;
+
+import 'package:barback/barback.dart' show TransformLogger;
+import 'package:source_maps/span.dart' show Span;
+import 'package:logging/logging.dart' show Level;
+
+import 'compiler_options.dart';
+import 'utils.dart';
+
+/** Map between error levels and their display color. */
+final Map<Level, String> _ERROR_COLORS = (() {
+  var colorsMap = new Map<Level, String>();
+  colorsMap[Level.SEVERE] = RED_COLOR;
+  colorsMap[Level.WARNING] = MAGENTA_COLOR;
+  colorsMap[Level.INFO] = GREEN_COLOR;
+  return colorsMap;
+})();
+
+/** A single message from the compiler. */
+class Message {
+  final Level level;
+  final String message;
+  final Span span;
+  final bool useColors;
+
+  Message(this.level, this.message, {this.span, this.useColors: false});
+
+  String get kind => level == Level.SEVERE ? 'error' :
+      (level == Level.WARNING ? 'warning' : 'info');
+
+  String toString() {
+    var output = new StringBuffer();
+    bool colors = useColors && _ERROR_COLORS.containsKey(level);
+    var levelColor =  _ERROR_COLORS[level];
+    if (colors) output.write(levelColor);
+    output..write(kind)..write(' ');
+    if (colors) output.write(NO_COLOR);
+
+    if (span == null) {
+      output.write(message);
+    } else {
+      output.write(span.getLocationMessage(message, useColors: colors,
+          color: levelColor));
+    }
+
+    return output.toString();
+  }
+
+  String toJson() {
+    if (span == null) return toString();
+    return json.stringify([{
+      'method': kind,
+      'params': {
+        'file': span.sourceUrl,
+        'message': message,
+        'line': span.start.line + 1,
+        'charStart': span.start.offset,
+        'charEnd': span.end.offset,
+      }
+    }]);
+  }
+}
+
+/**
+ * This class tracks and prints information, warnings, and errors emitted by the
+ * compiler.
+ */
+class Messages implements TransformLogger {
+  final CompilerOptions options;
+  final bool shouldPrint;
+
+  final List<Message> messages = <Message>[];
+
+  Messages({CompilerOptions options, this.shouldPrint: true})
+      : options = options != null ? options : new CompilerOptions();
+
+  /**
+   * Creates a new instance of [Messages] which doesn't write messages to
+   * the console.
+   */
+  Messages.silent(): this(shouldPrint: false);
+
+  /**
+   * True if we have an error that prevents correct codegen.
+   * For example, if we failed to read an input file.
+   */
+  bool get hasErrors => messages.any((m) => m.level == Level.SEVERE);
+
+  // Convenience methods for testing
+  int get length => messages.length;
+
+  Message operator[](int index) => messages[index];
+
+  void clear() {
+    messages.clear();
+  }
+
+  /** [message] is considered a static compile-time error by the Dart lang. */
+  void error(String message, [Span span]) {
+    var msg = new Message(Level.SEVERE, message, span: span,
+        useColors: options.useColors);
+
+    messages.add(msg);
+    printMessage(msg);
+  }
+
+  /** [message] is considered a type warning by the Dart lang. */
+  void warning(String message, [Span span]) {
+    if (options.warningsAsErrors) {
+      error(message, span);
+    } else {
+      var msg = new Message(Level.WARNING, message,
+          span: span, useColors: options.useColors);
+
+      messages.add(msg);
+      printMessage(msg);
+    }
+  }
+
+  /// the list of error messages. Empty list, if there are no error messages.
+  List<Message> get errors =>
+        messages.where((m) => m.level == Level.SEVERE).toList();
+
+  /// the list of warning messages. Empty list if there are no warning messages.
+  List<Message> get warnings =>
+        messages.where((m) => m.level == Level.WARNING).toList();
+
+  /**
+   * [message] at [span] will tell the user about what the compiler
+   * is doing.
+   */
+  void info(String message, [Span span]) {
+    var msg = new Message(Level.INFO, message, span: span,
+        useColors: options.useColors);
+
+    messages.add(msg);
+    if (options.verbose) printMessage(msg);
+  }
+
+  void printMessage(msg) {
+    if (shouldPrint) print(options.jsonFormat ? msg.toJson() : msg);
+  }
+}
diff --git a/pkg/polymer/lib/src/paths.dart b/pkg/polymer/lib/src/paths.dart
new file mode 100644
index 0000000..34037d9
--- /dev/null
+++ b/pkg/polymer/lib/src/paths.dart
@@ -0,0 +1,170 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Holds path information that is used by the WebUI compiler to find files,
+ * compute their output location and relative paths between them.
+ */
+library polymer.src.paths;
+
+import 'info.dart' show UrlInfo;
+import 'messages.dart';
+import 'summary.dart';
+import 'utils.dart' show path, pathToUrl;
+
+/**
+ * Stores information about paths and computes mappings between input and output
+ * path locations.
+ */
+class PathMapper {
+  /**
+   * Common prefix to all input paths that are read from the file system. The
+   * output generated by the compiler will reflect the directory structure
+   * starting from [_baseDir]. For instance, if [_baseDir] is `a/b/c` and
+   * [_outputDir] is `g/h/`, then the corresponding output file for
+   * `a/b/c/e/f.html` will be under `g/h/e/f.html.dart`.
+   */
+  final String _baseDir;
+
+  /** Base path where all output is generated. */
+  final String _outputDir;
+
+  /** The package root directory. */
+  final String packageRoot;
+
+  /** Whether to add prefixes and to output file names. */
+  final bool _mangleFilenames;
+
+  final bool _rewriteUrls;
+
+  bool get _rewritePackageImports => _rewriteUrls || !_mangleFilenames;
+
+  /** Default prefix added to all filenames. */
+  static const String _DEFAULT_PREFIX = '_';
+
+  PathMapper(String baseDir, String outputDir, this.packageRoot,
+      bool forceMangle, this._rewriteUrls)
+      : _baseDir = baseDir,
+        _outputDir = outputDir,
+        _mangleFilenames = forceMangle || (baseDir == outputDir);
+
+  /** Add a prefix and [suffix] if [_mangleFilenames] is true */
+  String mangle(String name, String suffix, [bool forceSuffix = false]) =>
+    _mangleFilenames ? "$_DEFAULT_PREFIX$name$suffix"
+        : (forceSuffix ? "$name$suffix" : name);
+
+  /**
+   * Checks that `input.resolvedPath` is a valid input path. It must be in
+   * [_baseDir] and must not be in the [_outputDir]. If not, an error message
+   * is added to [messages].
+   */
+  bool checkInputPath(UrlInfo input, Messages messages) {
+    if (_mangleFilenames) return true;
+    var canonicalized = path.normalize(input.resolvedPath);
+    var parentDir = '..${path.separator}';
+    if (!path.relative(canonicalized, from: _outputDir).startsWith(parentDir)) {
+      messages.error(
+          'The file ${input.resolvedPath} cannot be processed. '
+          'Files cannot be under the output folder (${_outputDir}).',
+          input.sourceSpan);
+      return false;
+    }
+    if (path.relative(canonicalized, from: _baseDir).startsWith(parentDir)) {
+      messages.error(
+          'The file ${input.resolvedPath} cannot be processed. '
+          'All processed files must be under the base folder (${_baseDir}), you'
+          ' can specify the base folder using the --basedir flag.',
+          input.sourceSpan);
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * The path to the output file corresponding to [input], by adding
+   * [_DEFAULT_PREFIX] and a [suffix] to its file name.
+   */
+  String outputPath(String input, String suffix, [bool forceSuffix = false]) =>
+      path.join(outputDirPath(input),
+          mangle(path.basename(input), suffix, forceSuffix));
+
+  /** The path to the output file corresponding to [info]. */
+  String outputLibraryPath(LibrarySummary lib) =>
+      path.join(outputDirPath(lib.dartCodeUrl.resolvedPath),
+          lib.outputFilename);
+
+  /** The corresponding output directory for [input]'s directory. */
+  String outputDirPath(String input) {
+    return _rewritePackages(path.normalize(
+          path.join(_outputDir, path.relative(
+              path.dirname(input), from: _baseDir))));
+  }
+
+  /**
+   * We deal with `packages/` directories in a very special way. We assume it
+   * points to resources loaded from other pub packages. If an output directory
+   * is specified, the compiler will create a packages symlink so that
+   * `package:` imports work.
+   *
+   * To make it possible to share components through pub, we allow using tags of
+   * the form `<link rel="import" href="packages/...">`, so that you can
+   * refer to components within the packages symlink.  Regardless of whether an
+   * --out option was given to the compiler, we don't want to generate files
+   * inside `packages/` for those components.  Instead we will generate such
+   * code in a special directory called `_from_packages/`.
+   */
+  String _rewritePackages(String outputPath) {
+    // TODO(jmesserly): this should match against packageRoot instead.
+    if (!outputPath.contains('packages')) return outputPath;
+    if (!_rewritePackageImports) return outputPath;
+    var segments = path.split(outputPath);
+    return path.joinAll(
+        segments.map((s) => s == 'packages' ? '_from_packages' : s));
+  }
+
+  /**
+   * Returns a url to import/export the output library represented by [target]
+   * from the output library of [src]. In other words, a url to import or export
+   * `target.outputFilename` from `src.outputFilename`.
+   */
+  String importUrlFor(LibrarySummary src, LibrarySummary target) {
+    if (!_rewritePackageImports &&
+        target.dartCodeUrl.url.startsWith('package:')) {
+      return pathToUrl(path.join(path.dirname(target.dartCodeUrl.url),
+            target.outputFilename));
+    }
+    var srcDir = path.dirname(src.dartCodeUrl.resolvedPath);
+    var relDir = path.relative(
+        path.dirname(target.dartCodeUrl.resolvedPath), from: srcDir);
+    return pathToUrl(_rewritePackages(path.normalize(
+          path.join(relDir, target.outputFilename))));
+  }
+
+  /**
+   * Transforms a [target] url seen in [src] (e.g. a Dart import, a .css href in
+   * an HTML file, etc) into a corresponding url from the output file associated
+   * with [src]. This will keep 'package:', 'dart:', path-absolute, and absolute
+   * urls intact, but it will fix relative paths to walk from the output
+   * directory back to the input directory. An exception will be thrown if
+   * [target] is not under [_baseDir].
+   */
+  String transformUrl(String src, String target) {
+    var uri = Uri.parse(target);
+    if (uri.isAbsolute) return target;
+    if (!uri.scheme.isEmpty) return target;
+    if (!uri.host.isEmpty) return target;
+    if (uri.path.isEmpty) return target;  // Implies standalone ? or # in URI.
+    if (path.isAbsolute(target)) return target;
+
+    return pathToUrl(path.normalize(path.relative(
+          path.join(path.dirname(src), target), from: outputDirPath(src))));
+  }
+}
+
+/**
+ * Returns a "mangled" name, with a prefix and [suffix] depending on the
+ * compiler's settings. [forceSuffix] causes [suffix] to be appended even if
+ * the compiler is not mangling names.
+ */
+typedef String NameMangler(String name, String suffix, [bool forceSuffix]);
diff --git a/pkg/polymer/lib/src/summary.dart b/pkg/polymer/lib/src/summary.dart
new file mode 100644
index 0000000..841870a
--- /dev/null
+++ b/pkg/polymer/lib/src/summary.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Summary information for components and libraries.
+ *
+ * These classes are used for modular compilation. Summaries are a subset of the
+ * information collected by Info objects (see `info.dart`). When we are
+ * compiling a single file, the information extracted from that file is stored
+ * as info objects, but any information that is needed from other files (like
+ * imported components) is stored as a summary.
+ */
+library polymer.src.summary;
+
+import 'package:source_maps/span.dart' show Span;
+
+// TODO(sigmund): consider moving UrlInfo out of info.dart
+import 'info.dart' show UrlInfo;
+
+/**
+ * Summary information from other library-like objects, which includes HTML
+ * components and dart libraries).
+ */
+class LibrarySummary {
+  /** Path to the sources represented by this summary. */
+  final UrlInfo dartCodeUrl;
+
+  /** Name given to this source after it was compiled. */
+  final String outputFilename;
+
+  LibrarySummary(this.dartCodeUrl, this.outputFilename);
+}
+
+/** Summary information for an HTML file that defines custom elements. */
+class HtmlFileSummary extends LibrarySummary {
+  /**
+   * Summary of each component defined either explicitly the HTML file or
+   * included transitively from `<link rel="import">` tags.
+   */
+  final Map<String, ComponentSummary> components;
+
+  HtmlFileSummary(UrlInfo dartCodeUrl, String outputFilename, this.components)
+      : super(dartCodeUrl, outputFilename);
+}
+
+/** Information about a web component definition. */
+class ComponentSummary extends LibrarySummary {
+  /** The component tag name, defined with the `name` attribute on `element`. */
+  final String tagName;
+
+  /**
+   * The tag name that this component extends, defined with the `extends`
+   * attribute on `element`.
+   */
+  final String extendsTag;
+
+  /**
+   * The Dart class containing the component's behavior, derived from tagName or
+   * defined in the `constructor` attribute on `element`.
+   */
+  final String className;
+
+  /** Summary of the base component, if any. */
+  final ComponentSummary extendsComponent;
+
+  /**
+   * True if [tagName] was defined by more than one component. Used internally
+   * by the analyzer. Conflicting component will be skipped by the compiler.
+   */
+  bool hasConflict;
+
+  /** Original span where this component is declared. */
+  final Span sourceSpan;
+
+  ComponentSummary(UrlInfo dartCodeUrl, String outputFilename,
+      this.tagName, this.extendsTag, this.className, this.extendsComponent,
+      this.sourceSpan, [this.hasConflict = false])
+      : super(dartCodeUrl, outputFilename);
+
+  /**
+   * Gets the HTML tag extended by the base of the component hierarchy.
+   * Equivalent to [extendsTag] if this inherits directly from an HTML element,
+   * in other words, if [extendsComponent] is null.
+   */
+  String get baseExtendsTag =>
+      extendsComponent == null ? extendsTag : extendsComponent.baseExtendsTag;
+}
diff --git a/pkg/polymer/lib/src/utils.dart b/pkg/polymer/lib/src/utils.dart
new file mode 100644
index 0000000..da79dc2
--- /dev/null
+++ b/pkg/polymer/lib/src/utils.dart
@@ -0,0 +1,177 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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 polymer.src.utils;
+
+import 'dart:async';
+import 'package:path/path.dart' show Builder;
+export 'utils_observe.dart' show toCamelCase, toHyphenedName;
+
+/**
+ * An instance of the pathos library builder. We could just use the default
+ * builder in pathos, but we add this indirection to make it possible to run
+ * unittest for windows paths.
+ */
+Builder path = new Builder();
+
+/** Convert a OS specific path into a url. */
+String pathToUrl(String relPath) =>
+  (path.separator == '/') ? relPath : path.split(relPath).join('/');
+
+/**
+ * Invokes [callback], logs how long it took to execute in ms, and returns
+ * whatever [callback] returns. The log message will be printed if [printTime]
+ * is true.
+ */
+time(String logMessage, callback(),
+     {bool printTime: false, bool useColors: false}) {
+  final watch = new Stopwatch();
+  watch.start();
+  var result = callback();
+  watch.stop();
+  final duration = watch.elapsedMilliseconds;
+  if (printTime) {
+    _printMessage(logMessage, duration, useColors);
+  }
+  return result;
+}
+
+/**
+ * Invokes [callback], logs how long it takes from the moment [callback] is
+ * executed until the future it returns is completed. Returns the future
+ * returned by [callback]. The log message will be printed if [printTime]
+ * is true.
+ */
+Future asyncTime(String logMessage, Future callback(),
+                 {bool printTime: false, bool useColors: false}) {
+  final watch = new Stopwatch();
+  watch.start();
+  return callback()..then((_) {
+    watch.stop();
+    final duration = watch.elapsedMilliseconds;
+    if (printTime) {
+      _printMessage(logMessage, duration, useColors);
+    }
+  });
+}
+
+void _printMessage(String logMessage, int duration, bool useColors) {
+  var buf = new StringBuffer();
+  buf.write(logMessage);
+  for (int i = logMessage.length; i < 60; i++) buf.write(' ');
+  buf.write(' -- ');
+  if (useColors) {
+    buf.write(GREEN_COLOR);
+  }
+  if (duration < 10) buf.write(' ');
+  if (duration < 100) buf.write(' ');
+  buf..write(duration)..write(' ms');
+  if (useColors) {
+    buf.write(NO_COLOR);
+  }
+  print(buf.toString());
+}
+
+// Color constants used for generating messages.
+final String GREEN_COLOR = '\u001b[32m';
+final String RED_COLOR = '\u001b[31m';
+final String MAGENTA_COLOR = '\u001b[35m';
+final String NO_COLOR = '\u001b[0m';
+
+/** A future that waits until all added [Future]s complete. */
+// TODO(sigmund): this should be part of the futures/core libraries.
+class FutureGroup {
+  static const _FINISHED = -1;
+
+  int _pending = 0;
+  Future _failedTask;
+  final Completer<List> _completer = new Completer<List>();
+  final List results = [];
+
+  /** Gets the task that failed, if any. */
+  Future get failedTask => _failedTask;
+
+  /**
+   * Wait for [task] to complete.
+   *
+   * If this group has already been marked as completed, you'll get a
+   * [StateError].
+   *
+   * If this group has a [failedTask], new tasks will be ignored, because the
+   * error has already been signaled.
+   */
+  void add(Future task) {
+    if (_failedTask != null) return;
+    if (_pending == _FINISHED) throw new StateError("Future already completed");
+
+    _pending++;
+    var i = results.length;
+    results.add(null);
+    task.then((res) {
+      results[i] = res;
+      if (_failedTask != null) return;
+      _pending--;
+      if (_pending == 0) {
+        _pending = _FINISHED;
+        _completer.complete(results);
+      }
+    }, onError: (e) {
+      if (_failedTask != null) return;
+      _failedTask = task;
+      _completer.completeError(e, getAttachedStackTrace(e));
+    });
+  }
+
+  Future<List> get future => _completer.future;
+}
+
+
+/**
+ * Escapes [text] for use in a Dart string.
+ * [single] specifies single quote `'` vs double quote `"`.
+ * [triple] indicates that a triple-quoted string, such as `'''` or `"""`.
+ */
+String escapeDartString(String text, {bool single: true, bool triple: false}) {
+  // Note: don't allocate anything until we know we need it.
+  StringBuffer result = null;
+
+  for (int i = 0; i < text.length; i++) {
+    int code = text.codeUnitAt(i);
+    var replace = null;
+    switch (code) {
+      case 92/*'\\'*/: replace = r'\\'; break;
+      case 36/*r'$'*/: replace = r'\$'; break;
+      case 34/*'"'*/:  if (!single) replace = r'\"'; break;
+      case 39/*"'"*/:  if (single) replace = r"\'"; break;
+      case 10/*'\n'*/: if (!triple) replace = r'\n'; break;
+      case 13/*'\r'*/: if (!triple) replace = r'\r'; break;
+
+      // Note: we don't escape unicode characters, under the assumption that
+      // writing the file in UTF-8 will take care of this.
+
+      // TODO(jmesserly): do we want to replace any other non-printable
+      // characters (such as \f) for readability?
+    }
+
+    if (replace != null && result == null) {
+      result = new StringBuffer(text.substring(0, i));
+    }
+
+    if (result != null) result.write(replace != null ? replace : text[i]);
+  }
+
+  return result == null ? text : result.toString();
+}
+
+/** Iterates through an infinite sequence, starting from zero. */
+class IntIterator implements Iterator<int> {
+  int _next = -1;
+
+  int get current => _next < 0 ? null : _next;
+
+  bool moveNext() {
+    _next++;
+    return true;
+  }
+}
diff --git a/pkg/polymer/lib/src/utils_observe.dart b/pkg/polymer/lib/src/utils_observe.dart
new file mode 100644
index 0000000..b568d0c
--- /dev/null
+++ b/pkg/polymer/lib/src/utils_observe.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library polymer.src.utils_observe;
+
+/**
+ * Converts a string name with hyphens into an identifier, by removing hyphens
+ * and capitalizing the following letter. Optionally [startUppercase] to
+ * captialize the first letter.
+ */
+String toCamelCase(String hyphenedName, {bool startUppercase: false}) {
+  var segments = hyphenedName.split('-');
+  int start = startUppercase ? 0 : 1;
+  for (int i = start; i < segments.length; i++) {
+    var segment = segments[i];
+    if (segment.length > 0) {
+      // Character between 'a'..'z' mapped to 'A'..'Z'
+      segments[i] = '${segment[0].toUpperCase()}${segment.substring(1)}';
+    }
+  }
+  return segments.join('');
+}
+
+String toHyphenedName(String word) {
+  var sb = new StringBuffer();
+  for (int i = 0; i < word.length; i++) {
+    var lower = word[i].toLowerCase();
+    if (word[i] != lower && i > 0) sb.write('-');
+    sb.write(lower);
+  }
+  return sb.toString();
+}
diff --git a/pkg/polymer/lib/testing/content_shell_test.dart b/pkg/polymer/lib/testing/content_shell_test.dart
new file mode 100644
index 0000000..97398be
--- /dev/null
+++ b/pkg/polymer/lib/testing/content_shell_test.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.
+
+/**
+ * Helper library to run tests in content_shell
+ */
+library polymer.testing.end2end;
+
+import 'dart:io';
+import 'package:args/args.dart';
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+import 'package:polymer/dwc.dart' as dwc;
+
+
+/**
+ * Compiles [testFile] with the web-ui compiler, and then runs the output as a
+ * unit test in content_shell.
+ */
+void endToEndTests(String inputDir, String outDir, {List<String> arguments}) {
+  _testHelper(new _TestOptions(inputDir, inputDir, null, outDir,
+        arguments: arguments));
+}
+
+/**
+ * Compiles [testFile] with the web-ui compiler, and then runs the output as a
+ * render test in content_shell.
+ */
+void renderTests(String baseDir, String inputDir, String expectedDir,
+    String outDir, {List<String> arguments, String script, String pattern,
+    bool deleteDir: true}) {
+  _testHelper(new _TestOptions(baseDir, inputDir, expectedDir, outDir,
+      arguments: arguments, script: script, pattern: pattern,
+      deleteDir: deleteDir));
+}
+
+void _testHelper(_TestOptions options) {
+  expect(options, isNotNull);
+
+  var paths = new Directory(options.inputDir).listSync()
+      .where((f) => f is File).map((f) => f.path)
+      .where((p) => p.endsWith('_test.html') && options.pattern.hasMatch(p));
+
+  if (paths.isEmpty) return;
+
+  // First clear the output folder. Otherwise we can miss bugs when we fail to
+  // generate a file.
+  var dir = new Directory(options.outDir);
+  if (dir.existsSync() && options.deleteDir) {
+    print('Cleaning old output for ${path.normalize(options.outDir)}');
+    dir.deleteSync(recursive: true);
+  }
+  dir.createSync();
+
+  for (var filePath in paths) {
+    var filename = path.basename(filePath);
+    test('compile $filename', () {
+      var testArgs = ['-o', options.outDir, '--basedir', options.baseDir,
+          '--deploy']
+          ..addAll(options.compilerArgs)
+          ..add(filePath);
+      expect(dwc.run(testArgs, printTime: false).then((res) {
+        expect(res.messages.length, 0, reason: res.messages.join('\n'));
+      }), completes);
+    });
+  }
+
+  var filenames = paths.map(path.basename).toList();
+  // Sort files to match the order in which run.sh runs diff.
+  filenames.sort();
+
+  // Get the path from "input" relative to "baseDir"
+  var relativeToBase = path.relative(options.inputDir, from: options.baseDir);
+  var finalOutDir = path.join(options.outDir, relativeToBase);
+
+  runTests(String search) {
+    var output;
+
+    for (var filename in filenames) {
+      test('content_shell run $filename$search', () {
+        var args = ['--dump-render-tree',
+            'file://$finalOutDir/$filename$search'];
+        var env = {'DART_FLAGS': '--checked'};
+        expect(Process.run('content_shell', args, environment: env).then((res) {
+          expect(res.exitCode, 0, reason: 'content_shell exit code: '
+              '${res.exitCode}. Contents of stderr: \n${res.stderr}');
+          var outs = res.stdout.split('#EOF\n')
+            .where((s) => !s.trim().isEmpty).toList();
+          expect(outs.length, 1);
+          output = outs.first;
+        }), completes);
+      });
+
+      test('verify $filename $search', () {
+        expect(output, isNotNull, reason:
+          'Output not available, maybe content_shell failed to run.');
+        var outPath = path.join(options.outDir, '$filename.txt');
+        new File(outPath).writeAsStringSync(output);
+        if (options.isRenderTest) {
+          var expectedPath = path.join(options.expectedDir, '$filename.txt');
+          var expected = new File(expectedPath).readAsStringSync();
+          expect(output, expected, reason: 'unexpected output for <$filename>');
+        } else {
+          bool passes = matches(
+              new RegExp('All .* tests passed')).matches(output, {});
+          expect(passes, true, reason: 'unit test failed:\n$output');
+        }
+      });
+    }
+  }
+
+  bool compiled = false;
+  ensureCompileToJs() {
+    if (compiled) return;
+    compiled = true;
+
+    for (var filename in filenames) {
+      test('dart2js $filename', () {
+        // TODO(jmesserly): this depends on DWC's output scheme.
+        // Alternatively we could use html5lib to find the script tag.
+        var inPath = '${filename}_bootstrap.dart';
+        var outPath = '${inPath}.js';
+
+        inPath = path.join(finalOutDir, inPath);
+        outPath = path.join(finalOutDir, outPath);
+
+        expect(Process.run('dart2js', ['-o$outPath', inPath]).then((res) {
+          expect(res.exitCode, 0, reason: 'dart2js exit code: '
+            '${res.exitCode}. Contents of stderr: \n${res.stderr}. '
+            'Contents of stdout: \n${res.stdout}.');
+          expect(new File(outPath).existsSync(), true, reason: 'input file '
+            '$inPath should have been compiled to $outPath.');
+        }), completes);
+      });
+    }
+  }
+
+  if (options.runAsDart) {
+    runTests('');
+  }
+  if (options.runAsJs) {
+    ensureCompileToJs();
+    runTests('?js=1');
+  }
+  if (options.forcePolyfillShadowDom) {
+    ensureCompileToJs();
+    runTests('?js=1&shadowdomjs=1');
+  }
+}
+
+class _TestOptions {
+  final String baseDir;
+  final String inputDir;
+
+  final String expectedDir;
+  bool get isRenderTest => expectedDir != null;
+
+  final String outDir;
+  final bool deleteDir;
+
+  final bool runAsDart;
+  final bool runAsJs;
+  final bool forcePolyfillShadowDom;
+
+  final List<String> compilerArgs;
+  final RegExp pattern;
+
+  factory _TestOptions(String baseDir, String inputDir, String expectedDir,
+      String outDir, {List<String> arguments, String script, String pattern,
+      bool deleteDir: true}) {
+    if (arguments == null) arguments = new Options().arguments;
+    if (script == null) script = new Options().script;
+
+    var args = _parseArgs(arguments, script);
+    if (args == null) return null;
+    var compilerArgs = args.rest;
+    var filePattern;
+    if (pattern != null) {
+      filePattern = new RegExp(pattern);
+    } else if (compilerArgs.length > 0) {
+      filePattern = new RegExp(compilerArgs[0]);
+      compilerArgs = compilerArgs.sublist(1);
+    } else {
+      filePattern = new RegExp('.');
+    }
+
+    var scriptDir = path.absolute(path.dirname(script));
+    baseDir = path.join(scriptDir, baseDir);
+    inputDir = path.join(scriptDir, inputDir);
+    outDir = path.join(scriptDir, outDir);
+    if (expectedDir != null) {
+      expectedDir = path.join(scriptDir, expectedDir);
+    }
+
+    return new _TestOptions._(baseDir, inputDir, expectedDir, outDir, deleteDir,
+        args['dart'] == true, args['js'] == true, args['shadowdom'] == true,
+        compilerArgs, filePattern);
+  }
+
+  _TestOptions._(this.baseDir, this.inputDir, this.expectedDir, this.outDir,
+      this.deleteDir, this.runAsDart, this.runAsJs,
+      this.forcePolyfillShadowDom, this.compilerArgs, this.pattern);
+}
+
+ArgResults _parseArgs(List<String> arguments, String script) {
+  var parser = new ArgParser()
+    ..addFlag('dart', abbr: 'd', help: 'run on Dart VM', defaultsTo: true)
+    ..addFlag('js', abbr: 'j', help: 'run compiled dart2js', defaultsTo: true)
+    ..addFlag('shadowdom', abbr: 's',
+        help: 'run dart2js and polyfilled ShadowDOM', defaultsTo: true)
+    ..addFlag('help', abbr: 'h', help: 'Displays this help message',
+        defaultsTo: false, negatable: false);
+
+  showUsage() {
+    print('Usage: $script [options...] [test_name_regexp]');
+    print(parser.getUsage());
+    return null;
+  }
+
+  try {
+    var results = parser.parse(arguments);
+    if (results['help']) return showUsage();
+    return results;
+  } on FormatException catch (e) {
+    print(e.message);
+    return showUsage();
+  }
+}
diff --git a/pkg/polymer/lib/testing/testing.js b/pkg/polymer/lib/testing/testing.js
new file mode 100644
index 0000000..de27047
--- /dev/null
+++ b/pkg/polymer/lib/testing/testing.js
@@ -0,0 +1,147 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+(function() {
+  var undoReplaceScripts = [];
+
+  var flags = {};
+  // populate flags from location
+  location.search.slice(1).split('&').forEach(function(o) {
+    o = o.split('=');
+    o[0] && (flags[o[0]] = o[1] || true);
+  });
+
+  // Webkit is migrating from layoutTestController to testRunner, we use
+  // layoutTestController as a fallback until that settles in.
+  var runner = window.testRunner || window.layoutTestController;
+
+  if (runner) {
+    runner.dumpAsText();
+    runner.waitUntilDone();
+  }
+
+  function dumpDOM() {
+    // Undo any scripts that were modified.
+    undoReplaceScripts.forEach(function(undo) { undo(); });
+
+    function expandShadowRoot(node) {
+      for (var n = node.firstChild; n; n = n.nextSibling) {
+        expandShadowRoot(n);
+      }
+      var shadow = node.shadowRoot || node.webkitShadowRoot ||
+          node.olderShadowRoot;
+
+      if (shadow) {
+        expandShadowRoot(shadow);
+
+        var name = 'shadow-root';
+        if (shadow == node.olderShadowRoot) name = 'older-' + name;
+
+        var fakeShadow = document.createElement(name);
+        while (shadow.firstChild) fakeShadow.appendChild(shadow.firstChild);
+        node.insertBefore(fakeShadow, node.firstChild);
+      }
+    }
+
+    // TODO(jmesserly): use querySelector to workaround unwrapped "document".
+    expandShadowRoot(document.querySelector('body'));
+
+    // Clean up all of the junk added to the DOM by js-interop and shadow CSS
+    // TODO(jmesserly): it seems like we're leaking lots of dart-port attributes
+    // for the document elemenet
+    function cleanTree(node) {
+      for (var n = node.firstChild; n; n = n.nextSibling) {
+        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);
+          }
+        }
+      }
+
+      if (node.tagName == 'script' &&
+          node.textContent.indexOf('_DART_TEMPORARY_ATTACHED') >= 0)  {
+        node.parentNode.removeChild(node);
+      }
+    }
+
+    // TODO(jmesserly): use querySelector to workaround unwrapped "document".
+    cleanTree(document.querySelector('html'));
+
+    var out = document.createElement('pre');
+    out.textContent = document.documentElement.outerHTML;
+    document.body.innerHTML = '';
+    document.body.appendChild(out);
+  }
+
+  function messageHandler(e) {
+    if (e.data == 'done' && runner) {
+      // On success, dump the DOM. Convert shadowRoot contents into
+      // <shadow-root>
+      dumpDOM();
+      runner.notifyDone();
+    }
+  }
+
+  window.addEventListener('message', messageHandler, false);
+
+  function errorHandler(e) {
+    if (runner) {
+      window.setTimeout(function() { runner.notifyDone(); }, 0);
+    }
+    window.console.log('FAIL');
+  }
+
+  window.addEventListener('error', errorHandler, false);
+
+  if (navigator.webkitStartDart && !flags.js) {
+    // TODO(jmesserly): fix this so we don't need to copy from browser/dart.js
+    if (!navigator.webkitStartDart()) {
+      document.body.innerHTML = 'This build has expired.  Please download a new Dartium at http://www.dartlang.org/dartium/index.html';
+    }
+  } else {
+    if (flags.shadowdomjs) {
+      // Allow flags to force polyfill of ShadowDOM so we can test it.
+      window.__forceShadowDomPolyfill = true;
+    }
+
+    // TODO:
+    // - Support in-browser compilation.
+    // - Handle inline Dart scripts.
+    window.addEventListener("DOMContentLoaded", function (e) {
+      // Fall back to compiled JS. Run through all the scripts and
+      // replace them if they have a type that indicate that they source
+      // in Dart code.
+      //
+      //   <script type="application/dart" src="..."></script>
+      //
+      var scripts = document.getElementsByTagName("script");
+      var length = scripts.length;
+      for (var i = 0; i < length; ++i) {
+        var script = scripts[i];
+        if (script.type == "application/dart") {
+          // Remap foo.dart to foo.dart.js.
+          if (script.src && script.src != '') {
+            var jsScript = document.createElement('script');
+            jsScript.src = script.src.replace(/\.dart(?=\?|$)/, '.dart.js');
+            var parent = script.parentNode;
+            // TODO(vsm): Find a solution for issue 8455 that works with more
+            // than one script.
+            document.currentScript = jsScript;
+
+            undoReplaceScripts.push(function() {
+              parent.replaceChild(script, jsScript);
+            });
+            parent.replaceChild(jsScript, script);
+          }
+        }
+      }
+    }, false);
+  }
+
+})();
diff --git a/pkg/polymer/pubspec.yaml b/pkg/polymer/pubspec.yaml
new file mode 100644
index 0000000..78b2b66
--- /dev/null
+++ b/pkg/polymer/pubspec.yaml
@@ -0,0 +1,26 @@
+name: polymer
+author: Web UI Authors <web-ui-dev@dartlang.org>
+description: >
+  Polymer.dart is a new type of library for the web, built on top of Web
+  Components, and designed to leverage the evolving web platform on modern
+  browsers.
+homepage: https://www.dartlang.org
+dependencies:
+  analyzer_experimental: any
+  args: any
+  barback: any
+  browser: any
+  csslib: any
+  custom_element: any
+  html_import: any
+  html5lib: any
+  js: any
+  logging: any
+  mdv: any
+  observe: any
+  path: any
+  polymer_expressions: any
+  shadow_dom: any
+  source_maps: any
+  # TODO(jmesserly): make this a dev_dependency
+  unittest: any
diff --git a/pkg/polymer/test/compiler_test.dart b/pkg/polymer/test/compiler_test.dart
new file mode 100644
index 0000000..d5d47ba
--- /dev/null
+++ b/pkg/polymer/test/compiler_test.dart
@@ -0,0 +1,141 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/** End-to-end tests for the [Compiler] API. */
+library compiler_test;
+
+import 'package:logging/logging.dart' show Level;
+import 'package:path/path.dart' as path;
+import 'package:polymer/src/messages.dart';
+import 'package:unittest/compact_vm_config.dart';
+import 'package:unittest/unittest.dart';
+
+import 'testing.dart';
+
+main() {
+  useCompactVMConfiguration();
+
+  test('recursive dependencies', () {
+    var messages = new Messages.silent();
+    var compiler = createCompiler({
+      'index.html': '<head>'
+                    '<link rel="import" href="foo.html">'
+                    '<link rel="import" href="bar.html">'
+                    '<body><x-foo></x-foo><x-bar></x-bar>'
+                    '<script type="application/dart">main() {}</script>',
+      'foo.html': '<head><link rel="import" href="bar.html">'
+                  '<body><polymer-element name="x-foo" constructor="Foo">'
+                  '<template><x-bar>',
+      'bar.html': '<head><link rel="import" href="foo.html">'
+                  '<body><polymer-element name="x-bar" constructor="Boo">'
+                  '<template><x-foo>',
+    }, messages);
+
+    compiler.run().then(expectAsync1((e) {
+      MockFileSystem fs = compiler.fileSystem;
+      expect(fs.readCount, equals({
+        'index.html': 1,
+        'foo.html': 1,
+        'bar.html': 1
+      }), reason: 'Actual:\n  ${fs.readCount}');
+
+      var outputs = compiler.output.map((o) => o.path);
+      expect(outputs, equals([
+        'foo.html.dart',
+        'foo.html.dart.map',
+        'bar.html.dart',
+        'bar.html.dart.map',
+        'index.html.dart',
+        'index.html.dart.map',
+        'index.html_bootstrap.dart',
+        'index.html',
+      ].map((p) => path.join('out', p))));
+    }));
+  });
+
+  group('missing files', () {
+    test('main script', () {
+      var messages = new Messages.silent();
+      var compiler = createCompiler({
+        'index.html': '<head></head><body>'
+            '<script type="application/dart" src="notfound.dart"></script>'
+            '</body>',
+      }, messages);
+
+      compiler.run().then(expectAsync1((e) {
+        var msgs = messages.messages.where((m) =>
+            m.message.contains('unable')).toList();
+
+        expect(msgs.length, 1);
+        expect(msgs[0].level, Level.SEVERE);
+        expect(msgs[0].message, contains('unable to open file'));
+        expect(msgs[0].span, isNotNull);
+        expect(msgs[0].span.sourceUrl, 'index.html');
+
+        MockFileSystem fs = compiler.fileSystem;
+        expect(fs.readCount, { 'index.html': 1, 'notfound.dart': 1 });
+
+        var outputs = compiler.output.map((o) => o.path.toString());
+        expect(outputs, []);
+      }));
+    });
+
+    test('component html', () {
+      var messages = new Messages.silent();
+      var compiler = createCompiler({
+        'index.html': '<head>'
+            '<link rel="import" href="notfound.html">'
+            '<body><x-foo>'
+            '<script type="application/dart">main() {}</script>',
+      }, messages);
+
+      compiler.run().then(expectAsync1((e) {
+        var msgs = messages.messages.where((m) =>
+            m.message.contains('unable')).toList();
+
+        expect(msgs.length, 1);
+        expect(msgs[0].level, Level.SEVERE);
+        expect(msgs[0].message, contains('unable to open file'));
+        expect(msgs[0].span, isNotNull);
+        expect(msgs[0].span.sourceUrl, 'index.html');
+
+        MockFileSystem fs = compiler.fileSystem;
+        expect(fs.readCount, { 'index.html': 1, 'notfound.html': 1 });
+
+        var outputs = compiler.output.map((o) => o.path.toString());
+        expect(outputs, []);
+      }));
+    });
+
+    test('component script', () {
+      var messages = new Messages.silent();
+      var compiler = createCompiler({
+        'index.html': '<head>'
+            '<link rel="import" href="foo.html">'
+            '<body><x-foo></x-foo>'
+            '<script type="application/dart">main() {}</script>'
+            '</body>',
+        'foo.html': '<body><polymer-element name="x-foo" constructor="Foo">'
+            '<template></template>'
+            '<script type="application/dart" src="notfound.dart"></script>',
+      }, messages);
+
+      compiler.run().then(expectAsync1((e) {
+        var msgs = messages.messages.where((m) =>
+            m.message.contains('unable')).toList();
+
+        expect(msgs.length, 1);
+        expect(msgs[0].level, Level.SEVERE);
+        expect(msgs[0].message, contains('unable to open file'));
+
+        MockFileSystem fs = compiler.fileSystem;
+        expect(fs.readCount,
+            { 'index.html': 1, 'foo.html': 1, 'notfound.dart': 1  });
+
+        var outputs = compiler.output.map((o) => o.path.toString());
+        expect(outputs, []);
+      }));
+    });
+  });
+}
diff --git a/pkg/polymer/test/css_test.dart b/pkg/polymer/test/css_test.dart
new file mode 100644
index 0000000..1702312
--- /dev/null
+++ b/pkg/polymer/test/css_test.dart
@@ -0,0 +1,559 @@
+// Copyright (c) 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 css_test;
+
+import 'package:path/path.dart' as path;
+import 'package:polymer/src/messages.dart';
+import 'package:polymer/src/utils.dart' as utils;
+import 'package:unittest/compact_vm_config.dart';
+import 'package:unittest/unittest.dart';
+
+import 'testing.dart';
+
+test_simple_var() {
+  Map createFiles() {
+    return {
+      'index.html':
+        '<!DOCTYPE html>'
+        '<html lang="en">'
+          '<head>'
+            '<meta charset="utf-8">'
+          '</head>'
+          '<body>'
+            '<style>'
+              '@main_color: var(b);'
+              '@b: var(c);'
+              '@c: red;'
+            '</style>'
+            '<style>'
+              '.test { color: var(main_color); }'
+            '</style>'
+            '<script type="application/dart">main() {}</script>'
+          '</body>'
+        '</html>',
+    };
+  }
+
+  var messages = new Messages.silent();
+  var compiler = createCompiler(createFiles(), messages, errors: true,
+      scopedCss: true);
+
+  compiler.run().then(expectAsync1((e) {
+    MockFileSystem fs = compiler.fileSystem;
+    expect(fs.readCount, equals({
+      'index.html': 1,
+    }), reason: 'Actual:\n  ${fs.readCount}');
+
+    var htmlInfo = compiler.info['index.html'];
+    expect(htmlInfo.styleSheets.length, 2);
+    expect(prettyPrintCss(htmlInfo.styleSheets[0]), '');
+    expect(prettyPrintCss(htmlInfo.styleSheets[1]), '.test { color: red; }');
+
+    var outputs = compiler.output.map((o) => o.path);
+    expect(outputs, equals([
+      'out/index.html.dart',
+      'out/index.html.dart.map',
+      'out/index.html_bootstrap.dart',
+      'out/index.html',
+    ]));
+  }));
+}
+
+test_var() {
+  Map createFiles() {
+    return {
+      'index.html':
+        '<!DOCTYPE html>'
+        '<html lang="en">'
+          '<head>'
+            '<meta charset="utf-8">'
+          '</head>'
+          '<body>'
+            '<style>'
+              '@main-color: var(b);'
+              '@b: var(c);'
+              '@c: red;'
+              '@d: var(main-color-1, green);'
+              '@border-pen: solid;'
+              '@inset: 5px;'
+              '@frame-color: solid orange;'
+              '@big-border: 2px 2px 2px;'
+              '@border-stuff: 3px dashed var(main-color);'
+              '@border-2: 3px var(big-border) dashed var(main-color-1, green);'
+              '@blue-border: bold var(not-found, 1px 10px blue)'
+            '</style>'
+            '<style>'
+              '.test-1 { color: var(main-color-1, blue); }'
+              '.test-2 { color: var(main-color-1, var(main-color)); }'
+              '.test-3 { color: var(d, yellow); }'
+              '.test-4 { color: var(d-1, yellow); }'
+              '.test-5 { color: var(d-1, var(d)); }'
+              '.test-6 { border: var(inset) var(border-pen) var(d); }'
+              '.test-7 { border: 10px var(border-pen) var(d); }'
+              '.test-8 { border: 20px var(border-pen) yellow; }'
+              '.test-9 { border: 30px dashed var(d); }'
+              '.test-10 { border: 40px var(frame-color);}'
+              '.test-11 { border: 40px var(frame-color-1, blue);}'
+              '.test-12 { border: 40px var(frame-color-1, solid blue);}'
+              '.test-13 {'
+                 'border: 40px var(x1, var(x2, var(x3, var(frame-color)));'
+              '}'
+              '.test-14 { border: 40px var(x1, var(frame-color); }'
+              '.test-15 { border: 40px var(x1, solid blue);}'
+              '.test-16 { border: 1px 1px 2px 3px var(frame-color);}'
+              '.test-17 { border: 1px 1px 2px 3px var(x1, solid blue);}'
+              '.test-18 { border: 1px 1px 2px var(border-stuff);}'
+              '.test-19 { border: var(big-border) var(border-stuff);}'
+              '.test-20 { border: var(border-2);}'
+              '.test-21 { border: var(blue-border);}'
+            '</style>'
+            '<script type="application/dart">main() {}</script>'
+          '</body>'
+        '</html>',
+    };
+  }
+
+  var messages = new Messages.silent();
+  var compiler = createCompiler(createFiles(), messages, errors: true,
+    scopedCss: true);
+
+  compiler.run().then(expectAsync1((e) {
+    MockFileSystem fs = compiler.fileSystem;
+    expect(fs.readCount, equals({
+      'index.html': 1,
+    }), reason: 'Actual:\n  ${fs.readCount}');
+
+    var htmlInfo = compiler.info['index.html'];
+    expect(htmlInfo.styleSheets.length, 2);
+    expect(prettyPrintCss(htmlInfo.styleSheets[0]), '');
+    expect(prettyPrintCss(htmlInfo.styleSheets[1]),
+        '.test-1 { color: blue; } '
+        '.test-2 { color: red; } '
+        '.test-3 { color: green; } '
+        '.test-4 { color: yellow; } '
+        '.test-5 { color: green; } '
+        '.test-6 { border: 5px solid green; } '
+        '.test-7 { border: 10px solid green; } '
+        '.test-8 { border: 20px solid yellow; } '
+        '.test-9 { border: 30px dashed green; } '
+        '.test-10 { border: 40px solid orange; } '
+        '.test-11 { border: 40px blue; } '
+        '.test-12 { border: 40px solid blue; } '
+        '.test-13 { border: 40px solid orange; } '
+        '.test-14 { border: 40px solid orange; } '
+        '.test-15 { border: 40px solid blue; } '
+        '.test-16 { border: 1px 1px 2px 3px solid orange; } '
+        '.test-17 { border: 1px 1px 2px 3px solid blue; } '
+        '.test-18 { border: 1px 1px 2px 3px dashed red; } '
+        '.test-19 { border: 2px 2px 2px 3px dashed red; } '
+        '.test-20 { border: 3px 2px 2px 2px dashed green; } '
+        '.test-21 { border: bold 1px 10px blue; }');
+    var outputs = compiler.output.map((o) => o.path);
+    expect(outputs, equals([
+      'out/index.html.dart',
+      'out/index.html.dart.map',
+      'out/index.html_bootstrap.dart',
+      'out/index.html',
+    ]));
+  }));
+}
+
+test_simple_import() {
+  Map createFiles() {
+    return {
+      'foo.css':  r'''@main_color: var(b);
+        @b: var(c);
+        @c: red;''',
+      'index.html':
+        '<!DOCTYPE html>'
+        '<html lang="en">'
+          '<head>'
+             '<meta charset="utf-8">'
+          '</head>'
+          '<body>'
+            '<style>'
+              '@import "foo.css";'
+              '.test { color: var(main_color); }'
+            '</style>'
+            '<script type="application/dart">main() {}</script>'
+          '</body>'
+        '</html>',
+    };
+  }
+
+  var messages = new Messages.silent();
+  var compiler = createCompiler(createFiles(), messages, errors: true,
+      scopedCss: true);
+
+  compiler.run().then(expectAsync1((e) {
+    MockFileSystem fs = compiler.fileSystem;
+    expect(fs.readCount, equals({
+      'foo.css': 1,
+      'index.html': 1,
+    }), reason: 'Actual:\n  ${fs.readCount}');
+
+    var cssInfo = compiler.info['foo.css'];
+    expect(cssInfo.styleSheets.length, 1);
+    expect(prettyPrintCss(cssInfo.styleSheets[0]), '');
+
+    var htmlInfo = compiler.info['index.html'];
+    expect(htmlInfo.styleSheets.length, 1);
+    expect(prettyPrintCss(htmlInfo.styleSheets[0]),
+        '@import url(foo.css); .test { color: red; }');
+
+    var outputs = compiler.output.map((o) => o.path);
+    expect(outputs, equals([
+      'out/index.html.dart',
+      'out/index.html.dart.map',
+      'out/index.html_bootstrap.dart',
+      'out/foo.css',
+      'out/index.html',
+    ]));
+  }));
+}
+
+test_imports() {
+  Map createFiles() {
+    return {
+      'first.css':
+        '@import "third.css";'
+        '@main-width: var(main-width-b);'
+        '@main-width-b: var(main-width-c);'
+        '@main-width-c: var(wide-width);',
+      'second.css':
+        '@import "fourth.css";'
+        '@main-color: var(main-color-b);'
+        '@main-color-b: var(main-color-c);'
+        '@main-color-c: var(color-value);',
+      'third.css':
+        '@wide-width: var(wide-width-b);'
+        '@wide-width-b: var(wide-width-c);'
+        '@wide-width-c: 100px;',
+      'fourth.css':
+        '@color-value: var(color-value-b);'
+        '@color-value-b: var(color-value-c);'
+        '@color-value-c: red;',
+      'index.html':
+        '<!DOCTYPE html>'
+        '<html lang="en">'
+          '<head>'
+            '<meta charset="utf-8">'
+            '<link rel="stylesheet" href="first.css">'
+          '</head>'
+          '<body>'
+            '<style>'
+              '@import "first.css";'
+              '@import "second.css";'
+              '.test-1 { color: var(main-color); }'
+              '.test-2 { width: var(main-width); }'
+            '</style>'
+            '<script type="application/dart">main() {}</script>'
+          '</body>'
+        '</html>',
+    };
+  }
+
+  var messages = new Messages.silent();
+  var compiler = createCompiler(createFiles(), messages, errors: true,
+      scopedCss: true);
+
+  compiler.run().then(expectAsync1((e) {
+    MockFileSystem fs = compiler.fileSystem;
+    expect(fs.readCount, equals({
+      'first.css': 1,
+      'second.css': 1,
+      'third.css': 1,
+      'fourth.css': 1,
+      'index.html': 1,
+    }), reason: 'Actual:\n  ${fs.readCount}');
+
+    var firstInfo = compiler.info['first.css'];
+    expect(firstInfo.styleSheets.length, 1);
+    expect(prettyPrintCss(firstInfo.styleSheets[0]), '@import url(third.css);');
+
+    var secondInfo = compiler.info['second.css'];
+    expect(secondInfo.styleSheets.length, 1);
+    expect(prettyPrintCss(secondInfo.styleSheets[0]),
+        '@import url(fourth.css);');
+
+    var thirdInfo = compiler.info['third.css'];
+    expect(thirdInfo.styleSheets.length, 1);
+    expect(prettyPrintCss(thirdInfo.styleSheets[0]), '');
+
+    var fourthInfo = compiler.info['fourth.css'];
+    expect(fourthInfo.styleSheets.length, 1);
+    expect(prettyPrintCss(fourthInfo.styleSheets[0]), '');
+
+    var htmlInfo = compiler.info['index.html'];
+    expect(htmlInfo.styleSheets.length, 1);
+    expect(prettyPrintCss(htmlInfo.styleSheets[0]),
+        '@import url(first.css); '
+        '@import url(second.css); '
+        '.test-1 { color: red; } '
+        '.test-2 { width: 100px; }');
+
+    var outputs = compiler.output.map((o) => o.path);
+    expect(outputs, equals([
+      'out/index.html.dart',
+      'out/index.html.dart.map',
+      'out/index.html_bootstrap.dart',
+      'out/first.css',
+      'out/second.css',
+      'out/third.css',
+      'out/fourth.css',
+      'out/index.html',
+    ]));
+  }));
+}
+
+test_component_var() {
+  Map createFiles() {
+    return {
+      'index.html': '<!DOCTYPE html>'
+                    '<html lang="en">'
+                      '<head>'
+                        '<meta charset="utf-8">'
+                        '<link rel="import" href="foo.html">'
+                      '</head>'
+                      '<body>'
+                        '<x-foo></x-foo>'
+                        '<script type="application/dart">main() {}</script>'
+                      '</body>'
+                    '</html>',
+      'foo.html': '<!DOCTYPE html>'
+                  '<html lang="en">'
+                    '<head>'
+                      '<meta charset="utf-8">'
+                    '</head>'
+                    '<body>'
+                      '<polymer-element name="x-foo" constructor="Foo">'
+                        '<template>'
+                          '<style scoped>'
+                            '@import "foo.css";'
+                            '.main { color: var(main_color); }'
+                            '.test-background { '
+                              'background:  url(http://www.foo.com/bar.png);'
+                            '}'
+                          '</style>'
+                        '</template>'
+                      '</polymer-element>'
+                    '</body>'
+                  '</html>',
+      'foo.css':  r'''@main_color: var(b);
+                      @b: var(c);
+                      @c: red;
+
+                      @one: var(two);
+                      @two: var(one);
+
+                      @four: var(five);
+                      @five: var(six);
+                      @six: var(four);
+
+                      @def-1: var(def-2);
+                      @def-2: var(def-3);
+                      @def-3: var(def-2);''',
+    };
+  }
+
+  test('var- and Less @define', () {
+    var messages = new Messages.silent();
+    var compiler = createCompiler(createFiles(), messages, errors: true,
+      scopedCss: true);
+
+    compiler.run().then(expectAsync1((e) {
+      MockFileSystem fs = compiler.fileSystem;
+      expect(fs.readCount, equals({
+        'index.html': 1,
+        'foo.html': 1,
+        'foo.css': 1
+      }), reason: 'Actual:\n  ${fs.readCount}');
+
+      var cssInfo = compiler.info['foo.css'];
+      expect(cssInfo.styleSheets.length, 1);
+      var htmlInfo = compiler.info['foo.html'];
+      expect(htmlInfo.styleSheets.length, 0);
+      expect(htmlInfo.declaredComponents.length, 1);
+      expect(htmlInfo.declaredComponents[0].styleSheets.length, 1);
+
+      var outputs = compiler.output.map((o) => o.path);
+      expect(outputs, equals([
+        'out/foo.html.dart',
+        'out/foo.html.dart.map',
+        'out/index.html.dart',
+        'out/index.html.dart.map',
+        'out/index.html_bootstrap.dart',
+        'out/foo.css',
+        'out/index.html.css',
+        'out/index.html',
+      ]));
+
+      for (var file in compiler.output) {
+        if (file.path == 'out/index.html.css') {
+          expect(file.contents,
+              '/* Auto-generated from components style tags. */\n'
+              '/* DO NOT EDIT. */\n\n'
+              '/* ==================================================== \n'
+              '   Component x-foo stylesheet \n'
+              '   ==================================================== */\n'
+              '@import "foo.css";\n'
+              '[is="x-foo"] .main {\n'
+              '  color: #f00;\n'
+              '}\n'
+              '[is="x-foo"] .test-background {\n'
+              '  background: url("http://www.foo.com/bar.png");\n'
+              '}\n\n');
+        } else if (file.path == 'out/foo.css') {
+          expect(file.contents,
+              '/* Auto-generated from style sheet href = foo.css */\n'
+              '/* DO NOT EDIT. */\n\n\n\n');
+        }
+      }
+
+      // Check for warning messages about var- cycles.
+      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)');
+    }));
+  });
+}
+
+test_pseudo_element() {
+  var messages = new Messages.silent();
+  var compiler = createCompiler({
+    'index.html': '<head>'
+                  '<link rel="import" href="foo.html">'
+                  '<style>'
+                    '.test::x-foo { background-color: red; }'
+                    '.test::x-foo1 { color: blue; }'
+                    '.test::x-foo2 { color: green; }'
+                  '</style>'
+                  '<body>'
+                    '<x-foo class=test></x-foo>'
+                    '<x-foo></x-foo>'
+                  '<script type="application/dart">main() {}</script>',
+    'foo.html': '<head>'
+                '<body><polymer-element name="x-foo" constructor="Foo">'
+                '<template>'
+                  '<div pseudo="x-foo">'
+                    '<div>Test</div>'
+                  '</div>'
+                  '<div pseudo="x-foo1 x-foo2">'
+                  '<div>Test</div>'
+                  '</div>'
+                '</template>',
+    }, messages, scopedCss: true);
+
+    compiler.run().then(expectAsync1((e) {
+      MockFileSystem fs = compiler.fileSystem;
+      expect(fs.readCount, equals({
+        'index.html': 1,
+        'foo.html': 1,
+      }), reason: 'Actual:\n  ${fs.readCount}');
+
+      var outputs = compiler.output.map((o) => o.path);
+      expect(outputs, equals([
+        'out/foo.html.dart',
+        'out/foo.html.dart.map',
+        'out/index.html.dart',
+        'out/index.html.dart.map',
+        'out/index.html_bootstrap.dart',
+        'out/index.html',
+      ]));
+      expect(compiler.output.last.contents, contains(
+          '<div pseudo="x-foo_0">'
+            '<div>Test</div>'
+          '</div>'
+          '<div pseudo="x-foo1_1 x-foo2_2">'
+          '<div>Test</div>'
+          '</div>'));
+      expect(compiler.output.last.contents, contains(
+          '<style>.test > *[pseudo="x-foo_0"] {\n'
+            '  background-color: #f00;\n'
+          '}\n'
+          '.test > *[pseudo="x-foo1_1"] {\n'
+          '  color: #00f;\n'
+          '}\n'
+          '.test > *[pseudo="x-foo2_2"] {\n'
+          '  color: #008000;\n'
+          '}'
+          '</style>'));
+    }));
+}
+
+main() {
+  useCompactVMConfiguration();
+
+  group('css', () {
+    setUp(() {
+      utils.path = new path.Builder(style: path.Style.posix);
+    });
+
+    tearDown(() {
+      utils.path = new path.Builder();
+    });
+
+    test('test_simple_var', test_simple_var);
+    test('test_var', test_var);
+    test('test_simple_import', test_simple_import);
+    test('test_imports', test_imports);
+    group('test_component_var', test_component_var);
+    test('test_pseudo_element', test_pseudo_element);
+  });
+}
diff --git a/pkg/polymer/test/data/unit/event_path_test.html b/pkg/polymer/test/data/unit/event_path_test.html
new file mode 100644
index 0000000..811479d
--- /dev/null
+++ b/pkg/polymer/test/data/unit/event_path_test.html
@@ -0,0 +1,142 @@
+<!doctype html>
+<!--
+   Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+   for details. All rights reserved. Use of this source code is governed by a
+   BSD-style license that can be found in the LICENSE file.
+-->
+<html>
+  <head>
+    <title>event path</title>
+    <script src="packages/polymer/testing/testing.js"></script>
+    <script src="packages/unittest/test_controller.js"></script>
+    <!--
+    Test ported from:
+    https://github.com/Polymer/polymer/blob/7936ff8/test/html/event-path.html
+
+    This test actually doesn't test the polymer's event layer. It just ensures
+    that tests are propagated in the right order when using Shadow DOM.
+    -->
+  </head>
+  <body>
+
+  <polymer-element name="x-selector">
+    <template>
+      <div id="selectorDiv">
+        <content id="selectorContent"></content>
+      </div>
+    </template>
+    <script type="application/dart">
+      import 'package:polymer/polymer.dart';
+      @CustomTag("x-selector")
+      class XSelector extends PolymerElement {}
+    </script>
+  </polymer-element>
+
+  <polymer-element name="x-overlay">
+    <template>
+      <content id="overlayContent"></content>
+    </template>
+    <script type="application/dart">
+      import 'package:polymer/polymer.dart';
+      @CustomTag("x-overlay")
+      class XOverlay extends PolymerElement {}
+    </script>
+  </polymer-element>
+
+  <polymer-element name="x-menu" extends="x-selector">
+    <template>
+      <div id="menuDiv">
+        <shadow id="menuShadow"></shadow>
+      </div>
+    </template>
+    <script type="application/dart">
+      import 'package:polymer/polymer.dart';
+      @CustomTag("x-menu")
+      class XMenu extends PolymerElement {}
+    </script>
+  </polymer-element>
+
+  <polymer-element name="x-menu-button">
+    <template>
+    <div>
+      <x-overlay id="overlay">
+        <div id="menuButtonDiv">
+          <x-menu id="menu">
+            <content id="menuButtonContent"></content>
+          </x-menu>
+        </div>
+      </x-overlay>
+      </div>
+    </template>
+    <script type="application/dart">
+      import 'package:polymer/polymer.dart';
+      @CustomTag("x-menu-button")
+      class XMenuButton extends PolymerElement {}
+    </script>
+  </polymer-element>
+
+  <x-menu-button id="menuButton">
+    <div id="item1"><div id="source"></div>Item1</div>
+    <div id="item2">Item2</div>
+  </x-menu-button>
+
+
+  <script type="application/dart">
+    import 'dart:html';
+    import 'dart:async';
+    import 'package:unittest/unittest.dart';
+    import 'package:unittest/html_config.dart';
+
+    main() {
+      useHtmlConfiguration();
+      test('bubbling in the right order', () {
+        // TODO(sigmund): this should change once we port over the
+        // 'WebComponentsReady' event.
+        runAsync(expectAsync0(() {
+          var item1 = query('#item1');
+          var menuButton = query('#menuButton');
+          // Note: polymer uses automatic node finding (menuButton.$.menu)
+          // also note that their node finding code also reachs into the ids
+          // from the parent shadow (menu.$.selectorContent instead of
+          // menu.$.menuShadow.$.selectorContent)
+          var menu = menuButton.shadowRoot.query('#menu');
+          var selector = menu.shadowRoot.query("#menuShadow");
+          var overlay = menuButton.shadowRoot.query('#overlay');
+          var expectedPath = <Node>[
+              item1,
+              menuButton.shadowRoot.query('#menuButtonContent'),
+              selector.olderShadowRoot.query('#selectorContent'),
+              selector.olderShadowRoot.query('#selectorDiv'),
+              menu.shadowRoot.query('#menuShadow').olderShadowRoot,
+              menu.shadowRoot.query('#menuShadow'),
+              menu.shadowRoot.query('#menuDiv'),
+              menu.shadowRoot,
+              menu,
+              menuButton.shadowRoot.query('#menuButtonDiv'),
+              // TODO(sigmund): this test is currently broken because currently
+              // registerElement is sensitive to the order in which each custom
+              // element is registered. When fixed, we should be able to add the
+              // following three targets:
+              //   overlay.shadowRoot.query('#overlayContent'),
+              //   overlay.shadowRoot,
+              //   overlay,
+              menuButton.shadowRoot,
+              menuButton
+          ];
+          var x = 0;
+          for (int i = 0; i < expectedPath.length; i++) {
+            var node = expectedPath[i];
+            expect(node, isNotNull, reason: "Should not be null at $i");
+            node.on['x'].listen(expectAsync1((e) {
+              expect(e.currentTarget, node);
+              expect(x++, i);
+            }));
+          }
+
+          item1.dispatchEvent(new Event('x', canBubble: true));
+        }));
+      });
+    }
+  </script>
+  </body>
+</html>
diff --git a/pkg/polymer/test/data/unit/events_test.html b/pkg/polymer/test/data/unit/events_test.html
new file mode 100644
index 0000000..cbf33d1
--- /dev/null
+++ b/pkg/polymer/test/data/unit/events_test.html
@@ -0,0 +1,97 @@
+<!doctype html>
+<!--
+   Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+   for details. All rights reserved. Use of this source code is governed by a
+   BSD-style license that can be found in the LICENSE file.
+-->
+<html>
+  <head>
+    <title>event path</title>
+    <script src="packages/polymer/testing/testing.js"></script>
+    <script src="packages/unittest/test_controller.js"></script>
+    <!--
+    Test ported from:
+    https://github.com/Polymer/polymer/blob/7936ff8/test/js/events.js
+
+    TODO(sigmund): when we have support for mutation observers, render all of
+    the test in Dart (like events.js does in JS)
+    -->
+  </head>
+  <body>
+
+  <polymer-element name="test-a" on-click="clickHandler">
+    <template></template>
+    <script type="application/dart">
+      import 'package:polymer/polymer.dart';
+
+      @CustomTag("test-a")
+      class TestA extends PolymerElement {
+        List clicks = [];
+        void clickHandler() {
+          clicks.add('host click on: $localName (id $id)');
+        }
+      }
+    </script>
+  </polymer-element>
+
+  <polymer-element name="test-b">
+    <template>
+      <div>
+        <span id="b-1">1</span>
+        <span id="b-2" on-click="clickHandler">2</span>
+      </div>
+    </template>
+    <script type="application/dart">
+      import 'package:polymer/polymer.dart';
+
+      @CustomTag("test-b")
+      class TestB extends PolymerElement {
+        List clicks = [];
+        void clickHandler(event, detail, target) {
+          clicks.add('local click under $localName (id $id) on ${target.id}');
+        }
+      }
+    </script>
+  </polymer-element>
+
+  <test-a id="a"></test-a>
+  <test-b id="b"></test-b>
+
+  <script type="application/dart">
+    import 'dart:html';
+    import 'dart:async';
+    import 'package:unittest/unittest.dart';
+    import 'package:unittest/html_config.dart';
+
+    main() {
+      useHtmlConfiguration();
+
+      test('host event', () {
+        // Note: this test is currently the only event in
+        // polymer/test/js/events.js at commit #7936ff8
+        Timer.run(expectAsync0(() {
+          var testA = query('#a');
+          expect(testA.xtag.clicks, isEmpty);
+          testA.click();
+          expect(testA.xtag.clicks, ['host click on: test-a (id a)']);
+        }));
+      });
+
+      test('local event', () {
+        Timer.run(expectAsync0(() {
+          var testB = query('#b');
+          expect(testB.xtag.clicks, isEmpty);
+          testB.click();
+          expect(testB.xtag.clicks, []);
+          var b1 = testB.shadowRoot.query('#b-1');
+          b1.click();
+          expect(testB.xtag.clicks, []);
+          var b2 = testB.shadowRoot.query('#b-2');
+          b2.click();
+          expect(testB.xtag.clicks, ['local click under test-b (id b) on b-2']);
+        }));
+      });
+    }
+  </script>
+  </body>
+</html>
diff --git a/pkg/polymer/test/paths_test.dart b/pkg/polymer/test/paths_test.dart
new file mode 100644
index 0000000..4a54a9d
--- /dev/null
+++ b/pkg/polymer/test/paths_test.dart
@@ -0,0 +1,339 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/** Tests for [PathMapper]. */
+library path_info_test;
+
+import 'package:path/path.dart' as path;
+import 'package:polymer/src/info.dart';
+import 'package:polymer/src/paths.dart';
+import 'package:polymer/src/utils.dart' as utils;
+import 'package:unittest/compact_vm_config.dart';
+import 'package:unittest/unittest.dart';
+
+main() {
+  useCompactVMConfiguration();
+  group('paths', () {
+    setUp(() {
+      utils.path = new path.Builder(style: path.Style.posix);
+    });
+
+    tearDown(() {
+      utils.path = new path.Builder();
+    });
+
+    testPaths();
+  });
+}
+
+testPaths() {
+  group('outdir == basedir:', () {
+    group('outputPath', () {
+      test('mangle automatic', () {
+        var pathMapper = _newPathMapper('a', 'a', false);
+        var file = _mockFile('a/b.dart', pathMapper);
+        expect(file.dartCodeUrl.resolvedPath, 'a/b.dart');
+        expect(pathMapper.outputPath(file.dartCodeUrl.resolvedPath, '.dart'),
+            'a/_b.dart.dart');
+      });
+
+      test('within packages/', () {
+        var pathMapper = _newPathMapper('a', 'a', false);
+        var file = _mockFile('a/packages/b.dart', pathMapper);
+        expect(file.dartCodeUrl.resolvedPath, 'a/packages/b.dart');
+        expect(pathMapper.outputPath(file.dartCodeUrl.resolvedPath, '.dart'),
+            'a/_from_packages/_b.dart.dart');
+      });
+    });
+
+    group('importUrlFor', () {
+      test('simple pathMapper', () {
+        var pathMapper = _newPathMapper('a', 'a', false);
+        var file1 = _mockFile('a/b.dart', pathMapper);
+        var file2 = _mockFile('a/c/d.dart', pathMapper);
+        var file3 = _mockFile('a/e/f.dart', pathMapper);
+        expect(pathMapper.importUrlFor(file1, file2), 'c/_d.dart.dart');
+        expect(pathMapper.importUrlFor(file1, file3), 'e/_f.dart.dart');
+        expect(pathMapper.importUrlFor(file2, file1), '../_b.dart.dart');
+        expect(pathMapper.importUrlFor(file2, file3), '../e/_f.dart.dart');
+        expect(pathMapper.importUrlFor(file3, file2), '../c/_d.dart.dart');
+        expect(pathMapper.importUrlFor(file3, file1), '../_b.dart.dart');
+      });
+
+      test('include packages/', () {
+        var pathMapper = _newPathMapper('a', 'a', false);
+        var file1 = _mockFile('a/b.dart', pathMapper);
+        var file2 = _mockFile('a/c/d.dart', pathMapper);
+        var file3 = _mockFile('a/packages/f.dart', pathMapper);
+        expect(pathMapper.importUrlFor(file1, file2), 'c/_d.dart.dart');
+        expect(pathMapper.importUrlFor(file1, file3),
+            '_from_packages/_f.dart.dart');
+        expect(pathMapper.importUrlFor(file2, file1), '../_b.dart.dart');
+        expect(pathMapper.importUrlFor(file2, file3),
+            '../_from_packages/_f.dart.dart');
+        expect(pathMapper.importUrlFor(file3, file2), '../c/_d.dart.dart');
+        expect(pathMapper.importUrlFor(file3, file1), '../_b.dart.dart');
+      });
+
+      test('packages, but no rewrite', () {
+        var pathMapper = _newPathMapper('a', 'a', false, rewriteUrls: false);
+        var file1 = _mockFile('a/b.dart', pathMapper);
+        var file2 = _mockFile('a/c/d.dart', pathMapper);
+        var file3 = _mockFile('a/packages/c/f.dart', pathMapper,
+            url: 'package:e/f.dart');
+        expect(pathMapper.importUrlFor(file1, file2), 'c/_d.dart.dart');
+        expect(pathMapper.importUrlFor(file1, file3),
+          'package:e/_f.dart.dart');
+        expect(pathMapper.importUrlFor(file2, file1), '../_b.dart.dart');
+        expect(pathMapper.importUrlFor(file2, file3),
+            'package:e/_f.dart.dart');
+      });
+
+      test('windows paths', () {
+        try {
+          utils.path = new path.Builder(style: path.Style.windows);
+          var pathMapper = _newPathMapper('a', 'a', false);
+          var file1 = _mockFile('a\\b.dart', pathMapper);
+          var file2 = _mockFile('a\\c\\d.dart', pathMapper);
+          var file3 = _mockFile('a\\packages\\f.dart', pathMapper);
+          expect(pathMapper.importUrlFor(file1, file2), 'c/_d.dart.dart');
+          expect(pathMapper.importUrlFor(file1, file3),
+              '_from_packages/_f.dart.dart');
+          expect(pathMapper.importUrlFor(file2, file1), '../_b.dart.dart');
+          expect(pathMapper.importUrlFor(file2, file3),
+              '../_from_packages/_f.dart.dart');
+          expect(pathMapper.importUrlFor(file3, file2), '../c/_d.dart.dart');
+          expect(pathMapper.importUrlFor(file3, file1), '../_b.dart.dart');
+        } finally {
+          utils.path = new path.Builder();
+        }
+      });
+    });
+
+    test('transformUrl simple paths', () {
+      var pathMapper = _newPathMapper('a', 'a', false);
+      var file1 = 'a/b.dart';
+      var file2 = 'a/c/d.html';
+      // when the output == input directory, no paths should be rewritten
+      expect(pathMapper.transformUrl(file1, '/a.dart'), '/a.dart');
+      expect(pathMapper.transformUrl(file1, 'c.dart'), 'c.dart');
+      expect(pathMapper.transformUrl(file1, '../c/d.dart'), '../c/d.dart');
+      expect(pathMapper.transformUrl(file1, 'packages/c.dart'),
+          'packages/c.dart');
+      expect(pathMapper.transformUrl(file2, 'e.css'), 'e.css');
+      expect(pathMapper.transformUrl(file2, '../c/e.css'), 'e.css');
+      expect(pathMapper.transformUrl(file2, '../q/e.css'), '../q/e.css');
+      expect(pathMapper.transformUrl(file2, 'packages/c.css'),
+          'packages/c.css');
+      expect(pathMapper.transformUrl(file2, '../packages/c.css'),
+          '../packages/c.css');
+    });
+
+    test('transformUrl with source in packages/', () {
+      var pathMapper = _newPathMapper('a', 'a', false);
+      var file = 'a/packages/e.html';
+      // Even when output == base, files under packages/ are moved to
+      // _from_packages, so all imports are affected:
+      expect(pathMapper.transformUrl(file, 'e.css'), '../packages/e.css');
+      expect(pathMapper.transformUrl(file, '../packages/e.css'),
+          '../packages/e.css');
+      expect(pathMapper.transformUrl(file, '../q/e.css'), '../q/e.css');
+      expect(pathMapper.transformUrl(file, 'packages/c.css'),
+          '../packages/packages/c.css');
+    });
+  });
+
+  group('outdir != basedir:', () {
+    group('outputPath', (){
+      test('no force mangle', () {
+        var pathMapper = _newPathMapper('a', 'out', false);
+        var file = _mockFile('a/b.dart', pathMapper);
+        expect(file.dartCodeUrl.resolvedPath, 'a/b.dart');
+        expect(pathMapper.outputPath(file.dartCodeUrl.resolvedPath, '.dart'),
+            'out/b.dart');
+      });
+
+      test('force mangling', () {
+        var pathMapper = _newPathMapper('a', 'out', true);
+        var file = _mockFile('a/b.dart', pathMapper);
+        expect(file.dartCodeUrl.resolvedPath, 'a/b.dart');
+        expect(pathMapper.outputPath(file.dartCodeUrl.resolvedPath, '.dart'),
+            'out/_b.dart.dart');
+      });
+
+      test('within packages/, no mangle', () {
+        var pathMapper = _newPathMapper('a', 'out', false);
+        var file = _mockFile('a/packages/b.dart', pathMapper);
+        expect(file.dartCodeUrl.resolvedPath, 'a/packages/b.dart');
+        expect(pathMapper.outputPath(file.dartCodeUrl.resolvedPath, '.dart'),
+            'out/_from_packages/b.dart');
+      });
+
+      test('within packages/, mangle', () {
+        var pathMapper = _newPathMapper('a', 'out', true);
+        var file = _mockFile('a/packages/b.dart', pathMapper);
+        expect(file.dartCodeUrl.resolvedPath, 'a/packages/b.dart');
+        expect(pathMapper.outputPath(file.dartCodeUrl.resolvedPath, '.dart'),
+            'out/_from_packages/_b.dart.dart');
+      });
+    });
+
+    group('importUrlFor', (){
+      test('simple paths, no mangle', () {
+        var pathMapper = _newPathMapper('a', 'out', false);
+        var file1 = _mockFile('a/b.dart', pathMapper);
+        var file2 = _mockFile('a/c/d.dart', pathMapper);
+        var file3 = _mockFile('a/e/f.dart', pathMapper);
+        expect(pathMapper.importUrlFor(file1, file2), 'c/d.dart');
+        expect(pathMapper.importUrlFor(file1, file3), 'e/f.dart');
+        expect(pathMapper.importUrlFor(file2, file1), '../b.dart');
+        expect(pathMapper.importUrlFor(file2, file3), '../e/f.dart');
+        expect(pathMapper.importUrlFor(file3, file2), '../c/d.dart');
+        expect(pathMapper.importUrlFor(file3, file1), '../b.dart');
+      });
+
+      test('simple paths, mangle', () {
+        var pathMapper = _newPathMapper('a', 'out', true);
+        var file1 = _mockFile('a/b.dart', pathMapper);
+        var file2 = _mockFile('a/c/d.dart', pathMapper);
+        var file3 = _mockFile('a/e/f.dart', pathMapper);
+        expect(pathMapper.importUrlFor(file1, file2), 'c/_d.dart.dart');
+        expect(pathMapper.importUrlFor(file1, file3), 'e/_f.dart.dart');
+        expect(pathMapper.importUrlFor(file2, file1), '../_b.dart.dart');
+        expect(pathMapper.importUrlFor(file2, file3), '../e/_f.dart.dart');
+        expect(pathMapper.importUrlFor(file3, file2), '../c/_d.dart.dart');
+        expect(pathMapper.importUrlFor(file3, file1), '../_b.dart.dart');
+      });
+
+      test('include packages/, no mangle', () {
+        var pathMapper = _newPathMapper('a', 'out', false);
+        var file1 = _mockFile('a/b.dart', pathMapper);
+        var file2 = _mockFile('a/c/d.dart', pathMapper);
+        var file3 = _mockFile('a/packages/e/f.dart', pathMapper,
+            url: 'package:e/f.dart');
+        expect(pathMapper.importUrlFor(file1, file2), 'c/d.dart');
+        expect(pathMapper.importUrlFor(file1, file3),
+            '_from_packages/e/f.dart');
+        expect(pathMapper.importUrlFor(file2, file1), '../b.dart');
+        expect(pathMapper.importUrlFor(file2, file3),
+            '../_from_packages/e/f.dart');
+        expect(pathMapper.importUrlFor(file3, file2), '../../c/d.dart');
+        expect(pathMapper.importUrlFor(file3, file1), '../../b.dart');
+      });
+
+      test('include packages/, mangle', () {
+        var pathMapper = _newPathMapper('a', 'out', true);
+        var file1 = _mockFile('a/b.dart', pathMapper);
+        var file2 = _mockFile('a/c/d.dart', pathMapper);
+        var file3 = _mockFile('a/packages/e/f.dart', pathMapper,
+            url: 'package:e/f.dart');
+        expect(pathMapper.importUrlFor(file1, file2), 'c/_d.dart.dart');
+        expect(pathMapper.importUrlFor(file1, file3),
+          '_from_packages/e/_f.dart.dart');
+        expect(pathMapper.importUrlFor(file2, file1), '../_b.dart.dart');
+        expect(pathMapper.importUrlFor(file2, file3),
+            '../_from_packages/e/_f.dart.dart');
+        expect(pathMapper.importUrlFor(file3, file2), '../../c/_d.dart.dart');
+        expect(pathMapper.importUrlFor(file3, file1), '../../_b.dart.dart');
+      });
+
+      test('windows paths', () {
+        try {
+          utils.path = new path.Builder(style: path.Style.windows);
+          var pathMapper = _newPathMapper('a', 'out', true);
+          var file1 = _mockFile('a\\b.dart', pathMapper);
+          var file2 = _mockFile('a\\c\\d.dart', pathMapper);
+          var file3 = _mockFile('a\\packages\\f.dart', pathMapper);
+          expect(pathMapper.importUrlFor(file1, file2), 'c/_d.dart.dart');
+          expect(pathMapper.importUrlFor(file1, file3),
+              '_from_packages/_f.dart.dart');
+          expect(pathMapper.importUrlFor(file2, file1), '../_b.dart.dart');
+          expect(pathMapper.importUrlFor(file2, file3),
+              '../_from_packages/_f.dart.dart');
+          expect(pathMapper.importUrlFor(file3, file2), '../c/_d.dart.dart');
+          expect(pathMapper.importUrlFor(file3, file1), '../_b.dart.dart');
+        } finally {
+          utils.path = new path.Builder();
+        }
+      });
+    });
+
+    group('transformUrl', () {
+      test('simple source, not in packages/', () {
+        var pathMapper = _newPathMapper('a', 'out', false);
+        var file1 = 'a/b.dart';
+        var file2 = 'a/c/d.html';
+        // when the output == input directory, no paths should be rewritten
+        expect(pathMapper.transformUrl(file1, '/a.dart'), '/a.dart');
+        expect(pathMapper.transformUrl(file1, 'c.dart'), '../a/c.dart');
+
+        // reach out from basedir:
+        expect(pathMapper.transformUrl(file1, '../c/d.dart'), '../c/d.dart');
+
+        // reach into packages dir:
+        expect(pathMapper.transformUrl(file1, 'packages/c.dart'),
+            '../a/packages/c.dart');
+
+        expect(pathMapper.transformUrl(file2, 'e.css'), '../../a/c/e.css');
+
+        _checkPath('../../a/c/../c/e.css', '../../a/c/e.css');
+        expect(pathMapper.transformUrl(file2, '../c/e.css'), '../../a/c/e.css');
+
+        _checkPath('../../a/c/../q/e.css', '../../a/q/e.css');
+        expect(pathMapper.transformUrl(file2, '../q/e.css'), '../../a/q/e.css');
+
+        expect(pathMapper.transformUrl(file2, 'packages/c.css'),
+            '../../a/c/packages/c.css');
+        _checkPath('../../a/c/../packages/c.css', '../../a/packages/c.css');
+        expect(pathMapper.transformUrl(file2, '../packages/c.css'),
+            '../../a/packages/c.css');
+      });
+
+      test('input in packages/', () {
+        var pathMapper = _newPathMapper('a', 'out', true);
+        var file = 'a/packages/e.html';
+        expect(pathMapper.transformUrl(file, 'e.css'),
+            '../../a/packages/e.css');
+        expect(pathMapper.transformUrl(file, '../packages/e.css'),
+            '../../a/packages/e.css');
+        expect(pathMapper.transformUrl(file, '../q/e.css'), '../../a/q/e.css');
+        expect(pathMapper.transformUrl(file, 'packages/c.css'),
+            '../../a/packages/packages/c.css');
+      });
+
+      test('src fragments', () {
+        var pathMapper = _newPathMapper('a', 'out', false);
+        var file1 = 'a/b.dart';
+        var file2 = 'a/c/html.html';
+        // when the output == input directory, no paths should be rewritten
+        expect(pathMapper.transformUrl(file1, '#tips'), '#tips');
+        expect(pathMapper.transformUrl(file1,
+            'http://www.w3schools.com/html_links.htm#tips'),
+            'http://www.w3schools.com/html_links.htm#tips');
+        expect(pathMapper.transformUrl(file2,
+          'html_links.html'),
+          '../../a/c/html_links.html');
+        expect(pathMapper.transformUrl(file2,
+            'html_links.html#tips'),
+            '../../a/c/html_links.html#tips');
+      });
+    });
+  });
+}
+
+_newPathMapper(String baseDir, String outDir, bool forceMangle,
+    {bool rewriteUrls: true}) =>
+  new PathMapper(baseDir, outDir, 'packages', forceMangle, rewriteUrls);
+
+_mockFile(String filePath, PathMapper pathMapper, {String url}) {
+  var file = new FileInfo(new UrlInfo(
+        url == null ? filePath : url, filePath, null));
+  file.outputFilename = pathMapper.mangle(
+      utils.path.basename(filePath), '.dart', false);
+  return file;
+}
+
+_checkPath(String filePath, String expected) {
+  expect(utils.path.normalize(filePath), expected);
+}
diff --git a/pkg/polymer/test/run.sh b/pkg/polymer/test/run.sh
new file mode 100755
index 0000000..0d2b569
--- /dev/null
+++ b/pkg/polymer/test/run.sh
@@ -0,0 +1,134 @@
+#!/bin/bash
+# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Usage: call directly in the commandline as test/run.sh ensuring that you have
+# both 'dart' and 'content_shell' in your path. Filter tests by passing a
+# pattern as an argument to this script.
+
+# TODO(sigmund): replace with a real test runner
+
+# bail on error
+set -e
+
+# print commands executed by this script
+# set -x
+
+DIR=$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd )
+export DART_FLAGS="--checked"
+TEST_PATTERN=$1
+
+function fail {
+  return 1
+}
+
+function show_diff {
+  diff -u -N $1 $2 | \
+    sed -e "s/^\(+.*\)/\1/" |\
+    sed -e "s/^\(-.*\)/\1/"
+  return 1
+}
+
+function update {
+  read -p "Would you like to update the expectations? [y/N]: " answer
+  if [[ $answer == 'y' || $answer == 'Y' ]]; then
+    cp $2 $1
+    return 0
+  fi
+  return 1
+}
+
+function pass {
+  echo -e "OK"
+}
+
+function compare {
+  # use a standard diff, if they are not identical, format the diff nicely to
+  # see what's the error and prompt to see if they wish to update it. If they
+  # do, continue running more tests.
+  diff -q $1 $2 && pass || show_diff $1 $2 || update $1 $2
+}
+
+if [[ ($TEST_PATTERN == "") ]]; then
+  # Note: dartanalyzer needs to be run from the root directory for proper path
+  # canonicalization.
+  pushd $DIR/.. > /dev/null
+
+  echo Analyzing compiler for warnings or type errors
+  dartanalyzer --hints --fatal-warnings --fatal-type-errors bin/dwc.dart
+
+  echo -e "\nAnalyzing runtime for warnings or type errors"
+  dartanalyzer --hints --fatal-warnings --fatal-type-errors lib/polymer.dart
+
+  popd > /dev/null
+fi
+
+function compare_all {
+# TODO(jmesserly): bash and dart regexp might not be 100% the same. Ideally we
+# could do all the heavy lifting in Dart code, and keep this script as a thin
+# wrapper that sets `--enable-type-checks --enable-asserts`
+  for input in $DIR/../example/component/news/test/*_test.html \
+               $DIR/../../../samples/third_party/todomvc/test/*_test.html; do
+    if [[ ($TEST_PATTERN == "") || ($input =~ $TEST_PATTERN) ]]; then
+      FILENAME=`basename $input`
+      DIRNAME=`dirname $input`
+      if [[ `basename $DIRNAME` == 'input' ]]; then
+        DIRNAME=`dirname $DIRNAME`
+      fi
+      echo -e -n "Checking diff for $FILENAME "
+      DUMP="$DIRNAME/out/$FILENAME.txt"
+      EXPECTATION="$DIRNAME/expected/$FILENAME.txt"
+
+      compare $EXPECTATION $DUMP
+    fi
+  done
+  echo -e "Some tests failed"
+  fail
+}
+
+if [[ -e $DIR/data/input/example ]]; then
+  echo "WARNING: detected old data/input/example symlink."
+  echo "Removing it and rerunning pub install to fix broken example symlinks."
+  echo "See http://dartbug.com/9418 for more information."
+  echo "You should only see this message once."
+  if [[ -e $DIR/packages ]]; then
+    find . -name packages -type l | xargs rm
+  fi
+  rm $DIR/data/input/example
+  pushd $DIR/..
+  pub install
+  popd
+fi
+
+# TODO(jmesserly): dart:io fails if we run the Dart scripts with an absolute
+# path. So use pushd/popd to change the working directory.
+if [[ ($TEST_PATTERN == "") ]]; then
+  pushd $DIR/.. > /dev/null
+  echo -e "\nTesting build.dart... "
+  dart $DART_FLAGS build.dart
+  # Run it the way the editor does. Hide stdout because it is in noisy machine
+  # format. Show stderr in case something breaks.
+  # NOTE: not using --checked because the editor doesn't use it, and to workaround
+  # http://dartbug.com/9637
+  dart build.dart --machine --clean > /dev/null
+  dart build.dart --machine --full > /dev/null
+  dart build.dart --machine --changed ../../samples/third_party/todomvc/web/index.html > /dev/null
+  popd > /dev/null
+fi
+
+pushd $DIR > /dev/null
+echo -e "\nRunning unit tests... "
+dart $DART_FLAGS run_all.dart $@ || compare_all
+popd > /dev/null
+
+# Run Dart analyzer to check that we're generating warning clean code.
+# It's a bit slow, so only do this for TodoMVC and html5_utils tests.
+OUT_PATTERN="$DIR/../../../third_party/samples/todomvc/test/out/test/*$TEST_PATTERN*_bootstrap.dart"
+if [[ `ls $OUT_PATTERN 2>/dev/null` != "" ]]; then
+  echo -e "\nAnalyzing generated code for warnings or type errors."
+  ls $OUT_PATTERN 2>/dev/null | dartanalyzer --package-root=packages \
+      --fatal-warnings --fatal-type-errors -batch
+fi
+
+echo -e "All tests pass"
diff --git a/pkg/polymer/test/run_all.dart b/pkg/polymer/test/run_all.dart
new file mode 100644
index 0000000..b149502
--- /dev/null
+++ b/pkg/polymer/test/run_all.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * This is a helper for run.sh. We try to run all of the Dart code in one
+ * instance of the Dart VM to reduce warm-up time.
+ */
+library run_impl;
+
+import 'dart:io';
+import 'package:unittest/compact_vm_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:polymer/testing/content_shell_test.dart';
+
+import 'css_test.dart' as css_test;
+import 'compiler_test.dart' as compiler_test;
+import 'paths_test.dart' as paths_test;
+import 'utils_test.dart' as utils_test;
+
+main() {
+  var args = new Options().arguments;
+  var pattern = new RegExp(args.length > 0 ? args[0] : '.');
+
+  useCompactVMConfiguration();
+
+  void addGroup(testFile, testMain) {
+    if (pattern.hasMatch(testFile)) {
+      group(testFile.replaceAll('_test.dart', ':'), testMain);
+    }
+  }
+
+  addGroup('compiler_test.dart', compiler_test.main);
+  addGroup('css_test.dart', css_test.main);
+  addGroup('paths_test.dart', paths_test.main);
+  addGroup('utils_test.dart', utils_test.main);
+
+  endToEndTests('data/unit/', 'data/out');
+
+  // Note: if you're adding more render test suites, make sure to update run.sh
+  // as well for convenient baseline diff/updating.
+
+  // TODO(jmesserly): figure out why this fails in content_shell but works in
+  // Dartium and Firefox when using the ShadowDOM polyfill.
+  exampleTest('../example/component/news', ['--no-shadowdom']..addAll(args));
+
+  exampleTest('../../../samples/third_party/todomvc');
+}
+
+void exampleTest(String path, [List<String> args]) {
+  renderTests(path, '$path/test', '$path/test/expected', '$path/test/out',
+      arguments: args);
+}
+
+void cssCompileMangleTest(String path, String pattern,
+    [bool deleteDirectory = true]) {
+  renderTests(path, path, '$path/expected', '$path/out',
+      arguments: ['--css-mangle'], pattern: pattern,
+      deleteDir: deleteDirectory);
+}
+
+void cssCompilePolyFillTest(String path, String pattern, String cssReset,
+    [bool deleteDirectory = true]) {
+  var args = ['--no-css-mangle'];
+  if (cssReset != null) {
+    args.addAll(['--css-reset', '${path}/${cssReset}']);
+  }
+  renderTests(path, path, '$path/expected', '$path/out',
+      arguments: args, pattern: pattern, deleteDir: deleteDirectory);
+}
+
+void cssCompileShadowDOMTest(String path, String pattern,
+    [bool deleteDirectory = true]) {
+  var args = ['--no-css'];
+  renderTests(path, path, '$path/expected', '$path/out',
+      arguments: args, pattern: pattern,
+      deleteDir: deleteDirectory);
+}
diff --git a/pkg/polymer/test/testing.dart b/pkg/polymer/test/testing.dart
new file mode 100644
index 0000000..c89b416
--- /dev/null
+++ b/pkg/polymer/test/testing.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/** Common definitions used for setting up the test environment. */
+library testing;
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:csslib/visitor.dart';
+import 'package:html5lib/dom.dart';
+import 'package:html5lib/parser.dart';
+import 'package:polymer/src/analyzer.dart';
+import 'package:polymer/src/compiler.dart';
+import 'package:polymer/src/file_system.dart';
+import 'package:polymer/src/info.dart';
+import 'package:polymer/src/messages.dart';
+import 'package:polymer/src/compiler_options.dart';
+import 'package:polymer/src/files.dart';
+import 'package:polymer/src/utils.dart';
+
+
+Document parseDocument(String html) => parse(html);
+
+Element parseSubtree(String html) => parseFragment(html).nodes[0];
+
+FileInfo analyzeDefinitionsInTree(Document doc, Messages messages,
+    {String packageRoot: 'packages'}) {
+
+  return analyzeDefinitions(new GlobalInfo(), new UrlInfo('', '', null),
+      doc, packageRoot, messages);
+}
+
+/** Parses files in [fileContents], with [mainHtmlFile] being the main file. */
+List<SourceFile> parseFiles(Map<String, String> fileContents,
+    [String mainHtmlFile = 'index.html']) {
+
+  var result = <SourceFile>[];
+  fileContents.forEach((filename, contents) {
+    var src = new SourceFile(filename);
+    src.document = parse(contents);
+    result.add(src);
+  });
+
+  return result;
+}
+
+/** Analyze all files. */
+Map<String, FileInfo> analyzeFiles(List<SourceFile> files,
+    {Messages messages, String packageRoot: 'packages'}) {
+  messages = messages == null ? new Messages.silent() : messages;
+  var result = new Map<String, FileInfo>();
+
+  // analyze definitions
+  var global = new GlobalInfo();
+  for (var file in files) {
+    var path = file.path;
+    result[path] = analyzeDefinitions(global, new UrlInfo(path, path, null),
+        file.document, packageRoot, messages);
+  }
+
+  // analyze file contents
+  var uniqueIds = new IntIterator();
+  var pseudoElements = new Map();
+  for (var file in files) {
+    analyzeFile(file, result, uniqueIds, pseudoElements, messages, true);
+  }
+  return result;
+}
+
+Compiler createCompiler(Map files, Messages messages, {bool errors: false,
+    bool scopedCss: false}) {
+  List baseOptions = ['--no-colors', '-o', 'out', '--deploy', 'index.html'];
+  if (errors) baseOptions.insert(0, '--warnings_as_errors');
+  if (scopedCss) baseOptions.insert(0, '--scoped-css');
+  var options = CompilerOptions.parse(baseOptions);
+  var fs = new MockFileSystem(files);
+  return new Compiler(fs, options, messages);
+}
+
+String prettyPrintCss(StyleSheet styleSheet) =>
+    ((new CssPrinter())..visitTree(styleSheet)).toString();
+
+/**
+ * Abstraction around file system access to work in a variety of different
+ * environments.
+ */
+class MockFileSystem extends FileSystem {
+  final Map _files;
+  final Map readCount = {};
+
+  MockFileSystem(this._files);
+
+  Future readTextOrBytes(String filename) => readText(filename);
+
+  Future<String> readText(String path) {
+    readCount[path] = readCount.putIfAbsent(path, () => 0) + 1;
+    var file = _files[path];
+    if (file != null) {
+      return new Future.value(file);
+    } else {
+      return new Future.error(
+          new FileException('MockFileSystem: $path not found'));
+    }
+  }
+
+  // Compiler doesn't call these
+  void writeString(String outfile, String text) {}
+  Future flush() {}
+}
diff --git a/pkg/polymer/test/utils_test.dart b/pkg/polymer/test/utils_test.dart
new file mode 100644
index 0000000..393d215
--- /dev/null
+++ b/pkg/polymer/test/utils_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/** Tests for some of the utility helper functions used by the compiler. */
+library utils_test;
+
+import 'package:unittest/compact_vm_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:polymer/src/utils.dart';
+
+main() {
+  useCompactVMConfiguration();
+
+  for (bool startUppercase in [false, true]) {
+    Matcher caseEquals(String str) {
+      if (startUppercase) str = str[0].toUpperCase() + str.substring(1);
+      return equals(str);
+    }
+
+    camelCase(str) => toCamelCase(str, startUppercase: startUppercase);
+
+    group('toCamelCase startUppercase=$startUppercase', () {
+      test('empty', () {
+        expect(camelCase(''), equals(''));
+      });
+
+      test('single token', () {
+        expect(camelCase('a'), caseEquals('a'));
+        expect(camelCase('ab'), caseEquals('ab'));
+        expect(camelCase('Ab'), caseEquals('Ab'));
+        expect(camelCase('AB'), caseEquals('AB'));
+        expect(camelCase('long_word'), caseEquals('long_word'));
+      });
+
+      test('dashes in the middle', () {
+        expect(camelCase('a-b'), caseEquals('aB'));
+        expect(camelCase('a-B'), caseEquals('aB'));
+        expect(camelCase('A-b'), caseEquals('AB'));
+        expect(camelCase('long-word'), caseEquals('longWord'));
+      });
+
+      test('leading/trailing dashes', () {
+        expect(camelCase('-hi'), caseEquals('Hi'));
+        expect(camelCase('hi-'), caseEquals('hi'));
+        expect(camelCase('hi-friend-'), caseEquals('hiFriend'));
+      });
+
+      test('consecutive dashes', () {
+        expect(camelCase('--hi-friend'), caseEquals('HiFriend'));
+        expect(camelCase('hi--friend'), caseEquals('hiFriend'));
+        expect(camelCase('hi-friend--'), caseEquals('hiFriend'));
+      });
+    });
+  }
+
+  group('toHyphenedName', () {
+    test('empty', () {
+      expect(toHyphenedName(''), '');
+    });
+
+    test('all lower case', () {
+      expect(toHyphenedName('a'), 'a');
+      expect(toHyphenedName('a-b'), 'a-b');
+      expect(toHyphenedName('aBc'), 'a-bc');
+      expect(toHyphenedName('abC'), 'ab-c');
+      expect(toHyphenedName('abc-d'), 'abc-d');
+      expect(toHyphenedName('long_word'), 'long_word');
+    });
+
+    test('capitalized letters in the middle/end', () {
+      expect(toHyphenedName('aB'), 'a-b');
+      expect(toHyphenedName('longWord'), 'long-word');
+    });
+
+    test('leading capital letters', () {
+      expect(toHyphenedName('Hi'), 'hi');
+      expect(toHyphenedName('Hi-'), 'hi-');
+      expect(toHyphenedName('HiFriend'), 'hi-friend');
+    });
+
+    test('consecutive capital letters', () {
+      expect(toHyphenedName('aBC'), 'a-b-c');
+    });
+  });
+}
diff --git a/pkg/scheduled_test/lib/scheduled_process.dart b/pkg/scheduled_test/lib/scheduled_process.dart
index 3ff903c..27ebc17 100644
--- a/pkg/scheduled_test/lib/scheduled_process.dart
+++ b/pkg/scheduled_test/lib/scheduled_process.dart
@@ -5,6 +5,7 @@
 library scheduled_test.scheduled_process;
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
 
 import 'scheduled_test.dart';
@@ -203,7 +204,7 @@
       return chunk;
     })
         .transform(new StringDecoder(_encoding))
-        .transform(new LineTransformer()));
+        .transform(new LineSplitter()));
   }
 
   /// Schedule an exception handler that will clean up the process and provide
diff --git a/pkg/scheduled_test/test/metatest.dart b/pkg/scheduled_test/test/metatest.dart
index 4834b6e..9e94d07 100644
--- a/pkg/scheduled_test/test/metatest.dart
+++ b/pkg/scheduled_test/test/metatest.dart
@@ -200,10 +200,9 @@
 
 /// Special test configuration for use within the child isolates. This hides all
 /// output and reports data back to the parent isolate.
-class _MetaConfiguration extends SimpleConfiguration {
-  final name = "MetaConfiguration";
+class _MetaConfiguration extends Configuration {
 
-  void logTestCaseMesssage(TestCase testCase, String message) {}
+  _MetaConfiguration() : super.blank();
 
   void onSummary(int passed, int failed, int errors, List<TestCase> results,
       String uncaughtError) {
@@ -220,7 +219,4 @@
       }).toList()
     });
   }
-
-  void onInit() {}
-  void onDone(bool success) {}
 }
diff --git a/pkg/scheduled_test/test/scheduled_process_test.dart b/pkg/scheduled_test/test/scheduled_process_test.dart
index b855e02..33cfa7c 100644
--- a/pkg/scheduled_test/test/scheduled_process_test.dart
+++ b/pkg/scheduled_test/test/scheduled_process_test.dart
@@ -5,6 +5,7 @@
 library scheduled_process_test;
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
 
 import 'package:path/path.dart' as path;
@@ -367,11 +368,12 @@
       var utilsPath = path.absolute(path.join(Platform.script, 'utils.dart'));
       return new File(path.join(dir, 'test.dart')).writeAsString('''
           import 'dart:async';
+          import 'dart:convert';
           import 'dart:io';
 
           var stdinLines = stdin
               .transform(new StringDecoder())
-              .transform(new LineTransformer());
+              .transform(new LineSplitter());
 
           void main() {
             $script
diff --git a/pkg/stack_trace/lib/src/frame.dart b/pkg/stack_trace/lib/src/frame.dart
index 3db4ab5..b222737 100644
--- a/pkg/stack_trace/lib/src/frame.dart
+++ b/pkg/stack_trace/lib/src/frame.dart
@@ -134,6 +134,12 @@
     }
   }
 
+  /// Parses a string representation of an IE stack frame.
+  ///
+  /// IE10+ frames look just like V8 frames. Prior to IE10, stack traces can't
+  /// be retrieved.
+  factory Frame.parseIE(String frame) => new Frame.parseV8(frame);
+
   /// Parses a string representation of a Firefox stack frame.
   factory Frame.parseFirefox(String frame) {
     var match = _firefoxFrame.firstMatch(frame);
@@ -155,6 +161,12 @@
     return new Frame(uri, int.parse(match[4]), null, member);
   }
 
+  /// Parses a string representation of a Safari stack frame.
+  ///
+  /// Safari 6+ frames look just like Firefox frames. Prior to Safari 6, stack
+  /// traces can't be retrieved.
+  factory Frame.parseSafari(String frame) => new Frame.parseFirefox(frame);
+
   /// Parses this package's string representation of a stack frame.
   factory Frame.parseFriendly(String frame) {
     var match = _friendlyFrame.firstMatch(frame);
diff --git a/pkg/stack_trace/lib/src/trace.dart b/pkg/stack_trace/lib/src/trace.dart
index 863d64e..19f0a12 100644
--- a/pkg/stack_trace/lib/src/trace.dart
+++ b/pkg/stack_trace/lib/src/trace.dart
@@ -14,6 +14,14 @@
 
 final _terseRegExp = new RegExp(r"(-patch)?(/.*)?$");
 
+/// A RegExp to match V8's stack traces.
+///
+/// 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 ");
+
 /// A RegExp to match Firefox's stack traces.
 ///
 /// Firefox's trace frames start with the name of the function in which the
@@ -74,8 +82,9 @@
   factory Trace.parse(String trace) {
     try {
       if (trace.isEmpty) return new Trace(<Frame>[]);
-      if (trace.startsWith("Error\n")) return new Trace.parseV8(trace);
-      if (trace.contains(_firefoxTrace)) return new Trace.parseFirefox(trace);
+      if (trace.contains(_v8Trace)) return new Trace.parseV8(trace);
+      // Valid Safari traces are a superset of valid Firefox traces.
+      if (trace.contains(_firefoxTrace)) return new Trace.parseSafari(trace);
       if (trace.contains(_friendlyTrace)) return new Trace.parseFriendly(trace);
 
       // Default to parsing the stack trace as a VM trace. This is also hit on
@@ -93,13 +102,36 @@
 
   /// Parses a string representation of a Chrome/V8 stack trace.
   Trace.parseV8(String trace)
-      : this(trace.split("\n").skip(1).map((line) => new Frame.parseV8(line)));
+      : this(trace.split("\n").skip(1)
+          // 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 "))
+          .map((line) => new Frame.parseV8(line)));
+
+  /// Parses a string representation of an Internet Explorer stack trace.
+  ///
+  /// IE10+ traces look just like V8 traces. Prior to IE10, stack traces can't
+  /// be retrieved.
+  Trace.parseIE(String trace)
+      : this.parseV8(trace);
 
   /// Parses a string representation of a Firefox stack trace.
   Trace.parseFirefox(String trace)
       : this(trace.trim().split("\n")
           .map((line) => new Frame.parseFirefox(line)));
 
+  /// Parses a string representation of a Safari stack trace.
+  ///
+  /// Safari 6+ stack traces look just like Firefox traces, except that they
+  /// sometimes (e.g. in isolates) have a "[native code]" frame. We just ignore
+  /// this frame to make the stack format more consistent between browsers.
+  /// Prior to Safari 6, stack traces can't be retrieved.
+  Trace.parseSafari(String trace)
+      : this(trace.trim().split("\n")
+          .where((line) => line != '[native code]')
+          .map((line) => new Frame.parseFirefox(line)));
+
   /// Parses this package's a string representation of a stack trace.
   Trace.parseFriendly(String trace)
       : this(trace.trim().split("\n")
diff --git a/pkg/stack_trace/test/trace_test.dart b/pkg/stack_trace/test/trace_test.dart
index 92b2b20..c3ce039 100644
--- a/pkg/stack_trace/test/trace_test.dart
+++ b/pkg/stack_trace/test/trace_test.dart
@@ -61,6 +61,35 @@
           equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
       expect(trace.frames[2].uri,
           equals(Uri.parse("http://pub.dartlang.org/thing.js")));
+
+      trace = new Trace.parse(
+          "Exception: foo\n"
+          '    at Foo._bar (http://pub.dartlang.org/stuff.js:42:21)\n'
+          '    at http://pub.dartlang.org/stuff.js:0:2\n'
+          '    at zip.<anonymous>.zap '
+              '(http://pub.dartlang.org/thing.js:1:100)');
+
+      expect(trace.frames[0].uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
+      expect(trace.frames[1].uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
+      expect(trace.frames[2].uri,
+          equals(Uri.parse("http://pub.dartlang.org/thing.js")));
+
+      trace = new Trace.parse(
+          'Exception: foo\n'
+          '    bar\n'
+          '    at Foo._bar (http://pub.dartlang.org/stuff.js:42:21)\n'
+          '    at http://pub.dartlang.org/stuff.js:0:2\n'
+          '    at zip.<anonymous>.zap '
+              '(http://pub.dartlang.org/thing.js:1:100)');
+
+      expect(trace.frames[0].uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
+      expect(trace.frames[1].uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
+      expect(trace.frames[2].uri,
+          equals(Uri.parse("http://pub.dartlang.org/thing.js")));
     });
 
     test('parses a Firefox stack trace correctly', () {
@@ -101,6 +130,22 @@
           equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
     });
 
+    test('.parseSafari', () {
+      var trace = new Trace.parse(
+          'Foo._bar@http://pub.dartlang.org/stuff.js:42\n'
+          'zip/<@http://pub.dartlang.org/stuff.js:0\n'
+          'zip.zap(12, "@)()/<")@http://pub.dartlang.org/thing.js:1\n'
+          '[native code]');
+
+      expect(trace.frames[0].uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
+      expect(trace.frames[1].uri,
+          equals(Uri.parse("http://pub.dartlang.org/stuff.js")));
+      expect(trace.frames[2].uri,
+          equals(Uri.parse("http://pub.dartlang.org/thing.js")));
+      expect(trace.frames.length, equals(3));
+    });
+
     test('parses a package:stack_trace stack trace correctly', () {
       var trace = new Trace.parse(
           'http://dartlang.org/foo/bar.dart 10:11  Foo.<fn>.bar\n'
diff --git a/pkg/unittest/lib/src/configuration.dart b/pkg/unittest/lib/src/configuration.dart
index 4571b90..c9ec1c0 100644
--- a/pkg/unittest/lib/src/configuration.dart
+++ b/pkg/unittest/lib/src/configuration.dart
@@ -1,4 +1,4 @@
-// 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.
 
@@ -16,10 +16,17 @@
   factory Configuration() => new SimpleConfiguration();
 
   /**
+   * Creates an [Configuration] instances that does nothing.
+   *
+   * For use by subclasses which wish to implement only a subset of features.
+   */
+  Configuration.blank();
+
+  /**
    * If [true], tests are started automatically. Otherwise [runTests]
    * must be called explicitly after tests are set up.
    */
-  bool get autoStart;
+  bool get autoStart => true;
 
   /**
    * Called as soon as the unittest framework becomes initialized. This is done
@@ -28,7 +35,7 @@
    * It is also used to tell the vm or browser that tests are going to be run
    * asynchronously and that the process should wait until they are done.
    */
-  void onInit();
+  void onInit() {}
 
   /** Called as soon as the unittest framework starts running. */
   void onStart() {}
@@ -37,31 +44,31 @@
    * Called when each test starts. Useful to show intermediate progress on
    * a test suite.
    */
-  void onTestStart(TestCase testCase);
+  void onTestStart(TestCase testCase) {}
 
   /**
    * Called when each test is first completed. Useful to show intermediate
    * progress on a test suite.
    */
-  void onTestResult(TestCase testCase);
+  void onTestResult(TestCase testCase) {}
 
   /**
    * Called when an already completed test changes state. For example: a test
    * that was marked as passing may later be marked as being in error because
    * it still had callbacks being invoked.
    */
-  void onTestResultChanged(TestCase testCase);
+  void onTestResultChanged(TestCase testCase) {}
 
   /**
    * Handles the logging of messages by a test case.
    */
-  void onLogMessage(TestCase testCase, String message);
+  void onLogMessage(TestCase testCase, String message) {}
 
   /**
    * Called when the unittest framework is done running. [success] indicates
    * whether all tests passed successfully.
    */
-  void onDone(bool success);
+  void onDone(bool success) {}
 
   /**
    * Called with the result of all test cases. Browser tests commonly override
@@ -71,6 +78,6 @@
    * of tests (e.g. setting up the test).
    */
   void onSummary(int passed, int failed, int errors, List<TestCase> results,
-      String uncaughtError);
+      String uncaughtError) {}
 }
 
diff --git a/pkg/unittest/lib/src/simple_configuration.dart b/pkg/unittest/lib/src/simple_configuration.dart
index b9d3a02..d4a0f6e 100644
--- a/pkg/unittest/lib/src/simple_configuration.dart
+++ b/pkg/unittest/lib/src/simple_configuration.dart
@@ -22,7 +22,7 @@
  * advantage of the platform can create a subclass and override methods from
  * this class.
  */
-class SimpleConfiguration implements Configuration {
+class SimpleConfiguration extends Configuration {
   // The VM won't shut down if a receive port is open. Use this to make sure
   // we correctly wait for asynchronous tests.
   ReceivePort _receivePort;
@@ -32,7 +32,7 @@
    * Particularly useful in cases where we have parent/child configurations
    * such as layout tests.
    */
-  final String name = 'Configuration';
+  String get name => 'Configuration';
 
   bool get autoStart => true;
 
@@ -56,7 +56,7 @@
    * The constructor sets up a failure handler for [expect] that redirects
    * [expect] failures to [onExpectFailure].
    */
-  SimpleConfiguration() {
+  SimpleConfiguration() : super.blank() {
     configureExpectFailureHandler(new _ExpectFailureHandler(this));
   }
 
@@ -65,8 +65,6 @@
     _postMessage('unittest-suite-wait-for-done');
   }
 
-  void onStart() {}
-
   /**
    * Called when each test starts. Useful to show intermediate progress on
    * a test suite. Derived classes should call this first before their own
diff --git a/pkg/unittest/test/unittest_test_utils.dart b/pkg/unittest/test/unittest_test_utils.dart
index 03fc8d6..7d9a922 100644
--- a/pkg/unittest/test/unittest_test_utils.dart
+++ b/pkg/unittest/test/unittest_test_utils.dart
@@ -33,7 +33,7 @@
       '$setup:$teardown:$uncaughtError$testDetails';
 }
 
-class TestConfiguration extends SimpleConfiguration {
+class TestConfiguration extends Configuration {
 
   // Some test state that is captured.
   int count = 0; // A count of callbacks.
@@ -44,9 +44,7 @@
   final SendPort _port;
   String _result;
 
-  TestConfiguration(this._port);
-
-  void onInit() {}
+  TestConfiguration(this._port) : super.blank();
 
   void onSummary(int passed, int failed, int errors, List<TestCase> results,
       String uncaughtError) {
diff --git a/runtime/bin/dbg_connection.cc b/runtime/bin/dbg_connection.cc
index e5d4f6b..e5abc5e 100644
--- a/runtime/bin/dbg_connection.cc
+++ b/runtime/bin/dbg_connection.cc
@@ -260,7 +260,9 @@
                                           int msg_id,
                                           const char* err_msg) {
   dart::TextBuffer msg(64);
-  msg.Printf("{\"id\": %d, \"error\": \"Error: %s\"}", msg_id, err_msg);
+  msg.Printf("{\"id\": %d, \"error\": \"Error: ", msg_id);
+  msg.AddEscapedString(err_msg);
+  msg.Printf("\"}");
   SendMsg(debug_fd, &msg);
 }
 
diff --git a/runtime/bin/dbg_message.cc b/runtime/bin/dbg_message.cc
index caec295..36cfeba 100644
--- a/runtime/bin/dbg_message.cc
+++ b/runtime/bin/dbg_message.cc
@@ -50,6 +50,14 @@
 }
 
 
+bool MessageParser::HasParam(const char* name) const {
+  const char* params = Params();
+  ASSERT(params != NULL);
+  dart::JSONReader r(params);
+  return r.Seek(name);
+}
+
+
 intptr_t MessageParser::GetIntParam(const char* name) const {
   const char* params = Params();
   ASSERT(params != NULL);
@@ -224,13 +232,13 @@
     intptr_t len = 0;
     Dart_Handle res = Dart_ListLength(object, &len);
     ASSERT_NOT_ERROR(res);
-    buf->Printf("\"kind\":\"list\",\"length\":%"Pd",", len);
+    buf->Printf("\"kind\":\"list\",\"length\":%" Pd ",", len);
   } else {
     buf->Printf("\"kind\":\"object\",");
     intptr_t class_id = 0;
     Dart_Handle res = Dart_GetObjClassId(object, &class_id);
     if (!Dart_IsError(res)) {
-      buf->Printf("\"classId\":%"Pd",", class_id);
+      buf->Printf("\"classId\":%" Pd ",", class_id);
     }
   }
   buf->Printf("\"text\":\"");
@@ -250,7 +258,7 @@
 static void FormatRemoteObj(dart::TextBuffer* buf, Dart_Handle object) {
   intptr_t obj_id = Dart_CacheObject(object);
   ASSERT(obj_id >= 0);
-  buf->Printf("{\"objectId\":%"Pd",", obj_id);
+  buf->Printf("{\"objectId\":%" Pd ",", obj_id);
   FormatValue(buf, object);
   buf->Printf("}");
 }
@@ -300,9 +308,9 @@
   RETURN_IF_ERROR(name);
   buf->Printf("{\"name\":\"%s\",", GetStringChars(name));
   if (super_id > 0) {
-    buf->Printf("\"superclassId\":%"Pd",", super_id);
+    buf->Printf("\"superclassId\":%" Pd ",", super_id);
   }
-  buf->Printf("\"libraryId\":%"Pd",", library_id);
+  buf->Printf("\"libraryId\":%" Pd ",", library_id);
   RETURN_IF_ERROR(static_fields);
   buf->Printf("\"fields\":");
   FormatNamedValueList(buf, static_fields);
@@ -366,7 +374,7 @@
   }
   Dart_Handle res = Dart_GetObjClassId(object, &class_id);
   RETURN_IF_ERROR(res);
-  buf->Printf("{\"classId\": %"Pd",", class_id);
+  buf->Printf("{\"classId\": %" Pd ",", class_id);
   buf->Printf("\"kind\":\"object\",\"fields\":");
   Dart_Handle fields = Dart_GetInstanceFields(object);
   RETURN_IF_ERROR(fields);
@@ -383,8 +391,8 @@
                                    intptr_t slice_length) {
   intptr_t end_index = index + slice_length;
   ASSERT(end_index <= list_length);
-  buf->Printf("{\"index\":%"Pd",", index);
-  buf->Printf("\"length\":%"Pd",", slice_length);
+  buf->Printf("{\"index\":%" Pd ",", index);
+  buf->Printf("\"length\":%" Pd ",", slice_length);
   buf->Printf("\"elements\":[");
   for (intptr_t i = index; i < end_index; i++) {
     Dart_Handle value = Dart_ListGetAt(list, i);
@@ -470,6 +478,7 @@
   { "getClassProperties", DbgMessage::HandleGetClassPropsCmd },
   { "getLibraryProperties", DbgMessage::HandleGetLibPropsCmd },
   { "setLibraryProperties", DbgMessage::HandleSetLibPropsCmd },
+  { "evaluateExpr", DbgMessage::HandleEvaluateExprCmd },
   { "getObjectProperties", DbgMessage::HandleGetObjPropsCmd },
   { "getListElements", DbgMessage::HandleGetListCmd },
   { "getGlobalVariables", DbgMessage::HandleGetGlobalsCmd },
@@ -633,6 +642,54 @@
 }
 
 
+bool DbgMessage::HandleEvaluateExprCmd(DbgMessage* in_msg) {
+  ASSERT(in_msg != NULL);
+  MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
+  int msg_id = msg_parser.MessageId();
+  Dart_Handle target;
+
+  if (msg_parser.HasParam("libraryId")) {
+    in_msg->SendErrorReply(msg_id,
+                           "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;
+  } else if (msg_parser.HasParam("objectId")) {
+    intptr_t obj_id = msg_parser.GetIntParam("objectId");
+    target = Dart_GetCachedObject(obj_id);
+  } else {
+    in_msg->SendErrorReply(msg_id, "illegal evaluation target");
+    return false;
+  }
+
+  if (Dart_IsError(target)) {
+    in_msg->SendErrorReply(msg_id, Dart_GetError(target));
+    return false;
+  }
+  char* expr_chars = msg_parser.GetStringParam("expression");
+  Dart_Handle expr = Dart_NewStringFromCString(expr_chars);
+  if (Dart_IsError(expr)) {
+    in_msg->SendErrorReply(msg_id, Dart_GetError(expr));
+    return false;
+  }
+
+  Dart_Handle value = Dart_EvaluateExpr(target, expr);
+  if (Dart_IsError(value)) {
+    in_msg->SendErrorReply(msg_id, Dart_GetError(value));
+    return false;
+  }
+
+  dart::TextBuffer msg(64);
+  msg.Printf("{\"id\":%d, \"result\":", msg_id);
+  FormatRemoteObj(&msg, value);
+  msg.Printf("}");
+  in_msg->SendReply(&msg);
+  return false;
+}
+
+
 bool DbgMessage::HandleGetObjPropsCmd(DbgMessage* in_msg) {
   ASSERT(in_msg != NULL);
   MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
@@ -869,7 +926,7 @@
   Dart_Handle res = Dart_IntegerToUint64(bp_id, &bp_id_value);
   ASSERT_NOT_ERROR(res);
   dart::TextBuffer msg(64);
-  msg.Printf("{ \"id\": %d, \"result\": { \"breakpointId\": %"Pu64" }}",
+  msg.Printf("{ \"id\": %d, \"result\": { \"breakpointId\": %" Pu64 " }}",
              msg_id, bp_id_value);
   in_msg->SendReply(&msg);
   return false;
@@ -992,7 +1049,7 @@
   dart::TextBuffer msg(128);
   msg.Printf("{ \"event\": \"paused\", \"params\": { ");
   msg.Printf("\"reason\": \"breakpoint\", ");
-  msg.Printf("\"isolateId\": %"Pd64"", isolate_id_);
+  msg.Printf("\"isolateId\": %" Pd64 "", isolate_id_);
   if (!Dart_IsNull(location.script_url)) {
     ASSERT(Dart_IsString(location.script_url));
     msg.Printf(",\"location\": { \"url\":");
@@ -1014,7 +1071,7 @@
   dart::TextBuffer msg(128);
   msg.Printf("{ \"event\": \"paused\", \"params\": {");
   msg.Printf("\"reason\": \"exception\", ");
-  msg.Printf("\"isolateId\": %"Pd64", ", isolate_id_);
+  msg.Printf("\"isolateId\": %" Pd64 ", ", isolate_id_);
   msg.Printf("\"exception\":");
   FormatRemoteObj(&msg, exception);
   FormatLocationFromTrace(&msg, stack_trace, ", ");
@@ -1034,7 +1091,7 @@
     ASSERT_NOT_ERROR(res);
     msg.Printf("{ \"event\": \"paused\", \"params\": { ");
     msg.Printf("\"reason\": \"interrupted\", ");
-    msg.Printf("\"isolateId\": %"Pd64"", isolate_id);
+    msg.Printf("\"isolateId\": %" Pd64 "", isolate_id);
     FormatLocationFromTrace(&msg, trace, ", ");
     msg.Printf("}}");
   } else {
@@ -1045,7 +1102,7 @@
       ASSERT(kind == kShutdown);
       msg.Printf("\"reason\": \"shutdown\", ");
     }
-    msg.Printf("\"id\": %"Pd64" ", isolate_id);
+    msg.Printf("\"id\": %" Pd64 " ", isolate_id);
     msg.Printf("}}");
   }
   DebuggerConnectionHandler::BroadcastMsg(&msg);
@@ -1170,10 +1227,10 @@
     return;  // No items in the list.
   }
   DbgMsgQueue* queue = list_;
-  msg->Printf("%"Pd64"", queue->isolate_id());
+  msg->Printf("%" Pd64 "", queue->isolate_id());
   queue = queue->next();
   while (queue != NULL) {
-    msg->Printf(",%"Pd64"", queue->isolate_id());
+    msg->Printf(",%" Pd64 "", queue->isolate_id());
     queue = queue->next();
   }
 }
@@ -1185,9 +1242,9 @@
   Dart_EnterScope();
   dart::TextBuffer msg(128);
   msg.Printf("{ \"event\": \"breakpointResolved\", \"params\": {");
-  msg.Printf("\"breakpointId\": %"Pd"", bp_id);
+  msg.Printf("\"breakpointId\": %" Pd "", bp_id);
 
-  msg.Printf(", \"isolateId\":%"Pd64"", isolate_id);
+  msg.Printf(", \"isolateId\":%" Pd64 "", isolate_id);
   ASSERT(!Dart_IsNull(location.script_url));
   ASSERT(Dart_IsString(location.script_url));
   msg.Printf(", \"location\":{\"url\":");
diff --git a/runtime/bin/dbg_message.h b/runtime/bin/dbg_message.h
index ca05255..5386318 100644
--- a/runtime/bin/dbg_message.h
+++ b/runtime/bin/dbg_message.h
@@ -43,6 +43,7 @@
   int MessageId() const;
 
   const char* Params() const;
+  bool HasParam(const char* name) const;
   intptr_t GetIntParam(const char* name) const;
   intptr_t GetOptIntParam(const char* name, intptr_t default_val) const;
 
@@ -103,6 +104,7 @@
   static bool HandleGetLibPropsCmd(DbgMessage* msg);
   static bool HandleSetLibPropsCmd(DbgMessage* msg);
   static bool HandleGetGlobalsCmd(DbgMessage* msg);
+  static bool HandleEvaluateExprCmd(DbgMessage* msg);
   static bool HandleGetObjPropsCmd(DbgMessage* msg);
   static bool HandleGetListCmd(DbgMessage* msg);
   static bool HandleGetScriptURLsCmd(DbgMessage* msg);
diff --git a/runtime/bin/eventhandler_linux.cc b/runtime/bin/eventhandler_linux.cc
index 111e7e6..6d15c9e 100644
--- a/runtime/bin/eventhandler_linux.cc
+++ b/runtime/bin/eventhandler_linux.cc
@@ -171,7 +171,7 @@
     if (result == -1) {
       perror("Interrupt message failure:");
     }
-    FATAL1("Interrupt message failure. Wrote %"Pd" bytes.", result);
+    FATAL1("Interrupt message failure. Wrote %" Pd " bytes.", result);
   }
 }
 
diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
index 971ef1b..419c93e 100644
--- a/runtime/bin/eventhandler_macos.cc
+++ b/runtime/bin/eventhandler_macos.cc
@@ -190,7 +190,7 @@
     if (result == -1) {
       perror("Interrupt message failure:");
     }
-    FATAL1("Interrupt message failure. Wrote %"Pd" bytes.", result);
+    FATAL1("Interrupt message failure. Wrote %" Pd " bytes.", result);
   }
 }
 
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index ff790d6..2948ce8 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -35,6 +35,8 @@
   V(Platform_LocalHostname, 0)                                                 \
   V(Platform_ExecutableName, 0)                                                \
   V(Platform_Environment, 0)                                                   \
+  V(Platform_ExecutableArguments, 0)                                           \
+  V(Platform_PackageRoot, 0)                                                   \
   V(Platform_GetVersion, 0)                                                    \
   V(Process_Start, 10)                                                         \
   V(Process_Wait, 5)                                                           \
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 57c5168..7e5138e 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -339,6 +339,8 @@
     }
   }
 
+  // The arguments to the VM are at positions 1 through i-1 in argv.
+  Platform::SetExecutableArguments(i, argv);
 
   // Get the script name.
   if (i < argc) {
@@ -461,6 +463,7 @@
     return NULL;
   }
 
+  Platform::SetPackageRoot(package_root);
   Dart_Handle io_lib_url = DartUtils::NewString("dart:io");
   CHECK_RESULT(io_lib_url);
   Dart_Handle io_lib = Dart_LookupLibrary(io_lib_url);
diff --git a/runtime/bin/platform.cc b/runtime/bin/platform.cc
index 4d1bbed..f7a2920 100644
--- a/runtime/bin/platform.cc
+++ b/runtime/bin/platform.cc
@@ -13,6 +13,9 @@
 namespace bin {
 
 const char* Platform::executable_name_ = NULL;
+const char* Platform::package_root_ = NULL;
+int Platform::script_index_ = 1;
+char** Platform::argv_ = NULL;
 
 void FUNCTION_NAME(Platform_NumberOfProcessors)(Dart_NativeArguments args) {
   Dart_SetReturnValue(args, Dart_NewInteger(Platform::NumberOfProcessors()));
@@ -46,6 +49,31 @@
       args, Dart_NewStringFromCString(Platform::GetExecutableName()));
 }
 
+
+void FUNCTION_NAME(Platform_ExecutableArguments)(Dart_NativeArguments args) {
+  int end = Platform::GetScriptIndex();
+  char** argv = Platform::GetArgv();
+  Dart_Handle result = Dart_NewList(end - 1);
+  for (intptr_t i = 1; i < end; i++) {
+    Dart_Handle str = DartUtils::NewString(argv[i]);
+    Dart_Handle error = Dart_ListSetAt(result, i - 1, str);
+    if (Dart_IsError(error)) {
+      Dart_PropagateError(error);
+    }
+  }
+  Dart_SetReturnValue(args, result);
+}
+
+
+void FUNCTION_NAME(Platform_PackageRoot)(Dart_NativeArguments args) {
+  const char* package_root = Platform::GetPackageRoot();
+  if (package_root == NULL) {
+    package_root = "";
+  }
+  Dart_SetReturnValue(args, Dart_NewStringFromCString(package_root));
+}
+
+
 void FUNCTION_NAME(Platform_Environment)(Dart_NativeArguments args) {
   intptr_t count = 0;
   char** env = Platform::Environment(&count);
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index dd195c3..ca723ae3 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -42,8 +42,31 @@
     return executable_name_;
   }
 
+  // Stores and gets the package root.
+  static void SetPackageRoot(const char* package_root) {
+    package_root_ = package_root;
+  }
+  static const char* GetPackageRoot() {
+    return package_root_;
+  }
+
+  // Stores and gets the flags passed to the executable.
+  static void SetExecutableArguments(int script_index, char** argv) {
+    script_index_ = script_index;
+    argv_ = argv;
+  }
+  static int GetScriptIndex() {
+    return script_index_;
+  }
+  static char** GetArgv() {
+    return argv_;
+  }
+
  private:
   static const char* executable_name_;
+  static const char* package_root_;
+  static int script_index_;
+  static char** argv_;  // VM flags are argv_[1 ... script_index_ - 1]
 
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(Platform);
diff --git a/runtime/bin/platform_patch.dart b/runtime/bin/platform_patch.dart
index cfe7a80..fe1e90c 100644
--- a/runtime/bin/platform_patch.dart
+++ b/runtime/bin/platform_patch.dart
@@ -11,5 +11,8 @@
   /* patch */ static _localHostname() native "Platform_LocalHostname";
   /* patch */ static _executable() native "Platform_ExecutableName";
   /* patch */ static _environment() native "Platform_Environment";
+  /* patch */ static List<String> _executableArguments()
+       native "Platform_ExecutableArguments";
+  /* patch */ static String _packageRoot() native "Platform_PackageRoot";
   /* patch */ static String _version() native "Platform_GetVersion";
 }
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index 9daac7d..7ff4198 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -52,7 +52,7 @@
       (run_filter == kAllBenchmarks) ||
       (strcmp(run_filter, this->name()) == 0)) {
     this->Run();
-    OS::Print("%s(RunTime): %"Pd"\n", this->name(), this->score());
+    OS::Print("%s(RunTime): %" Pd "\n", this->name(), this->score());
     run_matches++;
   } else if (run_filter == kList) {
     fprintf(stdout, "%s\n", this->name());
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index aa3963a..4f35fab 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -2010,6 +2010,39 @@
                                                      void** peer);
 
 /**
+ * Gets an integer native argument at some index.
+ * \param args Native arguments structure.
+ * \param arg_index Index of the desired argument in the structure above.
+ * \param value Returns the integer value if the argument is an Integer.
+ * \return Success if no error occurs. Otherwise returns an error handle.
+ */
+DART_EXPORT Dart_Handle Dart_GetNativeIntegerArgument(Dart_NativeArguments args,
+                                                      int index,
+                                                      int64_t* value);
+
+/**
+ * Gets a boolean native argument at some index.
+ * \param args Native arguments structure.
+ * \param arg_index Index of the desired argument in the structure above.
+ * \param value Returns the boolean value if the argument is a Boolean.
+ * \return Success if no error occurs. Otherwise returns an error handle.
+ */
+DART_EXPORT Dart_Handle Dart_GetNativeBooleanArgument(Dart_NativeArguments args,
+                                                      int index,
+                                                      bool* value);
+
+/**
+ * Gets a double native argument at some index.
+ * \param args Native arguments structure.
+ * \param arg_index Index of the desired argument in the structure above.
+ * \param value Returns the double value if the argument is a double.
+ * \return Success if no error occurs. Otherwise returns an error handle.
+ */
+DART_EXPORT Dart_Handle Dart_GetNativeDoubleArgument(Dart_NativeArguments args,
+                                                     int index,
+                                                     double* value);
+
+/**
  * Sets the return value for a native function.
  */
 DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args,
@@ -2022,7 +2055,7 @@
                                             bool retval);
 
 DART_EXPORT void Dart_SetIntegerReturnValue(Dart_NativeArguments args,
-                                            intptr_t retval);
+                                            int64_t retval);
 
 DART_EXPORT void Dart_SetDoubleReturnValue(Dart_NativeArguments args,
                                            double retval);
diff --git a/runtime/include/dart_debugger_api.h b/runtime/include/dart_debugger_api.h
index 36249ff..b847a91 100755
--- a/runtime/include/dart_debugger_api.h
+++ b/runtime/include/dart_debugger_api.h
@@ -472,6 +472,25 @@
 
 
 /**
+ * Execute the expression given in string \expr in the context
+ * of \target.
+ *
+ * Requires there to be a current isolate.
+ *
+ * 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.
+ * 
+ * \return A handle to the computed value, or an error object if
+ * the compilation of the expression fails, or if the evaluation throws
+ * an error.
+ */
+DART_EXPORT Dart_Handle Dart_EvaluateExpr(Dart_Handle target,
+                                          Dart_Handle expr);
+
+
+/**
  * Returns the class of the given \object.
  *
  * Requires there to be a current isolate.
diff --git a/runtime/lib/array.cc b/runtime/lib/array.cc
index da55de9..7116f5b 100644
--- a/runtime/lib/array.cc
+++ b/runtime/lib/array.cc
@@ -19,7 +19,7 @@
       isolate, arguments->NativeArgAt(1));
   if (!length.IsSmi()) {
     const String& error = String::Handle(String::NewFormatted(
-        "Length must be an integer in the range [0..%"Pd"].",
+        "Length must be an integer in the range [0..%" Pd "].",
         Array::kMaxElements));
     const Array& args = Array::Handle(Array::New(1));
     args.SetAt(0, error);
@@ -28,7 +28,7 @@
   intptr_t len = Smi::Cast(length).Value();
   if (len < 0 || len > Array::kMaxElements) {
     const String& error = String::Handle(String::NewFormatted(
-        "Length (%"Pd") must be an integer in the range [0..%"Pd"].",
+        "Length (%" Pd ") must be an integer in the range [0..%" Pd "].",
         len, Array::kMaxElements));
     const Array& args = Array::Handle(Array::New(1));
     args.SetAt(0, error);
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index 04006e5..f69e963 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -172,16 +172,6 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(Double_pow, 2) {
-  const double operand =
-      Double::CheckedHandle(arguments->NativeArgAt(0)).value();
-  GET_NON_NULL_NATIVE_ARGUMENT(
-      Double, exponent_object, arguments->NativeArgAt(1));
-  const double exponent = exponent_object.value();
-  return Double::New(pow(operand, exponent));
-}
-
-
 #if defined(TARGET_OS_MACOS)
 // MAC OSX math library produces old style cast warning.
 #pragma GCC diagnostic ignored "-Wold-style-cast"
diff --git a/runtime/lib/double.dart b/runtime/lib/double.dart
index 29247ad..166d731 100644
--- a/runtime/lib/double.dart
+++ b/runtime/lib/double.dart
@@ -126,21 +126,6 @@
   int toInt() native "Double_toInt";
   double toDouble() { return this; }
 
-  double pow(num exponent) {
-    if (exponent == 0) {
-      return 1.0;  // ECMA-262 15.8.2.13
-    }
-    if (exponent is! num) {
-      throw new ArgumentError(null);
-    }
-    double doubleExponent = exponent.toDouble();
-    if (isNaN || exponent.isNaN) {
-      return double.NAN;
-    }
-    return _pow(doubleExponent);
-  }
-  double _pow(double exponent) native "Double_pow";
-
   String toStringAsFixed(int fractionDigits) {
     // See ECMAScript-262, 15.7.4.5 for details.
 
diff --git a/runtime/lib/integers.dart b/runtime/lib/integers.dart
index aaf5712..dca7ef8 100644
--- a/runtime/lib/integers.dart
+++ b/runtime/lib/integers.dart
@@ -163,23 +163,6 @@
   int toInt() { return this; }
   double toDouble() { return new _Double.fromInteger(this); }
 
-  int pow(int exponent) {
-    // Exponentiation by squaring.
-    int base = this;
-    int result = 1;
-    while (exponent != 0) {
-      if ((exponent & 1) == 1) {
-        result *= base;
-      }
-      exponent >>= 1;
-      // Skip unnecessary operation (can overflow to Mint or Bigint).
-      if (exponent != 0) {
-        base *= base;
-      }
-    }
-    return result;
-  }
-
   String toStringAsFixed(int fractionDigits) {
     return this.toDouble().toStringAsFixed(fractionDigits);
   }
diff --git a/runtime/lib/math.cc b/runtime/lib/math.cc
index 317045d..ca7c7e6 100644
--- a/runtime/lib/math.cc
+++ b/runtime/lib/math.cc
@@ -66,6 +66,15 @@
   return Double::New(log(operand.value()));
 }
 
+DEFINE_NATIVE_ENTRY(Math_doublePow, 2) {
+  const double operand =
+      Double::CheckedHandle(arguments->NativeArgAt(0)).value();
+  GET_NON_NULL_NATIVE_ARGUMENT(
+      Double, exponent_object, arguments->NativeArgAt(1));
+  const double exponent = exponent_object.value();
+  return Double::New(pow(operand, exponent));
+}
+
 
 // Returns the typed-data array store in '_Random._state' field.
 static RawTypedData* GetRandomStateArray(const Instance& receiver) {
diff --git a/runtime/lib/math_patch.dart b/runtime/lib/math_patch.dart
index 1bf701d..00cacdf 100644
--- a/runtime/lib/math_patch.dart
+++ b/runtime/lib/math_patch.dart
@@ -10,10 +10,38 @@
 // an [int], otherwise the result is a [double].
 patch num pow(num x, num exponent) {
   if ((x is int) && (exponent is int) && (exponent >= 0)) {
-    return x.pow(exponent);
+    return _intPow(x, exponent);
   }
-  // Double.pow will call exponent.toDouble().
-  return x.toDouble().pow(exponent);
+  return _doublePow(x.toDouble(), exponent.toDouble());
+}
+
+double _doublePow(double base, double exponent) {
+  if (exponent == 0.0) {
+    return 1.0;  // ECMA-262 15.8.2.13
+  }
+  if (base == 1.0) return 1.0;
+  if (base.isNaN || exponent.isNaN) {
+    return double.NAN;
+  }
+  return _pow(base, exponent);
+}
+
+double _pow(double base, double exponent) native "Math_doublePow";
+
+int _intPow(int base, int exponent) {
+  // Exponentiation by squaring.
+  int result = 1;
+  while (exponent != 0) {
+    if ((exponent & 1) == 1) {
+      result *= base;
+    }
+    exponent >>= 1;
+    // Skip unnecessary operation (can overflow to Mint or Bigint).
+    if (exponent != 0) {
+      base *= base;
+    }
+  }
+  return result;
 }
 
 patch double atan2(num a, num b) => _atan2(a.toDouble(), b.toDouble());
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 7ab68b6..e0c8b23 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -305,9 +305,16 @@
   GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0));
   const Class& cls = Class::Handle(type.type_class());
   ASSERT(!cls.IsNull());
-  return CreateClassMirror(cls,
-                           AbstractType::Handle(),
-                           Instance::null_instance());
+  // Strip the type for generics only.
+  if (cls.NumTypeParameters() == 0) {
+    return CreateClassMirror(cls,
+                             type,
+                             Object::null_instance());
+  } else {
+    return CreateClassMirror(cls,
+                             AbstractType::Handle(),
+                             Object::null_instance());
+  }
 }
 
 
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 88a89cc..ea63f90 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -369,6 +369,15 @@
   final Type _reflectedType;
   final bool _isGeneric;
 
+  bool get hasReflectedType => _reflectedType != null;
+  Type get reflectedType {
+    if (!hasReflectedType) {
+      throw new UnsupportedError(
+          "Declarations of generics have no reflected type");
+    }
+    return _reflectedType;
+  }
+
   Symbol _simpleName;
   Symbol get simpleName {
     // dynamic, void and the function types have their names set eagerly in the
@@ -417,7 +426,7 @@
         // Object has no superclass.
         return null;
       }
-      _superclass = reflectClass(supertype);
+      _superclass = _Mirrors._reflectType(supertype);
     }
     return _superclass;
   }
@@ -924,7 +933,22 @@
                          this.isGenerativeConstructor,
                          this.isRedirectingConstructor,
                          this.isFactoryConstructor)
-      : super(reflectee, _s(simpleName));
+      : this.isOperator = _operators.contains(simpleName),
+        super(reflectee, _s(simpleName));
+
+  static const _operators = const ["%", "&", "*", "+", "-", "/", "<", "<<",
+      "<=", "==", ">", ">=", ">>", "[]", "[]=", "^", "|", "~", "unary-", "~/"];
+
+  final bool isStatic;
+  final bool isAbstract;
+  final bool isGetter;
+  final bool isSetter;
+  final bool isConstructor;
+  final bool isConstConstructor;
+  final bool isGenerativeConstructor;
+  final bool isRedirectingConstructor;
+  final bool isFactoryConstructor;
+  final bool isOperator;
 
   DeclarationMirror _owner;
   DeclarationMirror get owner {
@@ -969,20 +993,8 @@
     return _parameters;
   }
 
-  final bool isStatic;
-  final bool isAbstract;
-
   bool get isRegularMethod => !isGetter && !isSetter && !isConstructor;
 
-  TypeMirror get isOperator {
-    throw new UnimplementedError(
-        'MethodMirror.isOperator is not implemented');
-  }
-
-  final bool isGetter;
-  final bool isSetter;
-  final bool isConstructor;
-
   Symbol _constructorName = null;
   Symbol get constructorName {
     if (_constructorName == null) {
@@ -1004,11 +1016,6 @@
     return _constructorName;
   }
 
-  final bool isConstConstructor;
-  final bool isGenerativeConstructor;
-  final bool isRedirectingConstructor;
-  final bool isFactoryConstructor;
-
   String toString() => "MethodMirror on '${_n(simpleName)}'";
 
   static dynamic _MethodMirror_owner(reflectee)
diff --git a/runtime/lib/simd128.cc b/runtime/lib/simd128.cc
index 9b79412..1d4d551 100644
--- a/runtime/lib/simd128.cc
+++ b/runtime/lib/simd128.cc
@@ -229,13 +229,36 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(Float32x4_getSignMask, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
+  uint32_t mx = (bit_cast<uint32_t>(self.x()) & 0x80000000) >> 31;
+  uint32_t my = (bit_cast<uint32_t>(self.y()) & 0x80000000) >> 31;
+  uint32_t mz = (bit_cast<uint32_t>(self.z()) & 0x80000000) >> 31;
+  uint32_t mw = (bit_cast<uint32_t>(self.w()) & 0x80000000) >> 31;
+  uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3);
+  return Integer::New(value);
+}
+
+
+DEFINE_NATIVE_ENTRY(Uint32x4_getSignMask, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
+  uint32_t mx = (self.x() & 0x80000000) >> 31;
+  uint32_t my = (self.y() & 0x80000000) >> 31;
+  uint32_t mz = (self.z() & 0x80000000) >> 31;
+  uint32_t mw = (self.w() & 0x80000000) >> 31;
+  uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3);
+  return Integer::New(value);
+}
+
+
 DEFINE_NATIVE_ENTRY(Float32x4_shuffle, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(1));
   int64_t m = mask.AsInt64Value();
   if (m < 0 || m > 255) {
     const String& error = String::Handle(
-      String::NewFormatted("mask (%"Pd64") must be in the range [0..256)", m));
+      String::NewFormatted("mask (%" Pd64 ") must be in the range [0..256)",
+                           m));
     const Array& args = Array::Handle(Array::New(1));
     args.SetAt(0, error);
     Exceptions::ThrowByType(Exceptions::kRange, args);
@@ -471,6 +494,28 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(Uint32x4_add, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, other, arguments->NativeArgAt(1));
+  uint32_t _x = self.x() + other.x();
+  uint32_t _y = self.y() + other.y();
+  uint32_t _z = self.z() + other.z();
+  uint32_t _w = self.w() + other.w();
+  return Uint32x4::New(_x, _y, _z, _w);
+}
+
+
+DEFINE_NATIVE_ENTRY(Uint32x4_sub, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, other, arguments->NativeArgAt(1));
+  uint32_t _x = self.x() - other.x();
+  uint32_t _y = self.y() - other.y();
+  uint32_t _z = self.z() - other.z();
+  uint32_t _w = self.w() - other.w();
+  return Uint32x4::New(_x, _y, _z, _w);
+}
+
+
 DEFINE_NATIVE_ENTRY(Uint32x4_getX, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
   uint32_t value = self.x();
diff --git a/runtime/lib/typed_data.cc b/runtime/lib/typed_data.cc
index 23f0b83..bd7a266 100644
--- a/runtime/lib/typed_data.cc
+++ b/runtime/lib/typed_data.cc
@@ -30,7 +30,7 @@
                           intptr_t element_size_in_bytes) {
   if (!Utils::RangeCheck(offset_in_bytes, num_bytes, length_in_bytes)) {
     const String& error = String::Handle(String::NewFormatted(
-        "index (%"Pd") must be in the range [0..%"Pd")",
+        "index (%" Pd ") must be in the range [0..%" Pd ")",
         (offset_in_bytes / element_size_in_bytes),
         (length_in_bytes / element_size_in_bytes)));
     const Array& args = Array::Handle(Array::New(1));
@@ -44,7 +44,7 @@
 static void LengthCheck(intptr_t len, intptr_t max) {
   if (len < 0 || len > max) {
     const String& error = String::Handle(String::NewFormatted(
-        "Length (%"Pd") of object must be in range [0..%"Pd"]",
+        "Length (%" Pd ") of object must be in range [0..%" Pd "]",
         len, max));
     const Array& args = Array::Handle(Array::New(1));
     args.SetAt(0, error);
@@ -114,7 +114,7 @@
 
   if (length.Value() < 0) {
     const String& error = String::Handle(String::NewFormatted(
-        "length (%"Pd") must be non-negative", length.Value()));
+        "length (%" Pd ") must be non-negative", length.Value()));
     const Array& args = Array::Handle(Array::New(1));
     args.SetAt(0, error);
     Exceptions::ThrowByType(Exceptions::kArgument, args);
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index 4e76c27..e60c145 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -2022,6 +2022,7 @@
   double get y native "Float32x4_getY";
   double get z native "Float32x4_getZ";
   double get w native "Float32x4_getW";
+  int get signMask native "Float32x4_getSignMask";
 
   Float32x4 shuffle(int mask) native "Float32x4_shuffle";
 
@@ -2081,10 +2082,19 @@
     return _xor(other);
   }
   Uint32x4 _xor(Uint32x4 other) native "Uint32x4_xor";
+  Uint32x4 operator +(Uint32x4 other) {
+    return _add(other);
+  }
+  Uint32x4 _add(Uint32x4 other) native "Uint32x4_add";
+  Uint32x4 operator -(Uint32x4 other) {
+    return _sub(other);
+  }
+  Uint32x4 _sub(Uint32x4 other) native "Uint32x4_sub";
   int get x native "Uint32x4_getX";
   int get y native "Uint32x4_getY";
   int get z native "Uint32x4_getZ";
   int get w native "Uint32x4_getW";
+  int get signMask native "Uint32x4_getSignMask";
   Uint32x4 withX(int x) native "Uint32x4_setX";
   Uint32x4 withY(int y) native "Uint32x4_setY";
   Uint32x4 withZ(int z) native "Uint32x4_setZ";
diff --git a/runtime/platform/thread_win.cc b/runtime/platform/thread_win.cc
index 7b3ca56..e8be678 100644
--- a/runtime/platform/thread_win.cc
+++ b/runtime/platform/thread_win.cc
@@ -140,7 +140,7 @@
 void Mutex::Unlock() {
   BOOL result = ReleaseSemaphore(data_.semaphore_, 1, NULL);
   if (result == 0) {
-    FATAL1("Mutex unlock failed", GetLastError());
+    FATAL1("Mutex unlock failed %d", GetLastError());
   }
 }
 
@@ -244,7 +244,7 @@
     // Signal event.
     BOOL result = SetEvent(first->event_);
     if (result == 0) {
-      FATAL1("Monitor::Notify failed to signal event", GetLastError());
+      FATAL1("Monitor::Notify failed to signal event %d", GetLastError());
     }
   }
   LeaveCriticalSection(&waiters_cs_);
@@ -261,7 +261,7 @@
   while (current != NULL) {
     BOOL result = SetEvent(current->event_);
     if (result == 0) {
-      FATAL1("Failed to set event for NotifyAll", GetLastError());
+      FATAL1("Failed to set event for NotifyAll %d", GetLastError());
     }
     current = current->next_;
   }
@@ -315,14 +315,14 @@
     // Wait forever for a Notify or a NotifyAll event.
     result = WaitForSingleObject(wait_data->event_, INFINITE);
     if (result == WAIT_FAILED) {
-      FATAL1("Monitor::Wait failed", GetLastError());
+      FATAL1("Monitor::Wait failed %d", GetLastError());
     }
   } else {
     // Wait for the given period of time for a Notify or a NotifyAll
     // event.
     result = WaitForSingleObject(wait_data->event_, millis);
     if (result == WAIT_FAILED) {
-      FATAL1("Monitor::Wait with timeout failed", GetLastError());
+      FATAL1("Monitor::Wait with timeout failed %d", GetLastError());
     }
     if (result == WAIT_TIMEOUT) {
       // No longer waiting. Remove from the list of waiters.
diff --git a/runtime/vm/allocation.cc b/runtime/vm/allocation.cc
index 0e97ed0..1c88436 100644
--- a/runtime/vm/allocation.cc
+++ b/runtime/vm/allocation.cc
@@ -19,7 +19,7 @@
   ASSERT(isolate != NULL);
   ASSERT(isolate->current_zone() != NULL);
   if (size > static_cast<uword>(kIntptrMax)) {
-    FATAL1("ZoneAllocated object has unexpectedly large size %"Pu"", size);
+    FATAL1("ZoneAllocated object has unexpectedly large size %" Pu "", size);
   }
   return reinterpret_cast<void*>(isolate->current_zone()->AllocUnsafe(size));
 }
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index c04347c..a1dfc13 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -571,6 +571,24 @@
 }
 
 
+void Assembler::addpl(XmmRegister dst, XmmRegister src) {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  EmitUint8(0x66);
+  EmitUint8(0x0F);
+  EmitUint8(0xFE);
+  EmitXmmRegisterOperand(dst, src);
+}
+
+
+void Assembler::subpl(XmmRegister dst, XmmRegister src) {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  EmitUint8(0x66);
+  EmitUint8(0x0F);
+  EmitUint8(0xFA);
+  EmitXmmRegisterOperand(dst, src);
+}
+
+
 void Assembler::addps(XmmRegister dst, XmmRegister src) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(0x0F);
diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h
index 83b1c49..d0972ea 100644
--- a/runtime/vm/assembler_ia32.h
+++ b/runtime/vm/assembler_ia32.h
@@ -411,7 +411,8 @@
   void divsd(XmmRegister dst, XmmRegister src);
   void divsd(XmmRegister dst, const Address& src);
 
-
+  void addpl(XmmRegister dst, XmmRegister src);
+  void subpl(XmmRegister dst, XmmRegister src);
   void addps(XmmRegister dst, XmmRegister src);
   void subps(XmmRegister dst, XmmRegister src);
   void divps(XmmRegister dst, XmmRegister src);
diff --git a/runtime/vm/assembler_ia32_test.cc b/runtime/vm/assembler_ia32_test.cc
index 3a7d4a5..2f3087f 100644
--- a/runtime/vm/assembler_ia32_test.cc
+++ b/runtime/vm/assembler_ia32_test.cc
@@ -874,6 +874,31 @@
 }
 
 
+ASSEMBLER_TEST_GENERATE(PackedIntOperations, assembler) {
+  __ movl(EAX, Immediate(0x2));
+  __ movd(XMM0, EAX);
+  __ shufps(XMM0, XMM0, Immediate(0x0));
+  __ movl(EAX, Immediate(0x1));
+  __ movd(XMM1, EAX);
+  __ shufps(XMM1, XMM1, Immediate(0x0));
+  __ addpl(XMM0, XMM1);  // 0x3
+  __ addpl(XMM0, XMM0);  // 0x6
+  __ subpl(XMM0, XMM1);  // 0x5
+  // Copy the low lane at ESP.
+  __ pushl(EAX);
+  __ movss(Address(ESP, 0), XMM0);
+  __ popl(EAX);
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(PackedIntOperations, test) {
+  typedef uint32_t (*PackedIntOperationsCode)();
+  uint32_t res = reinterpret_cast<PackedIntOperationsCode>(test->entry())();
+  EXPECT_EQ(static_cast<uword>(0x5), res);
+}
+
+
 ASSEMBLER_TEST_GENERATE(PackedFPOperations2, assembler) {
   __ movl(EAX, Immediate(bit_cast<int32_t, float>(4.0f)));
   __ movd(XMM0, EAX);
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 488cd55..38fad31 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -641,6 +641,27 @@
   EmitXmmRegisterOperand(dst & 7, src);
 }
 
+
+void Assembler::addpl(XmmRegister dst, XmmRegister src) {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  EmitREX_RB(dst, src);
+  EmitUint8(0x66);
+  EmitUint8(0x0F);
+  EmitUint8(0xFE);
+  EmitXmmRegisterOperand(dst, src);
+}
+
+
+void Assembler::subpl(XmmRegister dst, XmmRegister src) {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  EmitREX_RB(dst, src);
+  EmitUint8(0x66);
+  EmitUint8(0x0F);
+  EmitUint8(0xFA);
+  EmitXmmRegisterOperand(dst, src);
+}
+
+
 void Assembler::addps(XmmRegister dst, XmmRegister src) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitREX_RB(dst, src);
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index 17324c0..fd0d70b 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -415,6 +415,8 @@
   void mulsd(XmmRegister dst, XmmRegister src);
   void divsd(XmmRegister dst, XmmRegister src);
 
+  void addpl(XmmRegister dst, XmmRegister src);
+  void subpl(XmmRegister dst, XmmRegister src);
   void addps(XmmRegister dst, XmmRegister src);
   void subps(XmmRegister dst, XmmRegister src);
   void divps(XmmRegister dst, XmmRegister src);
diff --git a/runtime/vm/assembler_x64_test.cc b/runtime/vm/assembler_x64_test.cc
index 7fe6a08..a735324 100644
--- a/runtime/vm/assembler_x64_test.cc
+++ b/runtime/vm/assembler_x64_test.cc
@@ -1449,6 +1449,30 @@
 }
 
 
+ASSEMBLER_TEST_GENERATE(PackedIntOperations, assembler) {
+  __ movl(RAX, Immediate(0x2));
+  __ movd(XMM0, RAX);
+  __ shufps(XMM0, XMM0, Immediate(0x0));
+  __ movl(RAX, Immediate(0x1));
+  __ movd(XMM1, RAX);
+  __ shufps(XMM1, XMM1, Immediate(0x0));
+  __ addpl(XMM0, XMM1);  // 0x3
+  __ addpl(XMM0, XMM0);  // 0x6
+  __ subpl(XMM0, XMM1);  // 0x5
+  __ pushq(RAX);
+  __ movss(Address(RSP, 0), XMM0);
+  __ popq(RAX);
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(PackedIntOperations, test) {
+  typedef uint32_t (*PackedIntOperationsCode)();
+  uint32_t res = reinterpret_cast<PackedIntOperationsCode>(test->entry())();
+  EXPECT_EQ(static_cast<uword>(0x5), res);
+}
+
+
 ASSEMBLER_TEST_GENERATE(PackedFPOperations2, assembler) {
   __ movq(RAX, Immediate(bit_cast<int32_t, float>(4.0f)));
   __ movd(XMM0, RAX);
diff --git a/runtime/vm/ast.cc b/runtime/vm/ast.cc
index 063470e..467de8c 100644
--- a/runtime/vm/ast.cc
+++ b/runtime/vm/ast.cc
@@ -83,7 +83,7 @@
 LocalVariable* LetNode::AddInitializer(AstNode* node) {
   initializers_.Add(node);
   char name[64];
-  OS::SNPrint(name, sizeof(name), ":lt%"Pd"_%d", token_pos(), vars_.length());
+  OS::SNPrint(name, sizeof(name), ":lt%" Pd "_%d", token_pos(), vars_.length());
   LocalVariable* temp_var =
       new LocalVariable(token_pos(),
                         String::ZoneHandle(Symbols::New(name)),
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index 57e11b0..a4a773d 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -1556,11 +1556,13 @@
                  const Function& function,
                  const String& native_c_function_name,
                  NativeFunction native_c_function,
+                 LocalScope* scope,
                  bool is_bootstrap_native)
       : AstNode(token_pos),
         function_(function),
         native_c_function_name_(native_c_function_name),
         native_c_function_(native_c_function),
+        scope_(scope),
         is_bootstrap_native_(is_bootstrap_native) {
     ASSERT(function_.IsZoneHandle());
     ASSERT(native_c_function_ != NULL);
@@ -1573,6 +1575,7 @@
     return native_c_function_name_;
   }
   NativeFunction native_c_function() const { return native_c_function_; }
+  LocalScope* scope() const { return scope_; }
   bool is_bootstrap_native() const { return is_bootstrap_native_; }
 
   virtual void VisitChildren(AstNodeVisitor* visitor) const { }
@@ -1583,6 +1586,7 @@
   const Function& function_;  // Native Dart function.
   const String& native_c_function_name_;
   NativeFunction native_c_function_;  // Actual non-Dart implementation.
+  LocalScope* scope_;
   const bool is_bootstrap_native_;  // Is a bootstrap native method.
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(NativeBodyNode);
diff --git a/runtime/vm/ast_printer.cc b/runtime/vm/ast_printer.cc
index 79006b5..21ff734 100644
--- a/runtime/vm/ast_printer.cc
+++ b/runtime/vm/ast_printer.cc
@@ -171,7 +171,7 @@
 void AstPrinter::VisitBinaryOpWithMask32Node(BinaryOpWithMask32Node* node) {
   OS::Print("(%s ", node->Name());
   node->VisitChildren(this);
-  OS::Print(" & 0x%"Px64"", node->mask32());
+  OS::Print(" & 0x%" Px64 "", node->mask32());
   OS::Print(")");
 }
 
@@ -419,7 +419,7 @@
     } else if (var->owner()->function_level() != 0) {
       OS::Print(" lev %d", var->owner()->function_level());
     }
-    OS::Print(" valid %"Pd"-%"Pd")",
+    OS::Print(" valid %" Pd "-%" Pd ")",
               var->token_pos(),
               scope->end_token_pos());
   }
@@ -480,7 +480,7 @@
         OS::Print(" ctx %d", param->owner()->context_level());
       }
     }
-    OS::Print(" valid %"Pd"-%"Pd")",
+    OS::Print(" valid %" Pd "-%" Pd ")",
               param->token_pos(),
               scope->end_token_pos());
     pos++;
diff --git a/runtime/vm/bitmap.cc b/runtime/vm/bitmap.cc
index e2d5fe6e..70619d4 100644
--- a/runtime/vm/bitmap.cc
+++ b/runtime/vm/bitmap.cc
@@ -88,7 +88,7 @@
 void BitmapBuilder::SetBit(intptr_t bit_offset, bool value) {
   if (!InRange(bit_offset)) {
     FATAL1("Fatal error in BitmapBuilder::SetBit :"
-           " invalid bit_offset, %"Pd"\n", bit_offset);
+           " invalid bit_offset, %" Pd "\n", bit_offset);
   }
   int byte_offset = bit_offset >> kBitsPerByteLog2;
   ASSERT(byte_offset < data_size_in_bytes_);
diff --git a/runtime/vm/bitmap.h b/runtime/vm/bitmap.h
index bf8e437..fc2c685 100644
--- a/runtime/vm/bitmap.h
+++ b/runtime/vm/bitmap.h
@@ -54,7 +54,7 @@
   bool InRange(intptr_t offset) const {
     if (offset < 0) {
       FATAL1("Fatal error in BitmapBuilder::InRange :"
-             " invalid bit_offset, %"Pd"\n", offset);
+             " invalid bit_offset, %" Pd "\n", offset);
     }
     return (offset < length_);
   }
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 60c4f54..e4e2127 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -73,7 +73,6 @@
   V(Double_toStringAsFixed, 2)                                                 \
   V(Double_toStringAsExponential, 2)                                           \
   V(Double_toStringAsPrecision, 2)                                             \
-  V(Double_pow, 2)                                                             \
   V(JSSyntaxRegExp_factory, 4)                                                 \
   V(JSSyntaxRegExp_getPattern, 1)                                              \
   V(JSSyntaxRegExp_getIsMultiLine, 1)                                          \
@@ -110,6 +109,7 @@
   V(Math_atan2, 2)                                                             \
   V(Math_exp, 1)                                                               \
   V(Math_log, 1)                                                               \
+  V(Math_doublePow, 2)                                                         \
   V(Random_nextState, 1)                                                       \
   V(Random_setupSeed, 2)                                                       \
   V(DateNatives_currentTimeMillis, 0)                                          \
@@ -202,6 +202,7 @@
   V(Float32x4_getY, 1)                                                         \
   V(Float32x4_getZ, 1)                                                         \
   V(Float32x4_getW, 1)                                                         \
+  V(Float32x4_getSignMask, 1)                                                  \
   V(Float32x4_shuffle, 2)                                                      \
   V(Float32x4_withZWInXY, 2)                                                   \
   V(Float32x4_interleaveXY, 2)                                                 \
@@ -223,6 +224,8 @@
   V(Uint32x4_or, 2)                                                            \
   V(Uint32x4_and, 2)                                                           \
   V(Uint32x4_xor, 2)                                                           \
+  V(Uint32x4_add, 2)                                                           \
+  V(Uint32x4_sub, 2)                                                           \
   V(Uint32x4_getX, 1)                                                          \
   V(Uint32x4_getY, 1)                                                          \
   V(Uint32x4_getZ, 1)                                                          \
@@ -231,6 +234,7 @@
   V(Uint32x4_setY, 2)                                                          \
   V(Uint32x4_setZ, 2)                                                          \
   V(Uint32x4_setW, 2)                                                          \
+  V(Uint32x4_getSignMask, 1)                                                   \
   V(Uint32x4_getFlagX, 1)                                                      \
   V(Uint32x4_getFlagY, 1)                                                      \
   V(Uint32x4_getFlagZ, 1)                                                      \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 5b4a370..84a3e37 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -648,10 +648,14 @@
     ASSERT(type_param.IsFinalized());
     declared_bound = type_param.bound();
     if (!declared_bound.IsObjectType() && !declared_bound.IsDynamicType()) {
+      if (!declared_bound.IsFinalized() && !declared_bound.IsBeingFinalized()) {
+        declared_bound = FinalizeType(cls, declared_bound, kCanonicalize);
+        type_param.set_bound(declared_bound);
+      }
+      ASSERT(declared_bound.IsFinalized() || declared_bound.IsBeingFinalized());
       Error& malformed_error = Error::Handle();
       // Note that the bound may be malformed, in which case the bound check
       // will return an error and the bound check will be postponed to run time.
-      // Note also that the bound may still be unfinalized.
       if (declared_bound.IsInstantiated()) {
         instantiated_bound = declared_bound.raw();
       } else {
@@ -821,15 +825,26 @@
       // argument vector.
       const intptr_t offset = num_type_arguments - num_type_parameters;
       AbstractType& type_arg = AbstractType::Handle(Type::DynamicType());
+      for (intptr_t i = 0; i < offset; i++) {
+        // Temporarily set the type arguments of the super classes to dynamic.
+        full_arguments.SetTypeAt(i, type_arg);
+      }
       for (intptr_t i = 0; i < num_type_parameters; i++) {
         // If no type parameters were provided, a raw type is desired, so we
-        // create a vector of DynamicType.
+        // create a vector of dynamic.
         if (!arguments.IsNull()) {
           type_arg = arguments.TypeAt(i);
         }
         ASSERT(type_arg.IsFinalized());  // Index of type parameter is adjusted.
         full_arguments.SetTypeAt(offset + i, type_arg);
       }
+      // Replace the compile-time argument vector (of length zero or
+      // num_type_parameters) of this type being finalized with the still
+      // unfinalized run-time argument vector (of length num_type_arguments).
+      // This type being finalized may be recursively reached via bounds
+      // checking, in which case type arguments of super classes will be seen
+      // as dynamic.
+      parameterized_type.set_arguments(full_arguments);
       // If the type class is a signature class, the full argument vector
       // must include the argument vector of the super type.
       // If the signature class is a function type alias, it is also the owner
@@ -932,10 +947,11 @@
 }
 
 
-// Check if an instance field or method of same name exists
+// Check if an instance field, getter, or method of same name exists
 // in any super class.
 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls,
-                                                const String& name) {
+                                                const String& name,
+                                                const String& getter_name) {
   Class& super_class = Class::Handle();
   Function& function = Function::Handle();
   Field& field = Field::Handle();
@@ -945,6 +961,10 @@
     if (!function.IsNull() && !function.is_static()) {
       return super_class.raw();
     }
+    function = super_class.LookupFunction(getter_name);
+    if (!function.IsNull() && !function.is_static()) {
+      return super_class.raw();
+    }
     field = super_class.LookupField(name);
     if (!field.IsNull() && !field.is_static()) {
       return super_class.raw();
@@ -1019,17 +1039,30 @@
   // Note that getters and setters are explicitly listed as such in the list of
   // functions of a class, so we do not need to consider fields as implicitly
   // generating getters and setters.
-  // The only compile errors we report are therefore:
-  // - a getter having the same name as a method (but not a getter) in a super
-  //   class or in a subclass.
-  // - a static field, instance field, or static method (but not an instance
-  //   method) having the same name as an instance member in a super class.
+  // Most overriding conflicts are only static warnings, i.e. they are not
+  // reported as compile-time errors by the vm. However, signature conflicts in
+  // overrides can be reported if the flag --error_on_bad_override is specified.
+  // Static warning examples are:
+  // - a static getter 'v' conflicting with an inherited instance setter 'v='.
+  // - a static setter 'v=' conflicting with an inherited instance member 'v'.
+  // - an instance member 'v' conflicting with an accessible static member 'v'
+  //   or 'v=' of a super class (except that an instance method 'v' does not
+  //   conflict with an accessible static setter 'v=' of a super class).
+  // The compile-time errors we report are:
+  // - a static member 'v' conflicting with an inherited instance member 'v'.
+  // - a static setter 'v=' conflicting with an inherited instance setter 'v='.
+  // - an instance method conflicting with an inherited instance field or
+  //   instance getter.
+  // - an instance field or instance getter conflicting with an inherited
+  //   instance method.
 
   // Resolve type of fields and check for conflicts in super classes.
   Array& array = Array::Handle(cls.fields());
   Field& field = Field::Handle();
   AbstractType& type = AbstractType::Handle();
   String& name = String::Handle();
+  String& getter_name = String::Handle();
+  String& setter_name = String::Handle();
   Class& super_class = Class::Handle();
   const intptr_t num_fields = array.Length();
   for (intptr_t i = 0; i < num_fields; i++) {
@@ -1040,7 +1073,8 @@
     field.set_type(type);
     name = field.name();
     if (field.is_static()) {
-      super_class = FindSuperOwnerOfInstanceMember(cls, name);
+      getter_name = Field::GetterSymbol(name);
+      super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name);
       if (!super_class.IsNull()) {
         const String& class_name = String::Handle(cls.Name());
         const String& super_class_name = String::Handle(super_class.Name());
@@ -1054,6 +1088,25 @@
                     name.ToCString(),
                     super_class_name.ToCString());
       }
+      // An implicit setter is not generated for a static field, therefore, we
+      // cannot rely on the code below handling the static setter case to report
+      // a conflict with an instance setter. So we check explicitly here.
+      setter_name = Field::SetterSymbol(name);
+      super_class = FindSuperOwnerOfFunction(cls, setter_name);
+      if (!super_class.IsNull()) {
+        const String& class_name = String::Handle(cls.Name());
+        const String& super_class_name = String::Handle(super_class.Name());
+        const Script& script = Script::Handle(cls.script());
+        ReportError(Error::Handle(),  // No previous error.
+                    script, field.token_pos(),
+                    "static field '%s' of class '%s' conflicts with "
+                    "instance setter '%s=' of super class '%s'",
+                    name.ToCString(),
+                    class_name.ToCString(),
+                    name.ToCString(),
+                    super_class_name.ToCString());
+      }
+
     } else {
       // Instance field. Check whether the field overrides a method
       // (but not getter).
@@ -1112,7 +1165,6 @@
           // Therefore, we undo the optimization performed by the parser, i.e.
           // we create an implicit static final getter and reset the field value
           // to the sentinel value.
-          const String& getter_name = String::Handle(Field::GetterSymbol(name));
           const Function& getter = Function::Handle(
               Function::New(getter_name,
                             RawFunction::kImplicitStaticFinalGetter,
@@ -1146,52 +1198,78 @@
   Function& function = Function::Handle();
   Function& overridden_function = Function::Handle();
   const intptr_t num_functions = array.Length();
-  String& function_name = String::Handle();
   Error& error = Error::Handle();
   for (intptr_t i = 0; i < num_functions; i++) {
     function ^= array.At(i);
     ResolveAndFinalizeSignature(cls, function);
-    function_name = function.name();
+    name = function.name();
+    if (FLAG_error_on_bad_override &&  // Report signature conflicts only.
+        !function.is_static() && !function.IsConstructor()) {
+      // A constructor cannot override anything.
+      for (int i = 0; i < interfaces.Length(); i++) {
+        super_class ^= interfaces.At(i);
+        overridden_function = super_class.LookupDynamicFunction(name);
+        if (!overridden_function.IsNull() &&
+            !function.HasCompatibleParametersWith(overridden_function,
+                                                  &error)) {
+          const String& class_name = String::Handle(cls.Name());
+          const String& super_class_name = String::Handle(super_class.Name());
+          const Script& script = Script::Handle(cls.script());
+          ReportError(error, script, function.token_pos(),
+                      "class '%s' overrides method '%s' of super class '%s' "
+                      "with incompatible parameters",
+                      class_name.ToCString(),
+                      name.ToCString(),
+                      super_class_name.ToCString());
+        }
+      }
+    }
+    if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) {
+      if (function.is_static()) {
+        super_class = FindSuperOwnerOfFunction(cls, name);
+        if (!super_class.IsNull()) {
+          const String& class_name = String::Handle(cls.Name());
+          const String& super_class_name = String::Handle(super_class.Name());
+          const Script& script = Script::Handle(cls.script());
+          ReportError(Error::Handle(),  // No previous error.
+                      script, function.token_pos(),
+                      "static setter '%s=' of class '%s' conflicts with "
+                      "instance setter '%s=' of super class '%s'",
+                      name.ToCString(),
+                      class_name.ToCString(),
+                      name.ToCString(),
+                      super_class_name.ToCString());
+        }
+      }
+      continue;
+    }
+    if (function.IsGetterFunction() || function.IsImplicitGetterFunction()) {
+      getter_name = name.raw();
+      name = Field::NameFromGetter(getter_name);
+    } else {
+      getter_name = Field::GetterSymbol(name);
+    }
     if (function.is_static()) {
-      super_class = FindSuperOwnerOfInstanceMember(cls, function_name);
+      super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name);
       if (!super_class.IsNull()) {
         const String& class_name = String::Handle(cls.Name());
         const String& super_class_name = String::Handle(super_class.Name());
         const Script& script = Script::Handle(cls.script());
         ReportError(Error::Handle(),  // No previous error.
                     script, function.token_pos(),
-                    "static function '%s' of class '%s' conflicts with "
+                    "static %s '%s' of class '%s' conflicts with "
                     "instance member '%s' of super class '%s'",
-                    function_name.ToCString(),
+                    (function.IsGetterFunction() ||
+                     function.IsImplicitGetterFunction()) ? "getter" : "method",
+                    name.ToCString(),
                     class_name.ToCString(),
-                    function_name.ToCString(),
+                    name.ToCString(),
                     super_class_name.ToCString());
       }
       // The function may be a still unresolved redirecting factory. Do not yet
       // try to resolve it in order to avoid cycles in class finalization.
-    } else if (FLAG_error_on_bad_override && !function.IsConstructor()) {
-      // A constructor cannot override anything.
-      for (int i = 0; i < interfaces.Length(); i++) {
-        super_class ^= interfaces.At(i);
-        overridden_function = super_class.LookupDynamicFunction(function_name);
-        if (!overridden_function.IsNull() &&
-            !function.HasCompatibleParametersWith(overridden_function,
-                                                  &error)) {
-          // Function types are purposely not checked for subtyping.
-          const String& class_name = String::Handle(cls.Name());
-          const String& super_class_name = String::Handle(super_class.Name());
-          const Script& script = Script::Handle(cls.script());
-          ReportError(error, script, function.token_pos(),
-                      "class '%s' overrides function '%s' of super class '%s' "
-                      "with incompatible parameters",
-                      class_name.ToCString(),
-                      function_name.ToCString(),
-                      super_class_name.ToCString());
-        }
-      }
-    }
-    if (function.IsGetterFunction()) {
-      name = Field::NameFromGetter(function_name);
+    } else if (function.IsGetterFunction() ||
+               function.IsImplicitGetterFunction()) {
       super_class = FindSuperOwnerOfFunction(cls, name);
       if (!super_class.IsNull()) {
         const String& class_name = String::Handle(cls.Name());
@@ -1200,28 +1278,28 @@
         ReportError(Error::Handle(),  // No previous error.
                     script, function.token_pos(),
                     "getter '%s' of class '%s' conflicts with "
-                    "function '%s' of super class '%s'",
+                    "method '%s' of super class '%s'",
                     name.ToCString(),
                     class_name.ToCString(),
                     name.ToCString(),
                     super_class_name.ToCString());
       }
-    } else if (!function.IsSetterFunction()) {
+    } else if (!function.IsSetterFunction() &&
+               !function.IsImplicitSetterFunction()) {
       // A function cannot conflict with a setter, since they cannot
       // have the same name. Thus, we do not need to check setters.
-      name = Field::GetterName(function_name);
-      super_class = FindSuperOwnerOfFunction(cls, name);
+      super_class = FindSuperOwnerOfFunction(cls, getter_name);
       if (!super_class.IsNull()) {
         const String& class_name = String::Handle(cls.Name());
         const String& super_class_name = String::Handle(super_class.Name());
         const Script& script = Script::Handle(cls.script());
         ReportError(Error::Handle(),  // No previous error.
                     script, function.token_pos(),
-                    "function '%s' of class '%s' conflicts with "
+                    "method '%s' of class '%s' conflicts with "
                     "getter '%s' of super class '%s'",
-                    function_name.ToCString(),
+                    name.ToCString(),
                     class_name.ToCString(),
-                    function_name.ToCString(),
+                    name.ToCString(),
                     super_class_name.ToCString());
       }
     }
@@ -1352,7 +1430,7 @@
   const Class& mixin_cls = Class::Handle(mixin_type.type_class());
 
   if (FLAG_trace_class_finalization) {
-    OS::Print("Applying mixin type '%s' to '%s' at pos %"Pd"\n",
+    OS::Print("Applying mixin type '%s' to '%s' at pos %" Pd "\n",
               String::Handle(mixin_type.Name()).ToCString(),
               cls.ToCString(),
               cls.token_pos());
@@ -1446,7 +1524,7 @@
   mixin_cls.EnsureIsFinalized(isolate);
 
   if (FLAG_trace_class_finalization) {
-    OS::Print("Applying mixin '%s' to '%s' at pos %"Pd"\n",
+    OS::Print("Applying mixin '%s' to '%s' at pos %" Pd "\n",
               String::Handle(mixin_cls.Name()).ToCString(),
               cls.ToCString(),
               cls.token_pos());
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index 2eac4c9..2cf1ac1 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -90,7 +90,7 @@
     cls = At(i);
     if (cls.raw() != reinterpret_cast<RawClass*>(0)) {
       name = cls.Name();
-      OS::Print("%"Pd": %s\n", i, name.ToCString());
+      OS::Print("%" Pd ": %s\n", i, name.ToCString());
     }
   }
 }
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 2f72473..a5a597f 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -352,7 +352,7 @@
   const Type& instance_type = Type::Handle(instance.GetType());
   ASSERT(instance_type.IsInstantiated());
   if (type.IsInstantiated()) {
-    OS::PrintErr("%s: '%s' %"Pd" %s '%s' %"Pd" (pc: %#"Px").\n",
+    OS::PrintErr("%s: '%s' %" Pd " %s '%s' %" Pd " (pc: %#" Px ").\n",
                  message,
                  String::Handle(instance_type.Name()).ToCString(),
                  Class::Handle(instance_type.type_class()).id(),
@@ -365,7 +365,7 @@
     Error& malformed_error = Error::Handle();
     const AbstractType& instantiated_type = AbstractType::Handle(
         type.InstantiateFrom(instantiator_type_arguments, &malformed_error));
-    OS::PrintErr("%s: '%s' %s '%s' instantiated from '%s' (pc: %#"Px").\n",
+    OS::PrintErr("%s: '%s' %s '%s' instantiated from '%s' (pc: %#" Px ").\n",
                  message,
                  String::Handle(instance_type.Name()).ToCString(),
                  (result.raw() == Bool::True().raw()) ? "is" : "is !",
@@ -488,7 +488,7 @@
         (last_instantiator_type_arguments.raw() ==
          instantiator_type_arguments.raw())) {
       if (FLAG_trace_type_checks) {
-        OS::PrintErr("%"Pd" ", i);
+        OS::PrintErr("%" Pd " ", i);
         if (type_arguments_replaced) {
           PrintTypeCheck("Duplicate cache entry (canonical.)", instance, type,
               instantiator_type_arguments, result);
@@ -517,10 +517,10 @@
                                        &malformed_error);
       ASSERT(malformed_error.IsNull());  // Malformed types are not optimized.
     }
-    OS::PrintErr("  Updated test cache %p ix: %"Pd" with "
-        "(cid: %"Pd", type-args: %p, instantiator: %p, result: %s)\n"
-        "    instance  [class: (%p '%s' cid: %"Pd"),    type-args: %p %s]\n"
-        "    test-type [class: (%p '%s' cid: %"Pd"), in-type-args: %p %s]\n",
+    OS::PrintErr("  Updated test cache %p ix: %" Pd " with "
+        "(cid: %" Pd ", type-args: %p, instantiator: %p, result: %s)\n"
+        "    instance  [class: (%p '%s' cid: %" Pd "),    type-args: %p %s]\n"
+        "    test-type [class: (%p '%s' cid: %" Pd "), in-type-args: %p %s]\n",
         new_cache.raw(),
         len,
 
@@ -739,7 +739,7 @@
                                  target_code.EntryPoint());
   caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code);
   if (FLAG_trace_patching) {
-    OS::PrintErr("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n",
+    OS::PrintErr("PatchStaticCall: patching from %#" Px " to '%s' %#" Px "\n",
         caller_frame->pc(),
         target_function.ToFullyQualifiedCString(),
         target_code.EntryPoint());
@@ -899,8 +899,8 @@
       }
     }
     if (FLAG_trace_ic) {
-      OS::PrintErr("InlineCacheMissHandler %d call at %#"Px"' "
-                   "adding <%s> id:%"Pd" -> <%s>\n",
+      OS::PrintErr("InlineCacheMissHandler %d call at %#" Px "' "
+                   "adding <%s> id:%" Pd " -> <%s>\n",
           args.length(),
           caller_frame->pc(),
           Class::Handle(receiver.clazz()).ToCString(),
@@ -1007,8 +1007,9 @@
     DartFrameIterator iterator;
     StackFrame* caller_frame = iterator.NextFrame();
     ASSERT(caller_frame != NULL);
-    OS::PrintErr("StaticCallMissHandler at %#"Px" target %s (%"Pd", %"Pd")\n",
-        caller_frame->pc(), target.ToCString(), cids[0], cids[1]);
+    OS::PrintErr("StaticCallMissHandler at %#" Px
+                 " target %s (%" Pd ", %" Pd ")\n",
+                 caller_frame->pc(), target.ToCString(), cids[0], cids[1]);
   }
   arguments.SetReturn(target);
 }
@@ -1178,7 +1179,7 @@
   ASSERT(!target_function.IsNull());
   ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
   if (FLAG_trace_ic) {
-    OS::PrintErr("InvokeField IC miss: adding <%s> id:%"Pd" -> <%s>\n",
+    OS::PrintErr("InvokeField IC miss: adding <%s> id:%" Pd " -> <%s>\n",
         Class::Handle(receiver.clazz()).ToCString(),
         receiver.GetClassId(),
         target_function.ToCString());
@@ -1255,7 +1256,7 @@
       ic_data.AddCheck(class_ids, target_function);
     }
     if (FLAG_trace_ic) {
-      OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%"Pd" -> <%s>\n",
+      OS::PrintErr("NoSuchMethod IC miss: adding <%s> id:%" Pd " -> <%s>\n",
           Class::Handle(receiver.clazz()).ToCString(),
           receiver_cid,
           target_function.ToCString());
@@ -1368,7 +1369,7 @@
     intptr_t osr_id =
         Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc());
     if (FLAG_trace_osr) {
-      OS::Print("Attempting OSR for %s at id=%"Pd", count=%"Pd"\n",
+      OS::Print("Attempting OSR for %s at id=%" Pd ", count=%" Pd "\n",
                 function.ToFullyQualifiedCString(),
                 osr_id,
                 function.usage_counter());
@@ -1403,7 +1404,8 @@
   DartFrameIterator iterator;
   StackFrame* frame = iterator.NextFrame();
   ASSERT(frame != NULL);
-  OS::PrintErr("IC call @%#"Px": ICData: %p cnt:%"Pd" nchecks: %"Pd" %s %s\n",
+  OS::PrintErr("IC call @%#" Px ": ICData: %p cnt:%" Pd " nchecks: %" Pd
+      " %s %s\n",
       frame->pc(),
       ic_data.raw(),
       function.usage_counter(),
@@ -1464,7 +1466,7 @@
                                  target_code.EntryPoint());
   caller_code.SetStaticCallTargetCodeAt(frame->pc(), target_code);
   if (FLAG_trace_patching) {
-    OS::PrintErr("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n",
+    OS::PrintErr("FixCallersTarget: patching from %#" Px " to '%s' %#" Px "\n",
         frame->pc(),
         Function::Handle(target_code.function()).ToFullyQualifiedCString(),
         target_code.EntryPoint());
@@ -1639,7 +1641,7 @@
   if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
     Function& function = Function::Handle(optimized_code.function());
     OS::PrintErr(
-        "Deoptimizing (reason %"Pd" '%s') at pc %#"Px" '%s' (count %d)\n",
+        "Deoptimizing (reason %" Pd " '%s') at pc %#" Px " '%s' (count %d)\n",
         deopt_reason,
         DeoptReasonToText(deopt_reason),
         caller_frame->pc(),
@@ -1723,7 +1725,7 @@
 
   if (FLAG_trace_deoptimization_verbose) {
     for (intptr_t i = 0; i < frame_size; i++) {
-      OS::PrintErr("*%"Pd". [%"Px"] %#014"Px" [%s]\n",
+      OS::PrintErr("*%" Pd ". [%" Px "] %#014" Px " [%s]\n",
                    i,
                    reinterpret_cast<uword>(&start[i]),
                    start[i],
@@ -1814,8 +1816,8 @@
     script.GetTokenLocation(token_pos, &line, &column);
     String& line_string = String::Handle(script.GetLine(line));
     OS::PrintErr("  Function: %s\n", top_function.ToFullyQualifiedCString());
-    OS::PrintErr("  Line %"Pd": '%s'\n", line, line_string.ToCString());
-    OS::PrintErr("  Deopt args: %"Pd"\n", deopt_arguments);
+    OS::PrintErr("  Line %" Pd ": '%s'\n", line, line_string.ToCString());
+    OS::PrintErr("  Deopt args: %" Pd "\n", deopt_arguments);
   }
 }
 
@@ -1851,6 +1853,31 @@
 }
 
 
+static intptr_t GetListLength(const Object& value) {
+  const intptr_t cid = value.GetClassId();
+  ASSERT(RawObject::IsBuiltinListClassId(cid));
+  // Extract list length.
+  if (value.IsTypedData()) {
+    const TypedData& list = TypedData::Cast(value);
+    return list.Length();
+  } else if (value.IsArray()) {
+    const Array& list = Array::Cast(value);
+    return list.Length();
+  } else if (value.IsGrowableObjectArray()) {
+    // List length is variable.
+    return Field::kNoFixedLength;
+  } else if (value.IsExternalTypedData()) {
+    // TODO(johnmccutchan): Enable for external typed data.
+    return Field::kNoFixedLength;
+  } else if (RawObject::IsTypedDataViewClassId(cid)) {
+    // TODO(johnmccutchan): Enable for typed data views.
+    return Field::kNoFixedLength;
+  }
+  UNIMPLEMENTED();
+  return Field::kNoFixedLength;
+}
+
+
 // Update global type feedback recorded for a field recording the assignment
 // of the given value.
 //   Arg0: Field object;
@@ -1859,8 +1886,14 @@
   ASSERT(arguments.ArgCount() == kUpdateFieldCidRuntimeEntry.argument_count());
   const Field& field = Field::CheckedHandle(arguments.ArgAt(0));
   const Object& value = Object::Handle(arguments.ArgAt(1));
-
-  field.UpdateCid(value.GetClassId());
+  const intptr_t cid = value.GetClassId();
+  field.UpdateCid(cid);
+  intptr_t list_length = Field::kNoFixedLength;
+  if ((field.guarded_cid() != kDynamicCid) &&
+      field.is_final() && RawObject::IsBuiltinListClassId(cid)) {
+    list_length = GetListLength(value);
+  }
+  field.UpdateLength(list_length);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index 6dceb4c..cac140a 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -224,6 +224,7 @@
                                         function,
                                         native_name,
                                         native_function,
+                                        local_scope,
                                         false /* not bootstrap native */)));
 }
 
@@ -406,6 +407,7 @@
                                         function,
                                         native_name,
                                         native_function,
+                                        local_scope,
                                         false /* Not bootstrap native */)));
 }
 
@@ -495,6 +497,7 @@
                                         function,
                                         native_name,
                                         native_function,
+                                        local_scope,
                                         false /* Not bootstrap native */)));
 }
 
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 73c6d63..9864e56 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -229,12 +229,12 @@
   // Disable optimized code.
   ASSERT(function.HasOptimizedCode());
   if (FLAG_trace_compiler) {
-    OS::Print("--> patching entry %#"Px"\n",
+    OS::Print("--> patching entry %#" Px "\n",
               Code::Handle(function.CurrentCode()).EntryPoint());
   }
   function.SwitchToUnoptimizedCode();
   if (FLAG_trace_compiler) {
-    OS::Print("--> restoring entry at %#"Px"\n",
+    OS::Print("--> restoring entry at %#" Px "\n",
               Code::Handle(function.unoptimized_code()).EntryPoint());
   }
 }
@@ -342,6 +342,17 @@
         if (FLAG_use_inlining) {
           TimerScope timer(FLAG_compiler_stats,
                            &CompilerStats::graphinliner_timer);
+          // Propagate types to create more inlining opportunities.
+          if (FLAG_propagate_types) {
+            FlowGraphTypePropagator propagator(flow_graph);
+            propagator.Propagate();
+            DEBUG_ASSERT(flow_graph->VerifyUseLists());
+          }
+
+          // Use propagated class-ids to create more inlining opportunities.
+          optimizer.ApplyClassIds();
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+
           FlowGraphInliner inliner(flow_graph, &guarded_fields);
           inliner.Inline();
           // Use lists are maintained and validated by the inliner.
@@ -528,7 +539,7 @@
           if (osr_id == Isolate::kNoDeoptId) {
             CodePatcher::PatchEntry(Code::Handle(function.CurrentCode()));
             if (FLAG_trace_compiler) {
-              OS::Print("--> patching entry %#"Px"\n",
+              OS::Print("--> patching entry %#" Px "\n",
                   Code::Handle(function.unoptimized_code()).EntryPoint());
             }
           }
@@ -595,7 +606,7 @@
     const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint();
     Object& obj = Object::Handle();
     obj = *reinterpret_cast<RawObject**>(addr);
-    OS::Print(" %d : %#"Px" '%s'\n",
+    OS::Print(" %d : %#" Px " '%s'\n",
               code.GetPointerOffsetAt(i), addr, obj.ToCString());
   }
   OS::Print("}\n");
@@ -616,7 +627,7 @@
     Smi& reason = Smi::Handle();
     for (intptr_t i = 0; i < deopt_table_length; ++i) {
       DeoptTable::GetEntry(deopt_table, i, &offset, &info, &reason);
-      OS::Print("%4"Pd": 0x%"Px"  %s  (%s)\n",
+      OS::Print("%4" Pd ": 0x%" Px "  %s  (%s)\n",
                 i,
                 start + offset.Value(),
                 info.ToCString(),
@@ -629,7 +640,7 @@
   if (object_table.Length() > 0) {
     OS::Print("Object Table: {\n");
     for (intptr_t i = 0; i < object_table.Length(); i++) {
-      OS::Print("  %"Pd": %s\n", i,
+      OS::Print("  %" Pd ": %s\n", i,
           Object::Handle(object_table.At(i)).ToCString());
     }
     OS::Print("}\n");
@@ -658,22 +669,22 @@
     RawLocalVarDescriptors::VarInfo var_info;
     var_descriptors.GetInfo(i, &var_info);
     if (var_info.kind == RawLocalVarDescriptors::kSavedEntryContext) {
-      OS::Print("  saved caller's CTX reg offset %"Pd"\n", var_info.index);
+      OS::Print("  saved caller's CTX reg offset %" Pd "\n", var_info.index);
     } else if (var_info.kind == RawLocalVarDescriptors::kSavedCurrentContext) {
-      OS::Print("  saved current CTX reg offset %"Pd"\n", var_info.index);
+      OS::Print("  saved current CTX reg offset %" Pd "\n", var_info.index);
     } else {
       if (var_info.kind == RawLocalVarDescriptors::kContextLevel) {
-        OS::Print("  context level %"Pd" scope %d",
+        OS::Print("  context level %" Pd " scope %d",
                   var_info.index, var_info.scope_id);
       } else if (var_info.kind == RawLocalVarDescriptors::kStackVar) {
-        OS::Print("  stack var '%s' offset %"Pd"",
+        OS::Print("  stack var '%s' offset %" Pd "",
                   var_name.ToCString(), var_info.index);
       } else {
         ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar);
-        OS::Print("  context var '%s' level %d offset %"Pd"",
+        OS::Print("  context var '%s' level %d offset %" Pd "",
                   var_name.ToCString(), var_info.scope_id, var_info.index);
       }
-      OS::Print(" (valid %"Pd"-%"Pd")\n",
+      OS::Print(" (valid %" Pd "-%" Pd ")\n",
                 var_info.begin_pos, var_info.end_pos);
     }
   }
@@ -695,7 +706,7 @@
       offset ^= table.At(i + Code::kSCallTableOffsetEntry);
       function ^= table.At(i + Code::kSCallTableFunctionEntry);
       code ^= table.At(i + Code::kSCallTableCodeEntry);
-      OS::Print("  0x%"Px": %s, %p\n",
+      OS::Print("  0x%" Px ": %s, %p\n",
           start + offset.Value(),
           function.ToFullyQualifiedCString(),
           code.raw());
@@ -726,7 +737,7 @@
     ParsedFunction* parsed_function = new ParsedFunction(
         Function::ZoneHandle(function.raw()));
     if (FLAG_trace_compiler) {
-      OS::Print("Compiling %s%sfunction: '%s' @ token %"Pd", size %"Pd"\n",
+      OS::Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n",
                 (osr_id == Isolate::kNoDeoptId ? "" : "osr "),
                 (optimized ? "optimized " : ""),
                 function.ToFullyQualifiedCString(),
@@ -758,7 +769,7 @@
     per_compile_timer.Stop();
 
     if (FLAG_trace_compiler) {
-      OS::Print("--> '%s' entry: %#"Px" size: %"Pd" time: %"Pd64" us\n",
+      OS::Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n",
                 function.ToFullyQualifiedCString(),
                 Code::Handle(function.CurrentCode()).EntryPoint(),
                 Code::Handle(function.CurrentCode()).Size(),
diff --git a/runtime/vm/compiler_stats.cc b/runtime/vm/compiler_stats.cc
index e9081f99..2a0671f 100644
--- a/runtime/vm/compiler_stats.cc
+++ b/runtime/vm/compiler_stats.cc
@@ -66,69 +66,69 @@
     return;
   }
   OS::Print("==== Compiler Stats ====\n");
-  OS::Print("Number of tokens:   %"Pd"\n", num_tokens_total);
-  OS::Print("  Literal tokens:   %"Pd"\n", num_literal_tokens_total);
-  OS::Print("  Ident tokens:     %"Pd"\n", num_ident_tokens_total);
-  OS::Print("Tokens consumed:    %"Pd" (%.2f times number of tokens)\n",
+  OS::Print("Number of tokens:   %" Pd "\n", num_tokens_total);
+  OS::Print("  Literal tokens:   %" Pd "\n", num_literal_tokens_total);
+  OS::Print("  Ident tokens:     %" Pd "\n", num_ident_tokens_total);
+  OS::Print("Tokens consumed:    %" Pd " (%.2f times number of tokens)\n",
             num_tokens_consumed,
             (1.0 * num_tokens_consumed) / num_tokens_total);
-  OS::Print("Tokens checked:     %"Pd"  (%.2f times tokens consumed)\n",
+  OS::Print("Tokens checked:     %" Pd "  (%.2f times tokens consumed)\n",
             num_token_checks, (1.0 * num_token_checks) / num_tokens_consumed);
-  OS::Print("Token rewind:       %"Pd" (%"Pd"%% of tokens checked)\n",
+  OS::Print("Token rewind:       %" Pd " (%" Pd "%% of tokens checked)\n",
             num_tokens_rewind, (100 * num_tokens_rewind) / num_token_checks);
-  OS::Print("Token lookahead:    %"Pd" (%"Pd"%% of tokens checked)\n",
+  OS::Print("Token lookahead:    %" Pd " (%" Pd "%% of tokens checked)\n",
             num_tokens_lookahead,
             (100 * num_tokens_lookahead) / num_token_checks);
-  OS::Print("Source length:      %"Pd" characters\n", src_length);
+  OS::Print("Source length:      %" Pd " characters\n", src_length);
   int64_t scan_usecs = scanner_timer.TotalElapsedTime();
-  OS::Print("Scanner time:       %"Pd64" msecs\n",
+  OS::Print("Scanner time:       %" Pd64 " msecs\n",
             scan_usecs / 1000);
   int64_t parse_usecs = parser_timer.TotalElapsedTime();
-  OS::Print("Parser time:        %"Pd64" msecs\n",
+  OS::Print("Parser time:        %" Pd64 " msecs\n",
             parse_usecs / 1000);
   int64_t codegen_usecs = codegen_timer.TotalElapsedTime();
-  OS::Print("Code gen. time:     %"Pd64" msecs\n",
+  OS::Print("Code gen. time:     %" Pd64 " msecs\n",
             codegen_usecs / 1000);
   int64_t graphbuilder_usecs = graphbuilder_timer.TotalElapsedTime();
-  OS::Print("  Graph builder:    %"Pd64" msecs\n", graphbuilder_usecs / 1000);
+  OS::Print("  Graph builder:    %" Pd64 " msecs\n", graphbuilder_usecs / 1000);
   int64_t ssa_usecs = ssa_timer.TotalElapsedTime();
-  OS::Print("  Graph SSA:        %"Pd64" msecs\n", ssa_usecs / 1000);
+  OS::Print("  Graph SSA:        %" Pd64 " msecs\n", ssa_usecs / 1000);
 
   int64_t graphinliner_usecs = graphinliner_timer.TotalElapsedTime();
-  OS::Print("  Graph inliner:    %"Pd64" msecs\n", graphinliner_usecs / 1000);
+  OS::Print("  Graph inliner:    %" Pd64 " msecs\n", graphinliner_usecs / 1000);
   int64_t graphinliner_parse_usecs =
       graphinliner_parse_timer.TotalElapsedTime();
-  OS::Print("    Parsing:        %"Pd64" msecs\n",
+  OS::Print("    Parsing:        %" Pd64 " msecs\n",
             graphinliner_parse_usecs / 1000);
   int64_t graphinliner_build_usecs =
       graphinliner_build_timer.TotalElapsedTime();
-  OS::Print("    Building:       %"Pd64" msecs\n",
+  OS::Print("    Building:       %" Pd64 " msecs\n",
             graphinliner_build_usecs / 1000);
   int64_t graphinliner_ssa_usecs = graphinliner_ssa_timer.TotalElapsedTime();
-  OS::Print("    SSA:            %"Pd64" msecs\n",
+  OS::Print("    SSA:            %" Pd64 " msecs\n",
             graphinliner_ssa_usecs / 1000);
   int64_t graphinliner_opt_usecs = graphinliner_opt_timer.TotalElapsedTime();
-  OS::Print("    Optimization:   %"Pd64" msecs\n",
+  OS::Print("    Optimization:   %" Pd64 " msecs\n",
             graphinliner_opt_usecs / 1000);
   int64_t graphinliner_subst_usecs =
       graphinliner_subst_timer.TotalElapsedTime();
-  OS::Print("    Substitution:   %"Pd64" msecs\n",
+  OS::Print("    Substitution:   %" Pd64 " msecs\n",
             graphinliner_subst_usecs / 1000);
 
   int64_t graphoptimizer_usecs = graphoptimizer_timer.TotalElapsedTime();
-  OS::Print("  Graph optimizer:  %"Pd64" msecs\n",
+  OS::Print("  Graph optimizer:  %" Pd64 " msecs\n",
             (graphoptimizer_usecs - graphinliner_usecs) / 1000);
   int64_t graphcompiler_usecs = graphcompiler_timer.TotalElapsedTime();
-  OS::Print("  Graph compiler:   %"Pd64" msecs\n",
+  OS::Print("  Graph compiler:   %" Pd64 " msecs\n",
             graphcompiler_usecs / 1000);
   int64_t codefinalizer_usecs = codefinalizer_timer.TotalElapsedTime();
-  OS::Print("  Code finalizer:   %"Pd64" msecs\n",
+  OS::Print("  Code finalizer:   %" Pd64 " msecs\n",
             codefinalizer_usecs / 1000);
-  OS::Print("Compilation speed:  %"Pd64" tokens per msec\n",
+  OS::Print("Compilation speed:  %" Pd64 " tokens per msec\n",
             1000 * num_tokens_total / (parse_usecs + codegen_usecs));
-  OS::Print("Code size:          %"Pd" KB\n",
+  OS::Print("Code size:          %" Pd " KB\n",
             code_allocated / 1024);
-  OS::Print("Code density:       %"Pd" tokens per KB\n",
+  OS::Print("Code density:       %" Pd " tokens per KB\n",
             num_tokens_total * 1024 / code_allocated);
 }
 
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index f2abb8a..e962155 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -5,6 +5,7 @@
 #include "platform/assert.h"
 #include "vm/class_finalizer.h"
 #include "vm/compiler.h"
+#include "vm/dart_api_impl.h"
 #include "vm/object.h"
 #include "vm/symbols.h"
 #include "vm/unit_test.h"
@@ -63,4 +64,34 @@
   EXPECT(function_moo.HasCode());
 }
 
+
+TEST_CASE(EvalExpression) {
+  const char* kScriptChars =
+      "int ten = 2 * 5;              \n"
+      "get dot => '.';               \n"
+      "class A {                     \n"
+      "  var apa = 'Herr Nilsson';   \n"
+      "  calc(x) => '${x*ten}';      \n"
+      "}                             \n"
+      "makeObj() => new A();         \n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  Dart_Handle obj_handle =
+      Dart_Invoke(lib, Dart_NewStringFromCString("makeObj"), 0,  NULL);
+  EXPECT(!Dart_IsNull(obj_handle));
+  EXPECT(!Dart_IsError(obj_handle));
+  const Object& obj = Object::Handle(Api::UnwrapHandle(obj_handle));
+  EXPECT(!obj.IsNull());
+  EXPECT(obj.IsInstance());
+
+  String& expr_text = String::Handle();
+  expr_text = String::New("apa + ' ${calc(10)}' + dot");
+  Object& val = Object::Handle();
+  val = Instance::Cast(obj).Evaluate(expr_text);
+  EXPECT(!val.IsNull());
+  EXPECT(!val.IsError());
+  EXPECT(val.IsString());
+  EXPECT_STREQ("Herr Nilsson 100.", val.ToCString());
+}
+
 }  // namespace dart
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index fdc7e50..4c082e8 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1836,7 +1836,7 @@
   if ((length < str_size) || (length > String::kMaxElements)) {
     return Api::NewError("Dart_MakeExternalString "
                          "expects argument length to be in the range"
-                         "[%"Pd"..%"Pd"].",
+                         "[%" Pd "..%" Pd "].",
                          str_size, String::kMaxElements);
   }
   if (str_obj.InVMHeap()) {
@@ -3719,6 +3719,108 @@
 }
 
 
+DART_EXPORT Dart_Handle Dart_GetNativeIntegerArgument(Dart_NativeArguments args,
+                                                      int index,
+                                                      int64_t* value) {
+  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
+  if ((index < 0) || (index >= arguments->NativeArgCount())) {
+    return Api::NewError(
+        "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
+        CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
+  }
+  Isolate* isolate = arguments->isolate();
+  ReusableObjectHandleScope reused_obj_handle(isolate);
+  Object& obj = reused_obj_handle.Handle();
+  obj = arguments->NativeArgAt(index);
+  intptr_t cid = obj.GetClassId();
+  if (cid == kSmiCid) {
+    *value = Smi::Cast(obj).Value();
+    return Api::Success();
+  }
+  if (cid == kMintCid) {
+    *value = Mint::Cast(obj).value();
+    return Api::Success();
+  }
+  if (cid == kBigintCid) {
+    const Bigint& bigint = Bigint::Cast(obj);
+    if (BigintOperations::FitsIntoInt64(bigint)) {
+      *value = BigintOperations::ToInt64(bigint);
+      return Api::Success();
+    }
+    return Api::NewError(
+        "%s: argument %d is a big integer that does not fit in 'value'.",
+        CURRENT_FUNC, index);
+  }
+  return Api::NewError(
+      "%s: argument %d is not an Integer argument.",
+      CURRENT_FUNC, index);
+}
+
+
+DART_EXPORT Dart_Handle Dart_GetNativeBooleanArgument(Dart_NativeArguments args,
+                                                      int index,
+                                                      bool* value) {
+  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
+  if ((index < 0) || (index >= arguments->NativeArgCount())) {
+    return Api::NewError(
+        "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
+        CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
+  }
+  Isolate* isolate = arguments->isolate();
+  ReusableObjectHandleScope reused_obj_handle(isolate);
+  Object& obj = reused_obj_handle.Handle();
+  obj = arguments->NativeArgAt(index);
+  intptr_t cid = obj.GetClassId();
+  if (cid == kBoolCid) {
+    *value = Bool::Cast(obj).value();
+    return Api::Success();
+  }
+  if (obj.IsNull()) {
+    *value = false;
+    return Api::Success();
+  }
+  return Api::NewError(
+      "%s: argument %d is not a Boolean argument.",
+      CURRENT_FUNC, index);
+}
+
+
+DART_EXPORT Dart_Handle Dart_GetNativeDoubleArgument(Dart_NativeArguments args,
+                                                     int index,
+                                                     double* value) {
+  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
+  if ((index < 0) || (index >= arguments->NativeArgCount())) {
+    return Api::NewError(
+        "%s: argument 'index' out of range. Expected 0..%d but saw %d.",
+        CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
+  }
+  Isolate* isolate = arguments->isolate();
+  ReusableObjectHandleScope reused_obj_handle(isolate);
+  Object& obj = reused_obj_handle.Handle();
+  obj = arguments->NativeArgAt(index);
+  intptr_t cid = obj.GetClassId();
+  if (cid == kDoubleCid) {
+    *value = Double::Cast(obj).value();
+    return Api::Success();
+  }
+  if (cid == kSmiCid) {
+    *value = Smi::Cast(obj).AsDoubleValue();
+    return Api::Success();
+  }
+  if (cid == kMintCid) {
+    *value = Mint::Cast(obj).AsDoubleValue();
+    return Api::Success();
+  }
+  if (cid == kBigintCid) {
+    *value = Bigint::Cast(obj).AsDoubleValue();
+    return Api::Success();
+  }
+  return Api::NewError(
+      "%s: argument %d is not a Double argument.",
+      CURRENT_FUNC, index);
+}
+
+
 DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args,
                                      Dart_Handle retval) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
@@ -3754,7 +3856,7 @@
 
 
 DART_EXPORT void Dart_SetIntegerReturnValue(Dart_NativeArguments args,
-                                            intptr_t retval) {
+                                            int64_t retval) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   Isolate* isolate = arguments->isolate();
   CHECK_ISOLATE(isolate);
@@ -3879,7 +3981,7 @@
                          " snapshot.", CURRENT_FUNC);
   }
   if (snapshot->length() != buffer_len) {
-    return Api::NewError("%s: 'buffer_len' of %"Pd" is not equal to %d which"
+    return Api::NewError("%s: 'buffer_len' of %" Pd " is not equal to %d which"
                          " is the expected length in the snapshot.",
                          CURRENT_FUNC, buffer_len, snapshot->length());
   }
@@ -3981,7 +4083,7 @@
   if (cls.NumTypeArguments() == 0) {
     if (number_of_type_arguments != 0) {
       return Api::NewError("Invalid number of type arguments specified, "
-                           "got %"Pd" expected 0", number_of_type_arguments);
+                           "got %" Pd " expected 0", number_of_type_arguments);
     }
     return Api::NewHandle(isolate, Type::NewNonParameterizedType(cls));
   }
@@ -3993,7 +4095,7 @@
     }
     if (num_expected_type_arguments != number_of_type_arguments) {
       return Api::NewError("Invalid number of type arguments specified, "
-                           "got %"Pd" expected %"Pd,
+                           "got %" Pd " expected %" Pd,
                            number_of_type_arguments,
                            num_expected_type_arguments);
     }
@@ -4003,7 +4105,7 @@
     }
     if (array.Length() != num_expected_type_arguments) {
       return Api::NewError("Invalid type arguments specified, expected an "
-                           "array of len %"Pd" but got an array of len %"Pd,
+                           "array of len %" Pd " but got an array of len %" Pd,
                            number_of_type_arguments,
                            array.Length());
     }
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index dc2f88c..322a265 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -86,7 +86,7 @@
     intptr_t max = (max_elements);                                             \
     if (len < 0 || len > max) {                                                \
       return Api::NewError(                                                    \
-          "%s expects argument '%s' to be in the range [0..%"Pd"].",           \
+          "%s expects argument '%s' to be in the range [0..%" Pd "].",         \
           CURRENT_FUNC, #length, max);                                         \
     }                                                                          \
   } while (0)
@@ -203,7 +203,7 @@
   static void SetSmiReturnValue(NativeArguments* args, intptr_t retval) {
     args->SetReturnUnsafe(Smi::New(retval));
   }
-  static void SetIntegerReturnValue(NativeArguments* args, intptr_t retval) {
+  static void SetIntegerReturnValue(NativeArguments* args, int64_t retval) {
     args->SetReturnUnsafe(Integer::New(retval));
   }
   static void SetDoubleReturnValue(NativeArguments* args, double retval) {
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index d73aa85..f92f29c 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -6207,8 +6207,23 @@
   Dart_EnterScope();
   intptr_t i = Dart_GetNativeArgumentCount(args);
   EXPECT_EQ(2, i);
-  Dart_Handle arg = Dart_GetNativeArgument(args, 1);
-  Dart_SetReturnValue(args, Dart_NewInteger(GetValue(arg)));
+  Dart_Handle arg1 = Dart_GetNativeArgument(args, 1);
+  EXPECT_VALID(arg1);
+  int64_t value = 0;
+  EXPECT_VALID(Dart_IntegerToInt64(arg1, &value));
+  int64_t integer_value = 0;
+  Dart_Handle result = Dart_GetNativeIntegerArgument(args,
+                                                     1,
+                                                     &integer_value);
+  EXPECT_VALID(result);
+  EXPECT_EQ(value, integer_value);
+  double double_value;
+  result = Dart_GetNativeDoubleArgument(args, 1, &double_value);
+  EXPECT_VALID(result);
+  bool bool_value;
+  result = Dart_GetNativeBooleanArgument(args, 1, &bool_value);
+  EXPECT(Dart_IsError(result));
+  Dart_SetReturnValue(args, Dart_NewInteger(GetValue(arg1)));
   Dart_ExitScope();
 }
 
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index 5a2cddf..4db8fab 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -40,7 +40,7 @@
     }
 #ifdef DEBUG
     if (FLAG_trace_zones) {
-      OS::PrintErr("*** Starting a new Api zone 0x%"Px"(0x%"Px")\n",
+      OS::PrintErr("*** Starting a new Api zone 0x%" Px "(0x%" Px ")\n",
                    reinterpret_cast<intptr_t>(this),
                    reinterpret_cast<intptr_t>(&zone_));
     }
@@ -55,7 +55,7 @@
     }
 #ifdef DEBUG
     if (FLAG_trace_zones) {
-      OS::PrintErr("*** Deleting Api zone 0x%"Px"(0x%"Px")\n",
+      OS::PrintErr("*** Deleting Api zone 0x%" Px "(0x%" Px ")\n",
                    reinterpret_cast<intptr_t>(this),
                    reinterpret_cast<intptr_t>(&zone_));
     }
@@ -256,7 +256,7 @@
                            kOffsetOfRawPtrInLocalHandle>() {
 #ifdef DEBUG
     if (FLAG_trace_handles) {
-      OS::PrintErr("*** Starting a new Local handle block 0x%"Px"\n",
+      OS::PrintErr("*** Starting a new Local handle block 0x%" Px "\n",
                    reinterpret_cast<intptr_t>(this));
     }
 #endif
@@ -264,10 +264,10 @@
   ~LocalHandles() {
 #ifdef DEBUG
     if (FLAG_trace_handles) {
-      OS::PrintErr("***   Handle Counts for 0x(%"Px"):Scoped = %d\n",
+      OS::PrintErr("***   Handle Counts for 0x(%" Px "):Scoped = %d\n",
                    reinterpret_cast<intptr_t>(this),
                    CountHandles());
-      OS::PrintErr("*** Deleting Local handle block 0x%"Px"\n",
+      OS::PrintErr("*** Deleting Local handle block 0x%" Px "\n",
                    reinterpret_cast<intptr_t>(this));
     }
 #endif
@@ -325,7 +325,7 @@
         free_list_(NULL) {
 #ifdef DEBUG
     if (FLAG_trace_handles) {
-      OS::PrintErr("*** Starting a new Persistent handle block 0x%"Px"\n",
+      OS::PrintErr("*** Starting a new Persistent handle block 0x%" Px "\n",
                    reinterpret_cast<intptr_t>(this));
     }
 #endif
@@ -334,10 +334,10 @@
     free_list_ = NULL;
 #ifdef DEBUG
     if (FLAG_trace_handles) {
-      OS::PrintErr("***   Handle Counts for 0x(%"Px"):Scoped = %d\n",
+      OS::PrintErr("***   Handle Counts for 0x(%" Px "):Scoped = %d\n",
                    reinterpret_cast<intptr_t>(this),
                    CountHandles());
-      OS::PrintErr("*** Deleting Persistent handle block 0x%"Px"\n",
+      OS::PrintErr("*** Deleting Persistent handle block 0x%" Px "\n",
                    reinterpret_cast<intptr_t>(this));
     }
 #endif
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index bdecf76..ff19e46 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -295,6 +295,11 @@
 }
 
 
+bool ActivationFrame::IsDebuggable() const {
+  return Debugger::IsDebuggable(function());
+}
+
+
 // Calculate the context level at the current token index of the frame.
 intptr_t ActivationFrame::ContextLevel() {
   if (context_level_ < 0 && !ctx_.IsNull()) {
@@ -377,8 +382,8 @@
   Array& handled_types = Array::Handle();
   AbstractType& type = Type::Handle();
   const TypeArguments& no_instantiator = TypeArguments::Handle();
-  for (int frame_index = 0; frame_index < Length(); frame_index++) {
-    ActivationFrame* frame = trace_[frame_index];
+  for (int frame_index = 0; frame_index < UnfilteredLength(); frame_index++) {
+    ActivationFrame* frame = UnfilteredFrameAt(frame_index);
     intptr_t try_index = frame->TryIndex();
     if (try_index < 0) continue;
     handlers = frame->code().exception_handlers();
@@ -580,6 +585,9 @@
 
 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) {
   trace_.Add(frame);
+  if (frame->IsDebuggable()) {
+    user_trace_.Add(frame);
+  }
 }
 
 
@@ -963,7 +971,7 @@
           script.GetTokenLocation(activation->TokenPos(), &line, &col);
           OS::Print("CollectStackTrace error: no saved context in function "
               "'%s' which calls closure '%s' "
-              " in line %"Pd" column %"Pd"\n",
+              " in line %" Pd " column %" Pd "\n",
               caller.ToFullyQualifiedCString(),
               callee.ToFullyQualifiedCString(),
               line, col);
@@ -977,10 +985,7 @@
         ASSERT(!ctx.IsNull());
         activation->SetContext(ctx);
       }
-      // Check if frame is a debuggable function.
-      if (IsDebuggable(activation->function())) {
-        stack_trace->AddActivation(activation);
-      }
+      stack_trace->AddActivation(activation);
       callee_activation = activation;
       // Get caller's context if this function saved it on entry.
       ctx = activation->GetSavedEntryContext(ctx);
@@ -1191,7 +1196,7 @@
       // already exists.
       if (FLAG_verbose_debug) {
         OS::Print("Pending breakpoint for uncompiled function"
-                  " '%s' at line %"Pd" already exists\n",
+                  " '%s' at line %" Pd " already exists\n",
                   target_function.ToFullyQualifiedCString(),
                   source_bpt->LineNumber());
       }
@@ -1202,7 +1207,7 @@
     RegisterSourceBreakpoint(source_bpt);
     if (FLAG_verbose_debug) {
       OS::Print("Registering pending breakpoint for "
-                "uncompiled function '%s' at line %"Pd"\n",
+                "uncompiled function '%s' at line %" Pd "\n",
                 target_function.ToFullyQualifiedCString(),
                 source_bpt->LineNumber());
     }
@@ -1286,7 +1291,7 @@
   if (first_token_idx < 0) {
     // Script does not contain the given line number.
     if (FLAG_verbose_debug) {
-      OS::Print("Script '%s' does not contain line number %"Pd"\n",
+      OS::Print("Script '%s' does not contain line number %" Pd "\n",
                 script_url.ToCString(), line_number);
     }
     return NULL;
@@ -1307,7 +1312,7 @@
   }
   if (func.IsNull()) {
     if (FLAG_verbose_debug) {
-      OS::Print("No executable code at line %"Pd" in '%s'\n",
+      OS::Print("No executable code at line %" Pd " in '%s'\n",
                 line_number, script_url.ToCString());
     }
     return NULL;
@@ -1588,7 +1593,7 @@
   }
 
   if (FLAG_verbose_debug) {
-    OS::Print(">>> single step break at %s:%"Pd" (func %s token %"Pd")\n",
+    OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n",
               String::Handle(frame->SourceUrl()).ToCString(),
               frame->LineNumber(),
               String::Handle(frame->QualifiedFunctionName()).ToCString(),
@@ -1603,7 +1608,7 @@
     InstrumentForStepping(func);
   } else if (resume_action_ == kStepOut) {
     if (stack_trace_->Length() > 1) {
-      ActivationFrame* caller_frame = stack_trace_->ActivationFrameAt(1);
+      ActivationFrame* caller_frame = stack_trace_->FrameAt(1);
       InstrumentForStepping(caller_frame->function());
     }
   }
@@ -1619,8 +1624,8 @@
     return;
   }
   DebuggerStackTrace* stack_trace = CollectStackTrace();
-  ASSERT(stack_trace->Length() > 0);
-  ActivationFrame* top_frame = stack_trace->ActivationFrameAt(0);
+  ASSERT(stack_trace->UnfilteredLength() > 0);
+  ActivationFrame* top_frame = stack_trace->UnfilteredFrameAt(0);
   ASSERT(top_frame != NULL);
   CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc());
   ASSERT(bpt != NULL);
@@ -1630,8 +1635,8 @@
     report_bp = false;
   }
   if (FLAG_verbose_debug) {
-    OS::Print(">>> %s %s breakpoint at %s:%"Pd" "
-              "(token %"Pd") (address %#"Px")\n",
+    OS::Print(">>> %s %s breakpoint at %s:%" Pd " "
+              "(token %" Pd ") (address %#" Px ")\n",
               report_bp ? "hit" : "ignore",
               bpt->IsInternal() ? "internal" : "user",
               String::Handle(bpt->SourceUrl()).ToCString(),
@@ -1657,7 +1662,7 @@
     }
   } else if (resume_action_ == kStepOut) {
     if (stack_trace->Length() > 1) {
-      ActivationFrame* caller_frame = stack_trace->ActivationFrameAt(1);
+      ActivationFrame* caller_frame = stack_trace->FrameAt(1);
       func_to_instrument = caller_frame->function().raw();
     }
   } else {
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 90ec050..bf4bc73 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -144,6 +144,10 @@
   intptr_t LineNumber();
   void SetContext(const Context& ctx) { ctx_ = ctx.raw(); }
 
+  // Returns true if this frame is for a function that is visible
+  // to the user and can be debugged.
+  bool IsDebuggable() const;
+
   // The context level of a frame is the context level at the
   // PC/token index of the frame. It determines the depth of the context
   // chain that belongs to the function of this activation frame.
@@ -201,18 +205,27 @@
 class DebuggerStackTrace : public ZoneAllocated {
  public:
   explicit DebuggerStackTrace(int capacity)
-      : trace_(capacity) { }
+      : trace_(capacity),
+        user_trace_(capacity) { }
 
-  intptr_t Length() const { return trace_.length(); }
+  intptr_t Length() const { return user_trace_.length(); }
 
-  ActivationFrame* ActivationFrameAt(int i) const {
-    ASSERT(i < trace_.length());
+  ActivationFrame* FrameAt(int i) const {
+    return user_trace_[i];
+  }
+
+  ActivationFrame* GetHandlerFrame(const Instance& exc_obj) const;
+
+ private:
+  intptr_t UnfilteredLength() const { return trace_.length(); }
+
+  ActivationFrame* UnfilteredFrameAt(int i) const {
     return trace_[i];
   }
-  ActivationFrame* GetHandlerFrame(const Instance& exc_obj) const;
- private:
+
   void AddActivation(ActivationFrame* frame);
   ZoneGrowableArray<ActivationFrame*> trace_;
+  ZoneGrowableArray<ActivationFrame*> user_trace_;
 
   friend class Debugger;
   DISALLOW_COPY_AND_ASSIGN(DebuggerStackTrace);
@@ -315,6 +328,8 @@
 
   uword GetPatchedStubAddress(uword breakpoint_address);
 
+  static bool IsDebuggable(const Function& func);
+
  private:
   enum ResumeAction {
     kContinue,
@@ -350,8 +365,6 @@
   void SignalBpResolved(SourceBreakpoint *bpt);
   void SignalPausedEvent(ActivationFrame* top_frame);
 
-  static bool IsDebuggable(const Function& func);
-
   intptr_t nextId() { return next_id_++; }
 
   bool ShouldPauseOnException(DebuggerStackTrace* stack_trace,
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 32e8a3a..0df495b 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -5,6 +5,7 @@
 #include "include/dart_debugger_api.h"
 
 #include "vm/class_finalizer.h"
+#include "vm/compiler.h"
 #include "vm/dart_api_impl.h"
 #include "vm/dart_api_state.h"
 #include "vm/debugger.h"
@@ -64,7 +65,7 @@
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   if (!isolate->debugger()->IsValidObjectId(obj_id)) {
-    return Api::NewError("%s: object id %"Pd" is invalid",
+    return Api::NewError("%s: object id %" Pd " is invalid",
                          CURRENT_FUNC, obj_id);
   }
   return Api::NewHandle(isolate, isolate->debugger()->GetCachedObject(obj_id));
@@ -96,7 +97,7 @@
                          CURRENT_FUNC);
   }
   *frame = reinterpret_cast<Dart_ActivationFrame>(
-       stack_trace->ActivationFrameAt(frame_index));
+       stack_trace->FrameAt(frame_index));
   return Api::Success();
 }
 
@@ -289,12 +290,18 @@
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   UNWRAP_AND_CHECK_PARAM(String, script_url, script_url_in);
+
+  Dart_Handle state = Api::CheckIsolateState(isolate);
+  if (::Dart_IsError(state)) {
+    return state;
+  }
+
   Debugger* debugger = isolate->debugger();
   ASSERT(debugger != NULL);
   SourceBreakpoint* bpt =
       debugger->SetBreakpointAtLine(script_url, line_number);
   if (bpt == NULL) {
-    return Api::NewError("%s: could not set breakpoint at line %"Pd" in '%s'",
+    return Api::NewError("%s: could not set breakpoint at line %" Pd " in '%s'",
                          CURRENT_FUNC, line_number, script_url.ToCString());
   }
   return Dart_NewInteger(bpt->id());
@@ -309,7 +316,7 @@
 
   SourceBreakpoint* bpt = debugger->GetBreakpointById(bp_id);
   if (bpt == NULL) {
-    return Api::NewError("%s: breakpoint with id %"Pd" does not exist",
+    return Api::NewError("%s: breakpoint with id %" Pd " does not exist",
                            CURRENT_FUNC, bp_id);
   }
   return Api::NewHandle(isolate, bpt->SourceUrl());
@@ -324,7 +331,7 @@
 
   SourceBreakpoint* bpt = debugger->GetBreakpointById(bp_id);
   if (bpt == NULL) {
-    return Api::NewError("%s: breakpoint with id %"Pd" does not exist",
+    return Api::NewError("%s: breakpoint with id %" Pd " does not exist",
                          CURRENT_FUNC, bp_id);
   }
   return Dart_NewInteger(bpt->LineNumber());
@@ -471,7 +478,7 @@
   const Library& lib =
       Library::Handle(isolate, Library::GetLibrary(library_id));
   if (lib.IsNull()) {
-    return Api::NewError("%s: %"Pd" is not a valid library id",
+    return Api::NewError("%s: %" Pd " is not a valid library id",
                          CURRENT_FUNC, library_id);
   }
   return Api::NewHandle(isolate, isolate->debugger()->GetLibraryFields(lib));
@@ -484,13 +491,23 @@
   DARTSCOPE(isolate);
   const Library& lib = Library::Handle(Library::GetLibrary(library_id));
   if (lib.IsNull()) {
-    return Api::NewError("%s: %"Pd" is not a valid library id",
+    return Api::NewError("%s: %" Pd " is not a valid library id",
                          CURRENT_FUNC, library_id);
   }
   return Api::NewHandle(isolate, isolate->debugger()->GetGlobalFields(lib));
 }
 
 
+DART_EXPORT Dart_Handle Dart_EvaluateExpr(Dart_Handle target,
+                                          Dart_Handle expr_in) {
+  Isolate* isolate = Isolate::Current();
+  DARTSCOPE(isolate);
+  UNWRAP_AND_CHECK_PARAM(Instance, obj, target);
+  UNWRAP_AND_CHECK_PARAM(String, expr, expr_in);
+  return Api::NewHandle(isolate, obj.Evaluate(expr));
+}
+
+
 DART_EXPORT Dart_Handle Dart_GetObjClass(Dart_Handle object_in) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
@@ -574,7 +591,7 @@
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   if (!isolate->class_table()->IsValidIndex(cls_id)) {
-    return Api::NewError("%s: %"Pd" is not a valid class id",
+    return Api::NewError("%s: %" Pd " is not a valid class id",
                          CURRENT_FUNC, cls_id);
   }
   Class& cls = Class::Handle(isolate, isolate->class_table()->At(cls_id));
@@ -607,7 +624,7 @@
   DARTSCOPE(isolate);
   const Library& lib = Library::Handle(Library::GetLibrary(library_id));
   if (lib.IsNull()) {
-    return Api::NewError("%s: %"Pd" is not a valid library id",
+    return Api::NewError("%s: %" Pd " is not a valid library id",
                          CURRENT_FUNC, library_id);
   }
   UNWRAP_AND_CHECK_PARAM(String, script_url, script_url_in);
@@ -628,7 +645,7 @@
   DARTSCOPE(isolate);
   const Library& lib = Library::Handle(Library::GetLibrary(library_id));
   if (lib.IsNull()) {
-    return Api::NewError("%s: %"Pd" is not a valid library id",
+    return Api::NewError("%s: %" Pd " is not a valid library id",
                          CURRENT_FUNC, library_id);
   }
   UNWRAP_AND_CHECK_PARAM(String, script_url, script_url_in);
@@ -749,7 +766,7 @@
   DARTSCOPE(isolate);
   const Library& lib = Library::Handle(Library::GetLibrary(library_id));
   if (lib.IsNull()) {
-    return Api::NewError("%s: %"Pd" is not a valid library id",
+    return Api::NewError("%s: %" Pd " is not a valid library id",
                          CURRENT_FUNC, library_id);
   }
   const GrowableObjectArray& import_list =
@@ -788,7 +805,7 @@
   DARTSCOPE(isolate);
   const Library& lib = Library::Handle(Library::GetLibrary(library_id));
   if (lib.IsNull()) {
-    return Api::NewError("%s: %"Pd" is not a valid library id",
+    return Api::NewError("%s: %" Pd " is not a valid library id",
                          CURRENT_FUNC, library_id);
   }
   return Api::NewHandle(isolate, lib.url());
@@ -803,7 +820,7 @@
   CHECK_NOT_NULL(is_debuggable);
   const Library& lib = Library::Handle(Library::GetLibrary(library_id));
   if (lib.IsNull()) {
-    return Api::NewError("%s: %"Pd" is not a valid library id",
+    return Api::NewError("%s: %" Pd " is not a valid library id",
                          CURRENT_FUNC, library_id);
   }
   *is_debuggable = lib.IsDebuggable();
@@ -818,7 +835,7 @@
   DARTSCOPE(isolate);
   const Library& lib = Library::Handle(Library::GetLibrary(library_id));
   if (lib.IsNull()) {
-    return Api::NewError("%s: %"Pd" is not a valid library id",
+    return Api::NewError("%s: %" Pd " is not a valid library id",
                          CURRENT_FUNC, library_id);
   }
   lib.set_debuggable(is_debuggable);
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index 070cf3f..2cec246 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -49,6 +49,24 @@
 }
 
 
+static int64_t ToInt64(Dart_Handle h) {
+  EXPECT(Dart_IsInteger(h));
+  int64_t i = 0;
+  Dart_Handle res = Dart_IntegerToInt64(h, &i);
+  EXPECT_VALID(res);
+  return i;
+}
+
+
+static double ToDouble(Dart_Handle h) {
+  EXPECT(Dart_IsDouble(h));
+  double d = 0.0;
+  Dart_Handle res = Dart_DoubleValue(h, &d);
+  EXPECT_VALID(res);
+  return d;
+}
+
+
 static char const* BreakpointInfo(Dart_StackTrace trace) {
   static char info_str[128];
   Dart_ActivationFrame frame;
@@ -61,7 +79,7 @@
   res = Dart_ActivationFrameInfo(
             frame, &func_name, &url, &line_number, &library_id);
   EXPECT_TRUE(res);
-  OS::SNPrint(info_str, sizeof(info_str), "function %s (%s:%"Pd")",
+  OS::SNPrint(info_str, sizeof(info_str), "function %s (%s:%" Pd ")",
               ToCString(func_name), ToCString(url), line_number);
   return info_str;
 }
@@ -151,6 +169,28 @@
 }
 
 
+static Dart_Handle GetLocalVariable(Dart_ActivationFrame frame,
+                                    const char* name) {
+  Dart_Handle locals = Dart_GetLocalVariables(frame);
+  EXPECT_VALID(locals);
+  intptr_t list_length = 0;
+  Dart_Handle ret = Dart_ListLength(locals, &list_length);
+  EXPECT_VALID(ret);
+  for (int i = 0; i + 1 < list_length; i += 2) {
+    Dart_Handle name_handle = Dart_ListGetAt(locals, i);
+    EXPECT_VALID(name_handle);
+    EXPECT(Dart_IsString(name_handle));
+    if (strcmp(ToCString(name_handle), name) == 0) {
+      Dart_Handle value_handle = Dart_ListGetAt(locals, i + 1);
+      EXPECT_VALID(value_handle);
+      return value_handle;
+    }
+  }
+  EXPECT(!"local variable not found");
+  return Dart_Null();
+}
+
+
 static void PrintStackTrace(Dart_StackTrace trace) {
   intptr_t trace_len;
   Dart_Handle res = Dart_StackTraceLength(trace, &trace_len);
@@ -344,8 +384,7 @@
   Dart_Handle retval = Invoke("main");
   EXPECT_VALID(retval);
   EXPECT(Dart_IsInteger(retval));
-  int64_t int_value = 0;
-  Dart_IntegerToInt64(retval, &int_value);
+  int64_t int_value = ToInt64(retval);
   EXPECT_EQ(2, int_value);
   EXPECT(breakpoint_hit == true);
 }
@@ -426,8 +465,7 @@
   Dart_Handle retval = Invoke("main");
   EXPECT_VALID(retval);
   EXPECT(Dart_IsInteger(retval));
-  int64_t int_value = 0;
-  Dart_IntegerToInt64(retval, &int_value);
+  int64_t int_value = ToInt64(retval);
   EXPECT_EQ(7, int_value);
   EXPECT(breakpoint_hit == true);
 }
@@ -472,8 +510,7 @@
   Dart_Handle retval = Invoke("main");
   EXPECT_VALID(retval);
   EXPECT(Dart_IsInteger(retval));
-  int64_t int_value = 0;
-  Dart_IntegerToInt64(retval, &int_value);
+  int64_t int_value = ToInt64(retval);
   EXPECT_EQ(101, int_value);
   EXPECT(breakpoint_hit == true);
 }
@@ -510,8 +547,7 @@
   Dart_Handle retval = Invoke("main");
   EXPECT_VALID(retval);
   EXPECT(Dart_IsInteger(retval));
-  int64_t int_value = 0;
-  Dart_IntegerToInt64(retval, &int_value);
+  int64_t int_value = ToInt64(retval);
   EXPECT_EQ(2 * 99, int_value);
   EXPECT(breakpoint_hit == true);
 }
@@ -624,8 +660,7 @@
   breakpoint_hit_counter = 0;
   Dart_Handle retval = Invoke("main");
   EXPECT_VALID(retval);
-  int64_t int_value = 0;
-  Dart_IntegerToInt64(retval, &int_value);
+  int64_t int_value = ToInt64(retval);
   EXPECT_EQ(442, int_value);
   EXPECT_EQ(2, breakpoint_hit_counter);
 }
@@ -671,8 +706,7 @@
   breakpoint_hit_counter = 0;
   Dart_Handle retval = Invoke("main");
   EXPECT_VALID(retval);
-  int64_t int_value = 0;
-  Dart_IntegerToInt64(retval, &int_value);
+  int64_t int_value = ToInt64(retval);
   EXPECT_EQ(30, int_value);
   EXPECT_EQ(1, breakpoint_hit_counter);
 }
@@ -737,8 +771,7 @@
   Dart_Handle res = Dart_SetBreakpoint(script_url, line_no);
   EXPECT_VALID(res);
   EXPECT(Dart_IsInteger(res));
-  int64_t bp_id = 0;
-  Dart_IntegerToInt64(res, &bp_id);
+  int64_t bp_id = ToInt64(res);
 
   // Function main() calls foo() 3 times. On the second iteration, the
   // breakpoint is removed by the handler, so we expect the breakpoint
@@ -888,8 +921,7 @@
   Dart_Handle triple_six = Invoke("get_int");
   EXPECT_VALID(triple_six);
   EXPECT(Dart_IsInteger(triple_six));
-  int64_t int_value = 0;
-  Dart_IntegerToInt64(triple_six, &int_value);
+  int64_t int_value = ToInt64(triple_six);
   EXPECT_EQ(666, int_value);
   fields = Dart_GetInstanceFields(triple_six);
   EXPECT_VALID(fields);
@@ -1281,8 +1313,7 @@
   breakpoint_hit_counter = 0;
   Dart_Handle retval = Invoke("main");
   EXPECT_VALID(retval);
-  int64_t int_value = 0;
-  Dart_IntegerToInt64(retval, &int_value);
+  int64_t int_value = ToInt64(retval);
   EXPECT_EQ(195, int_value);
   EXPECT_EQ(1, breakpoint_hit_counter);
 }
@@ -1448,6 +1479,89 @@
 }
 
 
+void TestEvaluateHandler(Dart_IsolateId isolate_id,
+                         const Dart_CodeLocation& location) {
+  Dart_StackTrace trace;
+  Dart_GetStackTrace(&trace);
+  intptr_t trace_len;
+  Dart_Handle res = Dart_StackTraceLength(trace, &trace_len);
+  EXPECT_VALID(res);
+  EXPECT_EQ(1, trace_len);
+  Dart_ActivationFrame frame;
+  res = Dart_GetActivationFrame(trace, 0, &frame);
+  EXPECT_VALID(res);
+
+  // Get the local variable p and evaluate an expression in the
+  // context of p.
+  Dart_Handle p = GetLocalVariable(frame, "p");
+  EXPECT_VALID(p);
+  EXPECT(!Dart_IsNull(p));
+
+  Dart_Handle r = Dart_EvaluateExpr(p, NewString("sqrt(x*x + y*this.y)"));
+  EXPECT_VALID(r);
+  EXPECT(Dart_IsNumber(r));
+  EXPECT_EQ(5.0, ToDouble(r));
+
+  // Set top-level variable to a new value.
+  Dart_Handle h = Dart_EvaluateExpr(p, NewString("_factor = 10"));
+  EXPECT_VALID(h);
+  EXPECT(Dart_IsInteger(h));
+  EXPECT_EQ(10, ToInt64(h));
+
+  // Check that the side effect of the previous expression is
+  // persistent.
+  h = Dart_EvaluateExpr(p, NewString("_factor"));
+  EXPECT_VALID(h);
+  EXPECT(Dart_IsInteger(h));
+  EXPECT_EQ(10, ToInt64(h));
+
+  breakpoint_hit = true;
+  breakpoint_hit_counter++;
+}
+
+
+TEST_CASE(Debug_EvaluateExpr) {
+  const char* kScriptChars =
+      "import 'dart:math';               \n"
+      "main() {                          \n"
+      "  var p = new Point(3, 4);        \n"
+      "  l = [1, 2, 3];        /*BP*/    \n"
+      "  return p;                       \n"
+      "}                                 \n"
+      "var _factor = 2;                  \n"
+      "var l;                            \n"
+      "class Point {                     \n"
+      "  var x, y;                       \n"
+      "  Point(this.x, this.y);          \n"
+      "}                                 \n";
+
+  LoadScript(kScriptChars);
+  Dart_SetPausedEventHandler(&TestEvaluateHandler);
+
+
+  Dart_Handle script_url = NewString(TestCase::url());
+  intptr_t line_no = 4;
+  Dart_Handle res = Dart_SetBreakpoint(script_url, line_no);
+  EXPECT_VALID(res);
+
+  breakpoint_hit = false;
+  Dart_Handle point = Invoke("main");
+  EXPECT_VALID(point);
+  EXPECT(breakpoint_hit == true);
+
+  Dart_Handle r =
+      Dart_EvaluateExpr(point, NewString("_factor * sqrt(x*x + y*y)"));
+  EXPECT_VALID(r);
+  EXPECT(Dart_IsDouble(r));
+  EXPECT_EQ(50.0, ToDouble(r));
+
+  Dart_Handle len = Dart_EvaluateExpr(point, NewString("l.length"));
+  EXPECT_VALID(len);
+  EXPECT(Dart_IsNumber(len));
+  EXPECT_EQ(3, ToInt64(len));
+}
+
+
 TEST_CASE(Debug_GetSupertype) {
   const char* kScriptChars =
       "class Test {\n"
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 834cfd0..f374053 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -87,7 +87,7 @@
 
   virtual const char* ToCString() const {
     return Isolate::Current()->current_zone()->PrintToString(
-        "s%"Pd"", stack_slot_index_);
+        "s%" Pd "", stack_slot_index_);
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
@@ -116,7 +116,7 @@
 
   virtual const char* ToCString() const {
     return Isolate::Current()->current_zone()->PrintToString(
-        "ds%"Pd"", stack_slot_index_);
+        "ds%" Pd "", stack_slot_index_);
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
@@ -148,7 +148,7 @@
 
   virtual const char* ToCString() const {
     return Isolate::Current()->current_zone()->PrintToString(
-        "ms%"Pd"", stack_slot_index_);
+        "ms%" Pd "", stack_slot_index_);
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
@@ -185,7 +185,7 @@
 
   virtual const char* ToCString() const {
     return Isolate::Current()->current_zone()->PrintToString(
-        "f32x4s%"Pd"", stack_slot_index_);
+        "f32x4s%" Pd "", stack_slot_index_);
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
@@ -217,7 +217,7 @@
 
   virtual const char* ToCString() const {
     return Isolate::Current()->current_zone()->PrintToString(
-        "ui32x4s%"Pd"", stack_slot_index_);
+        "ui32x4s%" Pd "", stack_slot_index_);
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
@@ -261,7 +261,7 @@
 
   virtual const char* ToCString() const {
     return Isolate::Current()->current_zone()->PrintToString(
-        "ret oti:%"Pd"(%"Pd")", object_table_index_, deopt_id_);
+        "ret oti:%" Pd "(%" Pd ")", object_table_index_, deopt_id_);
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
@@ -315,7 +315,7 @@
 
   virtual const char* ToCString() const {
     return Isolate::Current()->current_zone()->PrintToString(
-        "const oti:%"Pd"", object_table_index_);
+        "const oti:%" Pd "", object_table_index_);
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
@@ -484,7 +484,7 @@
 
   virtual const char* ToCString() const {
     return Isolate::Current()->current_zone()->PrintToString(
-        "pcmark oti:%"Pd"", object_table_index_);
+        "pcmark oti:%" Pd "", object_table_index_);
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
@@ -536,7 +536,7 @@
 
   virtual const char* ToCString() const {
     return Isolate::Current()->current_zone()->PrintToString(
-        "pp oti:%"Pd"", object_table_index_);
+        "pp oti:%" Pd "", object_table_index_);
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
@@ -647,7 +647,7 @@
 
   virtual const char* ToCString() const {
     return Isolate::Current()->current_zone()->PrintToString(
-        "suffix %"Pd":%"Pd, info_number_, suffix_length_);
+        "suffix %" Pd ":%" Pd, info_number_, suffix_length_);
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
@@ -686,7 +686,7 @@
 
   virtual const char* ToCString() const {
     return Isolate::Current()->current_zone()->PrintToString(
-        "mat ref #%"Pd"", index_);
+        "mat ref #%" Pd "", index_);
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
@@ -717,7 +717,7 @@
 
   virtual const char* ToCString() const {
     return Isolate::Current()->current_zone()->PrintToString(
-        "mat obj len:%"Pd"", field_count_);
+        "mat obj len:%" Pd "", field_count_);
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
diff --git a/runtime/vm/disassembler_arm.cc b/runtime/vm/disassembler_arm.cc
index 6acd20f..491d185 100644
--- a/runtime/vm/disassembler_arm.cc
+++ b/runtime/vm/disassembler_arm.cc
@@ -428,7 +428,7 @@
         uword destination = reinterpret_cast<uword>(instr) + off;
         buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
                                    remaining_size_in_buffer(),
-                                   "%#"Px"",
+                                   "%#" Px "",
                                    destination);
         return 4;
       } else {
diff --git a/runtime/vm/disassembler_ia32.cc b/runtime/vm/disassembler_ia32.cc
index 5f1131e..9272794 100644
--- a/runtime/vm/disassembler_ia32.cc
+++ b/runtime/vm/disassembler_ia32.cc
@@ -467,7 +467,7 @@
 void X86Decoder::PrintAddress(uword addr) {
   NoGCScope no_gc;
   char addr_buffer[32];
-  OS::SNPrint(addr_buffer, sizeof(addr_buffer), "%#"Px"", addr);
+  OS::SNPrint(addr_buffer, sizeof(addr_buffer), "%#" Px "", addr);
   Print(addr_buffer);
   // Try to print as heap object or stub name
   if (((addr & kSmiTagMask) == kHeapObjectTag) &&
@@ -1392,7 +1392,7 @@
             Print(",");
             data += PrintRightXmmOperand(data);
           } else if (f0byte == 0x50) {
-            Print("movmskpd ");
+            Print("movmskps ");
             int mod, regop, rm;
             GetModRm(*data, &mod, &regop, &rm);
             PrintCPURegister(regop);
@@ -1505,16 +1505,7 @@
           PrintCPURegister(regop);
         } else if (*data == 0x0F) {
           data++;
-          if (*data == 0x2F) {
-            data++;
-            int mod, regop, rm;
-            GetModRm(*data, &mod, &regop, &rm);
-            Print("comisd ");
-            PrintXmmRegister(regop);
-            Print(",");
-            PrintXmmRegister(rm);
-            data++;
-          } else if (*data == 0X6E) {
+          if (*data == 0X6E) {
             data++;
             int mod, regop, rm;
             GetModRm(*data, &mod, &regop, &rm);
@@ -1609,8 +1600,20 @@
             Print(",");
             PrintXmmRegister(rm);
             data += 2;
+          } else if ((*data == 0xFE) || (*data == 0xFA) || (*data == 0x2F)) {
+            const char* mnemonic = NULL;
+            if (*data == 0xFE) mnemonic = "paddd ";
+            if (*data == 0xFA) mnemonic = "psubd ";
+            if (*data == 0x2F) mnemonic = "comisd ";
+            int mod, regop, rm;
+            GetModRm(*(data+1), &mod, &regop, &rm);
+            Print(mnemonic);
+            PrintXmmRegister(regop);
+            Print(",");
+            PrintXmmRegister(rm);
+            data += 2;
           } else {
-            UNIMPLEMENTED();
+              UNIMPLEMENTED();
           }
         } else if (*data == 0x90) {
           data++;
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index 8c5dbd4..b47aaf2 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -215,7 +215,7 @@
           reinterpret_cast<uword>(instr) + off + Instr::kInstrSize;
       buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
                                  remaining_size_in_buffer(),
-                                 "%#"Px"",
+                                 "%#" Px "",
                                  destination);
       return 4;
     }
diff --git a/runtime/vm/disassembler_x64.cc b/runtime/vm/disassembler_x64.cc
index f42ebac..7aefeb5 100644
--- a/runtime/vm/disassembler_x64.cc
+++ b/runtime/vm/disassembler_x64.cc
@@ -566,7 +566,7 @@
       value = 0;  // Initialize variables on all paths to satisfy the compiler.
       count = 0;
   }
-  AppendToBuffer("%#"Px64"", value);
+  AppendToBuffer("%#" Px64 "", value);
   return count;
 }
 
@@ -804,7 +804,7 @@
 void DisassemblerX64::AppendAddressToBuffer(uint8_t* addr_byte_ptr) {
   NoGCScope no_gc;
   uword addr = reinterpret_cast<uword>(addr_byte_ptr);
-  AppendToBuffer("%#"Px"", addr);
+  AppendToBuffer("%#" Px "", addr);
   // Try to print as heap object or stub name
   if (((addr & kSmiTagMask) == kHeapObjectTag) &&
       !Isolate::Current()->heap()->CodeContains(addr) &&
@@ -1282,6 +1282,10 @@
           mnemonic = "ucomisd";
         } else if (opcode == 0x2F) {
           mnemonic = "comisd";
+        } else if (opcode == 0xFE) {
+          mnemonic = "paddd";
+        } else if (opcode == 0xFA) {
+          mnemonic = "psubd";
         } else {
           UnimplementedInstruction();
         }
@@ -1418,6 +1422,11 @@
     get_modrm(*current, &mod, &regop, &rm);
     AppendToBuffer("movups %s, ", NameOfXMMRegister(regop));
     current += PrintRightXMMOperand(current);
+  } else if (opcode == 0x50) {
+    int mod, regop, rm;
+    get_modrm(*current, &mod, &regop, &rm);
+    AppendToBuffer("movmskps %s,", NameOfCPURegister(regop));
+    current += PrintRightXMMOperand(current);
   } else if (opcode == 0xA2 || opcode == 0x31) {
     // RDTSC or CPUID
     AppendToBuffer("%s", mnemonic);
@@ -1823,7 +1832,7 @@
           default:
             UNREACHABLE();
         }
-        AppendToBuffer("test%c rax,%#"Px64"",
+        AppendToBuffer("test%c rax,%#" Px64 "",
                        operand_size_code(),
                        value);
         break;
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 8ff2c10..6259451 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -539,7 +539,7 @@
     }
     intptr_t line, column;
     script.GetTokenLocation(location, &line, &column);
-    OS::Print("'%s': Failed type check: line %"Pd" pos %"Pd": ",
+    OS::Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ",
               String::Handle(script.url()).ToCString(), line, column);
     if (!dst_name.IsNull() && (dst_name.Length() > 0)) {
       OS::Print("type '%s' is not a subtype of type '%s' of '%s'.\n",
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 0d80ae7..7cabc29 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -289,7 +289,7 @@
 static void PrintBitVector(const char* tag, BitVector* v) {
   OS::Print("%s:", tag);
   for (BitVector::Iterator it(v); !it.Done(); it.Advance()) {
-    OS::Print(" %"Pd"", it.Current());
+    OS::Print(" %" Pd "", it.Current());
   }
   OS::Print("\n");
 }
@@ -299,12 +299,12 @@
   const intptr_t block_count = postorder_.length();
   for (intptr_t i = 0; i < block_count; i++) {
     BlockEntryInstr* block = postorder_[i];
-    OS::Print("block @%"Pd" -> ", block->block_id());
+    OS::Print("block @%" Pd " -> ", block->block_id());
 
     Instruction* last = block->last_instruction();
     for (intptr_t j = 0; j < last->SuccessorCount(); j++) {
       BlockEntryInstr* succ = last->SuccessorAt(j);
-      OS::Print(" @%"Pd"", succ->block_id());
+      OS::Print(" @%" Pd "", succ->block_id());
     }
     OS::Print("\n");
 
@@ -984,7 +984,7 @@
   n->set_loop_info(loop);
   if (FLAG_trace_optimization) {
     for (BitVector::Iterator it(loop); !it.Done(); it.Advance()) {
-      OS::Print("  B%"Pd"\n", preorder_[it.Current()]->block_id());
+      OS::Print("  B%" Pd "\n", preorder_[it.Current()]->block_id());
     }
   }
 }
@@ -1002,7 +1002,7 @@
       BlockEntryInstr* pred = block->PredecessorAt(i);
       if (block->Dominates(pred)) {
         if (FLAG_trace_optimization) {
-          OS::Print("Back edge B%"Pd" -> B%"Pd"\n", pred->block_id(),
+          OS::Print("Back edge B%" Pd " -> B%" Pd "\n", pred->block_id(),
                     block->block_id());
         }
         FindLoop(pred, block);
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 5548c43..ab2d296 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -369,7 +369,8 @@
     return;
   }
 
-  OS::Print("  live range v%"Pd" [%"Pd", %"Pd") in ", vreg(), Start(), End());
+  OS::Print("  live range v%" Pd " [%" Pd ", %" Pd ") in ",
+            vreg(), Start(), End());
   assigned_location().Print();
   OS::Print("\n");
 
@@ -377,11 +378,11 @@
   for (UseInterval* interval = first_use_interval_;
        interval != NULL;
        interval = interval->next()) {
-    OS::Print("    use interval [%"Pd", %"Pd")\n",
+    OS::Print("    use interval [%" Pd ", %" Pd ")\n",
               interval->start(),
               interval->end());
     while ((use_pos != NULL) && (use_pos->pos() <= interval->end())) {
-      OS::Print("      use at %"Pd"", use_pos->pos());
+      OS::Print("      use at %" Pd "", use_pos->pos());
       if (use_pos->location_slot() != NULL) {
         OS::Print(" as ");
         use_pos->location_slot()->Print();
@@ -1482,7 +1483,7 @@
                                 first_safepoint_after_split,
                                 next_sibling_);
 
-  TRACE_ALLOC(OS::Print("  split sibling [%"Pd", %"Pd")\n",
+  TRACE_ALLOC(OS::Print("  split sibling [%" Pd ", %" Pd ")\n",
                         next_sibling_->Start(), next_sibling_->End()));
 
   last_use_interval_ = last_before_split;
@@ -1499,7 +1500,8 @@
 LiveRange* FlowGraphAllocator::SplitBetween(LiveRange* range,
                                             intptr_t from,
                                             intptr_t to) {
-  TRACE_ALLOC(OS::Print("split v%"Pd" [%"Pd", %"Pd") between [%"Pd", %"Pd")\n",
+  TRACE_ALLOC(OS::Print("split v%" Pd " [%" Pd ", %" Pd
+                        ") between [%" Pd ", %" Pd ")\n",
                         range->vreg(), range->Start(), range->End(), from, to));
 
   intptr_t split_pos = kIllegalPosition;
@@ -1537,8 +1539,8 @@
                                       intptr_t from,
                                       intptr_t to) {
   ASSERT(from < to);
-  TRACE_ALLOC(OS::Print("spill v%"Pd" [%"Pd", %"Pd") "
-                        "between [%"Pd", %"Pd")\n",
+  TRACE_ALLOC(OS::Print("spill v%" Pd " [%" Pd ", %" Pd ") "
+                        "between [%" Pd ", %" Pd ")\n",
                         range->vreg(), range->Start(), range->End(), from, to));
   LiveRange* tail = range->SplitAt(from);
 
@@ -1555,7 +1557,7 @@
 
 
 void FlowGraphAllocator::SpillAfter(LiveRange* range, intptr_t from) {
-  TRACE_ALLOC(OS::Print("spill v%"Pd" [%"Pd", %"Pd") after %"Pd"\n",
+  TRACE_ALLOC(OS::Print("spill v%" Pd " [%" Pd ", %" Pd ") after %" Pd "\n",
                         range->vreg(), range->Start(), range->End(), from));
 
   // When spilling the value inside the loop check if this spill can
@@ -1569,7 +1571,7 @@
         RangeHasOnlyUnconstrainedUsesInLoop(range, loop_header->loop_id())) {
       ASSERT(loop_header->entry()->start_pos() <= from);
       from = loop_header->entry()->start_pos();
-      TRACE_ALLOC(OS::Print("  moved spill position to loop header %"Pd"\n",
+      TRACE_ALLOC(OS::Print("  moved spill position to loop header %" Pd "\n",
                             from));
     }
   }
@@ -1791,7 +1793,7 @@
       candidate = hint.register_code();
     }
 
-    TRACE_ALLOC(OS::Print("found hint %s for v%"Pd": free until %"Pd"\n",
+    TRACE_ALLOC(OS::Print("found hint %s for v%" Pd ": free until %" Pd "\n",
                           hint.Name(),
                           unallocated->vreg(),
                           free_until));
@@ -1853,8 +1855,8 @@
 
     if (used_on_backedge[candidate]) {
       TRACE_ALLOC(OS::Print(
-          "considering %s for v%"Pd": has interference on the back edge"
-          " {loop [%"Pd", %"Pd")}\n",
+          "considering %s for v%" Pd ": has interference on the back edge"
+          " {loop [%" Pd ", %" Pd ")}\n",
           MakeRegisterLocation(candidate).Name(),
           unallocated->vreg(),
           loop_header->entry()->start_pos(),
@@ -1872,7 +1874,7 @@
           candidate = reg;
           free_until = intersection;
           TRACE_ALLOC(OS::Print(
-              "found %s for v%"Pd" with no interference on the back edge\n",
+              "found %s for v%" Pd " with no interference on the back edge\n",
               MakeRegisterLocation(candidate).Name(),
               candidate));
           break;
@@ -1883,11 +1885,11 @@
 
   TRACE_ALLOC(OS::Print("assigning free register "));
   TRACE_ALLOC(MakeRegisterLocation(candidate).Print());
-  TRACE_ALLOC(OS::Print(" to v%"Pd"\n", unallocated->vreg()));
+  TRACE_ALLOC(OS::Print(" to v%" Pd "\n", unallocated->vreg()));
 
   if (free_until != kMaxPosition) {
     // There was an intersection. Split unallocated.
-    TRACE_ALLOC(OS::Print("  splitting at %"Pd"\n", free_until));
+    TRACE_ALLOC(OS::Print("  splitting at %" Pd "\n", free_until));
     LiveRange* tail = unallocated->SplitAt(free_until);
     AddToUnallocated(tail);
   }
@@ -1985,7 +1987,7 @@
 
   TRACE_ALLOC(OS::Print("assigning blocked register "));
   TRACE_ALLOC(MakeRegisterLocation(candidate).Print());
-  TRACE_ALLOC(OS::Print(" to live range v%"Pd" until %"Pd"\n",
+  TRACE_ALLOC(OS::Print(" to live range v%" Pd " until %" Pd "\n",
                         unallocated->vreg(), blocked_at));
 
   if (blocked_at < unallocated->End()) {
@@ -2142,7 +2144,7 @@
   ASSERT(use->location_slot() != NULL);
   Location* slot = use->location_slot();
   ASSERT(slot->IsUnallocated());
-  TRACE_ALLOC(OS::Print("  use at %"Pd" converted to ", use->pos()));
+  TRACE_ALLOC(OS::Print("  use at %" Pd " converted to ", use->pos()));
   TRACE_ALLOC(loc.Print());
   TRACE_ALLOC(OS::Print("\n"));
   *slot = loc;
@@ -2155,8 +2157,8 @@
   const Location loc = range->assigned_location();
   ASSERT(!loc.IsInvalid());
 
-  TRACE_ALLOC(OS::Print("range [%"Pd", %"Pd") "
-                        "for v%"Pd" has been allocated to ",
+  TRACE_ALLOC(OS::Print("range [%" Pd ", %" Pd ") "
+                        "for v%" Pd " has been allocated to ",
                         range->Start(), range->End(), range->vreg()));
   TRACE_ALLOC(loc.Print());
   TRACE_ALLOC(OS::Print(":\n"));
@@ -2321,8 +2323,8 @@
   while (!unallocated_.is_empty()) {
     LiveRange* range = unallocated_.RemoveLast();
     const intptr_t start = range->Start();
-    TRACE_ALLOC(OS::Print("Processing live range for v%"Pd" "
-                          "starting at %"Pd"\n",
+    TRACE_ALLOC(OS::Print("Processing live range for v%" Pd " "
+                          "starting at %" Pd "\n",
                           range->vreg(),
                           start));
 
@@ -2358,13 +2360,13 @@
 void FlowGraphAllocator::ConnectSplitSiblings(LiveRange* parent,
                                               BlockEntryInstr* source_block,
                                               BlockEntryInstr* target_block) {
-  TRACE_ALLOC(OS::Print("Connect v%"Pd" on the edge B%"Pd" -> B%"Pd"\n",
+  TRACE_ALLOC(OS::Print("Connect v%" Pd " on the edge B%" Pd " -> B%" Pd "\n",
                         parent->vreg(),
                         source_block->block_id(),
                         target_block->block_id()));
   if (parent->next_sibling() == NULL) {
     // Nothing to connect. The whole range was allocated to the same location.
-    TRACE_ALLOC(OS::Print("range v%"Pd" has no siblings\n", parent->vreg()));
+    TRACE_ALLOC(OS::Print("range v%" Pd " has no siblings\n", parent->vreg()));
     return;
   }
 
@@ -2401,8 +2403,8 @@
     range = range->next_sibling();
   }
 
-  TRACE_ALLOC(OS::Print("connecting v%"Pd" between [%"Pd", %"Pd") {%s} "
-                        "to [%"Pd", %"Pd") {%s}\n",
+  TRACE_ALLOC(OS::Print("connecting v%" Pd " between [%" Pd ", %" Pd ") {%s} "
+                        "to [%" Pd ", %" Pd ") {%s}\n",
                         parent->vreg(),
                         source_cover->Start(),
                         source_cover->End(),
@@ -2438,10 +2440,10 @@
 
     while (range->next_sibling() != NULL) {
       LiveRange* sibling = range->next_sibling();
-      TRACE_ALLOC(OS::Print("connecting [%"Pd", %"Pd") [",
+      TRACE_ALLOC(OS::Print("connecting [%" Pd ", %" Pd ") [",
                             range->Start(), range->End()));
       TRACE_ALLOC(range->assigned_location().Print());
-      TRACE_ALLOC(OS::Print("] to [%"Pd", %"Pd") [",
+      TRACE_ALLOC(OS::Print("] to [%" Pd ", %" Pd ") [",
                             sibling->Start(), sibling->End()));
       TRACE_ALLOC(sibling->assigned_location().Print());
       TRACE_ALLOC(OS::Print("]\n"));
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index e818aa2..2ff3dc1 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -1879,7 +1879,7 @@
   ASSERT(value->definition()->temp_index() == temp_index() - 1);
   intptr_t index = GetCurrentTempLocalIndex();
   char name[64];
-  OS::SNPrint(name, 64, ":tmp_local%"Pd, index);
+  OS::SNPrint(name, 64, ":tmp_local%" Pd, index);
   LocalVariable*  var =
       new LocalVariable(0,
                         String::ZoneHandle(Symbols::New(name)),
@@ -2850,8 +2850,74 @@
 }
 
 
+static intptr_t OffsetForLengthGetter(MethodRecognizer::Kind kind) {
+  switch (kind) {
+    case MethodRecognizer::kObjectArrayLength:
+    case MethodRecognizer::kImmutableArrayLength:
+      return Array::length_offset();
+    case MethodRecognizer::kTypedDataLength:
+      // .length is defined in _TypedList which is the base class for internal
+      // and external typed data.
+      ASSERT(TypedData::length_offset() == ExternalTypedData::length_offset());
+      return TypedData::length_offset();
+    case MethodRecognizer::kGrowableArrayLength:
+      return GrowableObjectArray::length_offset();
+    default:
+      UNREACHABLE();
+      return 0;
+  }
+}
+
+
 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
+  const Function& function = owner()->parsed_function()->function();
+  if (!function.IsClosureFunction()) {
+    MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
+    switch (kind) {
+      case MethodRecognizer::kStringBaseLength: {
+        LocalVariable* receiver_var =
+            node->scope()->LookupVariable(Symbols::This(),
+                                          true);  // Test only.
+        Value* receiver = Bind(new LoadLocalInstr(*receiver_var));
+        // Treat length loads as mutable (i.e. affected by side effects) to
+        // avoid hoisting them since we can't hoist the preceding class-check.
+        // This is because of externalization of strings that affects their
+        // class-id.
+        const bool is_immutable = false;
+        LoadFieldInstr* load = new LoadFieldInstr(
+            receiver,
+            String::length_offset(),
+            Type::ZoneHandle(Type::SmiType()),
+            is_immutable);
+        load->set_result_cid(kSmiCid);
+        load->set_recognized_kind(MethodRecognizer::kStringBaseLength);
+        return ReturnDefinition(load);
+      }
+      case MethodRecognizer::kGrowableArrayLength:
+      case MethodRecognizer::kObjectArrayLength:
+      case MethodRecognizer::kImmutableArrayLength:
+      case MethodRecognizer::kTypedDataLength: {
+        LocalVariable* receiver_var =
+            node->scope()->LookupVariable(Symbols::This(),
+                                          true);  // Test only.
+        Value* receiver = Bind(new LoadLocalInstr(*receiver_var));
+        const bool is_immutable =
+            (kind != MethodRecognizer::kGrowableArrayLength);
+        LoadFieldInstr* load = new LoadFieldInstr(
+            receiver,
+            OffsetForLengthGetter(kind),
+            Type::ZoneHandle(Type::SmiType()),
+            is_immutable);
+        load->set_result_cid(kSmiCid);
+        load->set_recognized_kind(kind);
+        return ReturnDefinition(load);
+      }
+      default:
+        break;
+    }
+  }
   InlineBailout("EffectGraphVisitor::VisitNativeBodyNode");
+  function.set_is_optimizable(false);
   NativeCallInstr* native_call = new NativeCallInstr(node);
   ReturnDefinition(native_call);
 }
@@ -2938,6 +3004,12 @@
                                        dst_name);
   }
 
+  if (!node->field().is_final()) {
+    // For now, disable list length guarding on non-final fields by specifying
+    // that the field doesn't have a length. See issue #12485.
+    node->field().set_guarded_list_length(Field::kNoFixedLength);
+  }
+
   store_value = Bind(BuildStoreExprTemp(store_value));
   GuardFieldInstr* guard =
       new GuardFieldInstr(store_value,
@@ -3210,10 +3282,8 @@
       // memory leaks.
       // In this case, the parser pre-allocates a variable to save the context.
       if (MustSaveRestoreContext(node)) {
-        Value* current_context = Bind(new CurrentContextInstr());
-        Do(BuildStoreTemp(
-            *owner()->parsed_function()->saved_entry_context_var(),
-            current_context));
+        BuildSaveContext(
+            *owner()->parsed_function()->saved_entry_context_var());
         Value* null_context = Bind(new ConstantInstr(Object::ZoneHandle()));
         AddInstruction(new StoreContextInstr(null_context));
       }
@@ -3630,11 +3700,14 @@
   graph_entry_ = new GraphEntryInstr(*parsed_function(), normal_entry, osr_id_);
   EffectGraphVisitor for_effect(this, 0);
   // This check may be deleted if the generated code is leaf.
-  CheckStackOverflowInstr* check =
-      new CheckStackOverflowInstr(function.token_pos(), 0);
-  // If we are inlining don't actually attach the stack check. We must still
-  // create the stack check in order to allocate a deopt id.
-  if (!IsInlining()) for_effect.AddInstruction(check);
+  // Native functions don't need a stack check at entry.
+  if (!function.is_native()) {
+    CheckStackOverflowInstr* check =
+        new CheckStackOverflowInstr(function.token_pos(), 0);
+    // If we are inlining don't actually attach the stack check. We must still
+    // create the stack check in order to allocate a deopt id.
+    if (!IsInlining()) for_effect.AddInstruction(check);
+  }
   parsed_function()->node_sequence()->Visit(&for_effect);
   AppendFragment(normal_entry, for_effect);
   // Check that the graph is properly terminated.
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 4df5137..13516a1 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -152,7 +152,6 @@
   if (is_leaf) {
     // Remove the stack overflow check at function entry.
     Instruction* first = flow_graph_.graph_entry()->normal_entry()->next();
-    ASSERT(first->IsCheckStackOverflow());
     if (first->IsCheckStackOverflow()) first->RemoveFromGraph();
   }
 }
@@ -226,7 +225,7 @@
   for (intptr_t i = 0; i < block_order().length(); ++i) {
     // Compile the block entry.
     BlockEntryInstr* entry = block_order()[i];
-    assembler()->Comment("B%"Pd"", entry->block_id());
+    assembler()->Comment("B%" Pd "", entry->block_id());
     set_current_block(entry);
 
     if (WasCompacted(entry)) {
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 2dc5f64..c155fe3 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -150,7 +150,7 @@
   ASSERT(reason() != kDeoptAtCall);
   Assembler* assem = compiler->assembler();
 #define __ assem->
-  __ Comment("Deopt stub for id %"Pd"", deopt_id());
+  __ Comment("Deopt stub for id %" Pd "", deopt_id());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) __ bkpt(0);
 
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index e2a7bc8..924ade9 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -148,7 +148,7 @@
   ASSERT(reason() != kDeoptAtCall);
   Assembler* assem = compiler->assembler();
 #define __ assem->
-  __ Comment("Deopt stub for id %"Pd"", deopt_id());
+  __ Comment("Deopt stub for id %" Pd "", deopt_id());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) __ int3();
 
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 98527cf..49e8c3a 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -150,7 +150,7 @@
   ASSERT(reason() != kDeoptAtCall);
   Assembler* assem = compiler->assembler();
 #define __ assem->
-  __ Comment("Deopt stub for id %"Pd"", deopt_id());
+  __ Comment("Deopt stub for id %" Pd "", deopt_id());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) __ break_(0);
 
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index f07d491..398fe3a 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -145,7 +145,7 @@
   ASSERT(reason() != kDeoptAtCall);
   Assembler* assem = compiler->assembler();
 #define __ assem->
-  __ Comment("Deopt stub for id %"Pd"", deopt_id());
+  __ Comment("Deopt stub for id %" Pd "", deopt_id());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) __ int3();
 
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 247b0fe..15e6df8 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -165,9 +165,11 @@
            !it.Done();
            it.Advance()) {
         ++instruction_count_;
-        if (it.Current()->IsStaticCall() ||
-            it.Current()->IsClosureCall() ||
-            it.Current()->IsPolymorphicInstanceCall()) {
+        Instruction* current = it.Current();
+        if (current->IsStaticCall() ||
+            current->IsClosureCall() ||
+            (current->IsPolymorphicInstanceCall() &&
+             !current->AsPolymorphicInstanceCall()->HasRecognizedTarget())) {
           ++call_site_count_;
         }
       }
@@ -184,11 +186,10 @@
 
 
 // A collection of call sites to consider for inlining.
-class CallSites : public FlowGraphVisitor {
+class CallSites : public ValueObject {
  public:
   explicit CallSites(FlowGraph* flow_graph)
-      : FlowGraphVisitor(flow_graph->postorder()),  // We don't use this order.
-        static_calls_(),
+      : static_calls_(),
         closure_calls_(),
         instance_calls_() { }
 
@@ -269,8 +270,15 @@
     }
   }
 
-  void FindCallSites(FlowGraph* graph) {
+  void FindCallSites(FlowGraph* graph, intptr_t depth) {
     ASSERT(graph != NULL);
+    // If depth is less than the threshold recursively add call sites.
+    if (depth > FLAG_inlining_depth_threshold) return;
+
+    // Recognized methods are not treated as normal calls. They don't have
+    // calls in themselves, so we keep adding those even when at the threshold.
+    const bool only_recognized_methods =
+        (depth == FLAG_inlining_depth_threshold);
 
     const intptr_t instance_call_start_ix = instance_calls_.length();
     const intptr_t static_call_start_ix = static_calls_.length();
@@ -280,25 +288,39 @@
       for (ForwardInstructionIterator it(block_it.Current());
            !it.Done();
            it.Advance()) {
-        it.Current()->Accept(this);
+        Instruction* current = it.Current();
+        if (only_recognized_methods) {
+          PolymorphicInstanceCallInstr* instance_call =
+              current->AsPolymorphicInstanceCall();
+          if ((instance_call != NULL) && instance_call->HasRecognizedTarget()) {
+            instance_calls_.Add(InstanceCallInfo(instance_call));
+          }
+          continue;
+        }
+        // Collect all call sites (!only_recognized_methods).
+        ClosureCallInstr* closure_call = current->AsClosureCall();
+        if (closure_call != NULL) {
+          closure_calls_.Add(closure_call);
+          continue;
+        }
+        StaticCallInstr* static_call = current->AsStaticCall();
+        if (static_call != NULL) {
+          if (static_call->function().IsInlineable()) {
+            static_calls_.Add(StaticCallInfo(static_call));
+          }
+          continue;
+        }
+        PolymorphicInstanceCallInstr* instance_call =
+            current->AsPolymorphicInstanceCall();
+        if (instance_call != NULL) {
+          instance_calls_.Add(InstanceCallInfo(instance_call));
+          continue;
+        }
       }
     }
     ComputeCallSiteRatio(static_call_start_ix, instance_call_start_ix);
   }
 
-  void VisitClosureCall(ClosureCallInstr* call) {
-    closure_calls_.Add(call);
-  }
-
-  void VisitPolymorphicInstanceCall(PolymorphicInstanceCallInstr* call) {
-    instance_calls_.Add(InstanceCallInfo(call));
-  }
-
-  void VisitStaticCall(StaticCallInstr* call) {
-    if (!call->function().IsInlineable()) return;
-    static_calls_.Add(StaticCallInfo(call));
-  }
-
  private:
   GrowableArray<StaticCallInfo> static_calls_;
   GrowableArray<ClosureCallInstr*> closure_calls_;
@@ -394,8 +416,6 @@
     return false;
   }
 
-  // TODO(srdjan): Handle large 'skip_static_call_deopt_ids'. Currently
-  // max. size observed is 11 (dart2js).
   void InlineCalls() {
     // If inlining depth is less then one abort.
     if (FLAG_inlining_depth_threshold < 1) return;
@@ -410,9 +430,10 @@
     collected_call_sites_ = &sites1;
     inlining_call_sites_ = &sites2;
     // Collect initial call sites.
-    collected_call_sites_->FindCallSites(caller_graph_);
+    collected_call_sites_->FindCallSites(caller_graph_, inlining_depth_);
     while (collected_call_sites_->HasCalls()) {
-      TRACE_INLINING(OS::Print("  Depth %"Pd" ----------\n", inlining_depth_));
+      TRACE_INLINING(OS::Print("  Depth %" Pd " ----------\n",
+                               inlining_depth_));
       // Swap collected and inlining arrays and clear the new collecting array.
       call_sites_temp = collected_call_sites_;
       collected_call_sites_ = inlining_call_sites_;
@@ -471,9 +492,9 @@
                         function.optimized_call_site_count(),
                         constant_arguments)) {
       TRACE_INLINING(OS::Print("     Bailout: early heuristics with "
-                               "code size:  %"Pd", "
-                               "call sites: %"Pd", "
-                               "const args: %"Pd"\n",
+                               "code size:  %" Pd ", "
+                               "call sites: %" Pd ", "
+                               "const args: %" Pd "\n",
                                function.optimized_instruction_count(),
                                function.optimized_call_site_count(),
                                constant_arguments));
@@ -489,7 +510,8 @@
     }
 
     // Abort if the callee has an intrinsic translation.
-    if (Intrinsifier::CanIntrinsify(function)) {
+    if (Intrinsifier::CanIntrinsify(function) &&
+        !function.is_optimizable()) {
       function.set_is_inlinable(false);
       TRACE_INLINING(OS::Print("     Bailout: can intrinsify\n"));
       return false;
@@ -623,19 +645,16 @@
         isolate->set_long_jump_base(base);
         isolate->set_deopt_id(prev_deopt_id);
         TRACE_INLINING(OS::Print("     Bailout: heuristics with "
-                                 "code size:  %"Pd", "
-                                 "call sites: %"Pd", "
-                                 "const args: %"Pd"\n",
+                                 "code size:  %" Pd ", "
+                                 "call sites: %" Pd ", "
+                                 "const args: %" Pd "\n",
                                  size,
                                  call_site_count,
                                  constants_count));
         return false;
       }
 
-      // If depth is less or equal to threshold recursively add call sites.
-      if (inlining_depth_ < FLAG_inlining_depth_threshold) {
-        collected_call_sites_->FindCallSites(callee_graph);
-      }
+      collected_call_sites_->FindCallSites(callee_graph, inlining_depth_);
 
       // Add the function to the cache.
       if (!in_cache) function_cache_.Add(parsed_function);
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 84879f5..8affac2 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -303,7 +303,7 @@
     EnsureSSATempIndex(graph, current_defn, replacement_defn);
 
     if (FLAG_trace_optimization) {
-      OS::Print("Replacing v%"Pd" with v%"Pd"\n",
+      OS::Print("Replacing v%" Pd " with v%" Pd "\n",
                 current_defn->ssa_temp_index(),
                 replacement_defn->ssa_temp_index());
     }
@@ -312,7 +312,7 @@
       OS::Print("Removing %s\n", current->DebugName());
     } else {
       ASSERT(!current_defn->HasUses());
-      OS::Print("Removing v%"Pd".\n", current_defn->ssa_temp_index());
+      OS::Print("Removing v%" Pd ".\n", current_defn->ssa_temp_index());
     }
   }
   iterator->RemoveCurrentFromGraph();
@@ -1083,6 +1083,8 @@
         operands_type = kDoubleCid;
       } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) {
         operands_type = kFloat32x4Cid;
+      } else if (HasOnlyTwoOf(ic_data, kUint32x4Cid)) {
+        operands_type = kUint32x4Cid;
       } else {
         return false;
       }
@@ -1388,23 +1390,6 @@
 }
 
 
-void FlowGraphOptimizer::InlineArrayLengthGetter(InstanceCallInstr* call,
-                                                 intptr_t length_offset,
-                                                 bool is_immutable,
-                                                 MethodRecognizer::Kind kind) {
-  AddReceiverCheck(call);
-
-  LoadFieldInstr* load = new LoadFieldInstr(
-      new Value(call->ArgumentAt(0)),
-      length_offset,
-      Type::ZoneHandle(Type::SmiType()),
-      is_immutable);
-  load->set_result_cid(kSmiCid);
-  load->set_recognized_kind(kind);
-  ReplaceCall(call, load);
-}
-
-
 void FlowGraphOptimizer::InlineGrowableArrayCapacityGetter(
     InstanceCallInstr* call) {
   AddReceiverCheck(call);
@@ -1444,13 +1429,6 @@
 }
 
 
-void FlowGraphOptimizer::InlineStringLengthGetter(InstanceCallInstr* call) {
-  AddReceiverCheck(call);
-  LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0));
-  ReplaceCall(call, load);
-}
-
-
 void FlowGraphOptimizer::InlineStringIsEmptyGetter(InstanceCallInstr* call) {
   AddReceiverCheck(call);
 
@@ -1473,25 +1451,6 @@
 }
 
 
-static intptr_t OffsetForLengthGetter(MethodRecognizer::Kind kind) {
-  switch (kind) {
-    case MethodRecognizer::kObjectArrayLength:
-    case MethodRecognizer::kImmutableArrayLength:
-      return Array::length_offset();
-    case MethodRecognizer::kTypedDataLength:
-      // .length is defined in _TypedList which is the base class for internal
-      // and external typed data.
-      ASSERT(TypedData::length_offset() == ExternalTypedData::length_offset());
-      return TypedData::length_offset();
-    case MethodRecognizer::kGrowableArrayLength:
-      return GrowableObjectArray::length_offset();
-    default:
-      UNREACHABLE();
-      return 0;
-  }
-}
-
-
 bool FlowGraphOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call,
                                                MethodRecognizer::Kind getter) {
   if (!ShouldInlineSimd()) {
@@ -1505,8 +1464,8 @@
                 call);
   intptr_t mask = 0;
   if (getter == MethodRecognizer::kFloat32x4Shuffle) {
-    ASSERT(call->ArgumentCount() == 2);
     // Extract shuffle mask.
+    ASSERT(call->ArgumentCount() == 2);
     Definition* mask_definition = call->ArgumentAt(1);
     if (!mask_definition->IsConstant()) {
       // Not a constant.
@@ -1526,13 +1485,29 @@
       return false;
     }
   }
-  Float32x4ShuffleInstr* instr = new Float32x4ShuffleInstr(
-      getter,
-      new Value(call->ArgumentAt(0)),
-      mask,
-      call->deopt_id());
-  ReplaceCall(call, instr);
-  return true;
+  if (getter == MethodRecognizer::kFloat32x4GetSignMask) {
+    Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr(
+        getter,
+        new Value(call->ArgumentAt(0)),
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  } else {
+    ASSERT((getter == MethodRecognizer::kFloat32x4Shuffle)  ||
+           (getter == MethodRecognizer::kFloat32x4ShuffleX) ||
+           (getter == MethodRecognizer::kFloat32x4ShuffleY) ||
+           (getter == MethodRecognizer::kFloat32x4ShuffleZ) ||
+           (getter == MethodRecognizer::kFloat32x4ShuffleW));
+    Float32x4ShuffleInstr* instr = new Float32x4ShuffleInstr(
+        getter,
+        new Value(call->ArgumentAt(0)),
+        mask,
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  }
+  UNREACHABLE();
+  return false;
 }
 
 
@@ -1547,12 +1522,21 @@
                 call->deopt_id(),
                 call->env(),
                 call);
-  Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr(
-      getter,
-      new Value(call->ArgumentAt(0)),
-      call->deopt_id());
-  ReplaceCall(call, instr);
-  return true;
+  if (getter == MethodRecognizer::kUint32x4GetSignMask) {
+    Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr(
+        getter,
+        new Value(call->ArgumentAt(0)),
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  } else {
+    Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr(
+        getter,
+        new Value(call->ArgumentAt(0)),
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  }
 }
 
 
@@ -1651,34 +1635,9 @@
       InlineObjectCid(call);
       return true;
     }
-    case MethodRecognizer::kObjectArrayLength:
-    case MethodRecognizer::kImmutableArrayLength:
-    case MethodRecognizer::kTypedDataLength:
-    case MethodRecognizer::kGrowableArrayLength: {
-      if (!ic_data.HasOneTarget()) {
-        // TODO(srdjan): Implement for mutiple targets.
-        return false;
-      }
-      const bool is_immutable =
-          (recognized_kind == MethodRecognizer::kObjectArrayLength) ||
-          (recognized_kind == MethodRecognizer::kImmutableArrayLength) ||
-          (recognized_kind == MethodRecognizer::kTypedDataLength);
-      InlineArrayLengthGetter(call,
-                              OffsetForLengthGetter(recognized_kind),
-                              is_immutable,
-                              recognized_kind);
-      return true;
-    }
     case MethodRecognizer::kGrowableArrayCapacity:
       InlineGrowableArrayCapacityGetter(call);
       return true;
-    case MethodRecognizer::kStringBaseLength:
-      if (!ic_data.HasOneTarget()) {
-        // Target is not only StringBase_get_length.
-        return false;
-      }
-      InlineStringLengthGetter(call);
-      return true;
     case MethodRecognizer::kStringBaseIsEmpty:
       if (!ic_data.HasOneTarget()) {
         // Target is not only StringBase_get_isEmpty.
@@ -1690,6 +1649,7 @@
     case MethodRecognizer::kFloat32x4ShuffleY:
     case MethodRecognizer::kFloat32x4ShuffleZ:
     case MethodRecognizer::kFloat32x4ShuffleW:
+    case MethodRecognizer::kFloat32x4GetSignMask:
       if (!ic_data.HasReceiverClassId(kFloat32x4Cid) ||
           !ic_data.HasOneTarget()) {
         return false;
@@ -1698,7 +1658,8 @@
     case MethodRecognizer::kUint32x4GetFlagX:
     case MethodRecognizer::kUint32x4GetFlagY:
     case MethodRecognizer::kUint32x4GetFlagZ:
-    case MethodRecognizer::kUint32x4GetFlagW: {
+    case MethodRecognizer::kUint32x4GetFlagW:
+    case MethodRecognizer::kUint32x4GetSignMask: {
       if (!ic_data.HasReceiverClassId(kUint32x4Cid) ||
           !ic_data.HasOneTarget()) {
         return false;
@@ -1706,7 +1667,7 @@
       return InlineUint32x4Getter(call, recognized_kind);
     }
     default:
-      ASSERT(recognized_kind == MethodRecognizer::kUnknown);
+      break;
   }
   return false;
 }
@@ -1761,7 +1722,7 @@
     args->Add(new Value(call->ArgumentAt(i)));
   }
   InvokeMathCFunctionInstr* invoke =
-      new InvokeMathCFunctionInstr(args, call, recognized_kind);
+      new InvokeMathCFunctionInstr(args, call->deopt_id(), recognized_kind);
   ReplaceCall(call, invoke);
 }
 
@@ -1900,7 +1861,6 @@
         return true;
       }
       case MethodRecognizer::kDoubleMod:
-      case MethodRecognizer::kDoublePow:
       case MethodRecognizer::kDoubleRound:
         ReplaceWithMathCFunction(call, recognized_kind);
         return true;
@@ -2808,6 +2768,18 @@
         ReplaceCall(call, min_max);
       }
     }
+  } else if (recognized_kind == MethodRecognizer::kMathDoublePow) {
+    // We know that first argument is double, the second is num.
+    // InvokeMathCFunctionInstr requires unboxed doubles. UnboxDouble
+    // instructions contain type checks and conversions to double.
+    ZoneGrowableArray<Value*>* args =
+        new ZoneGrowableArray<Value*>(call->ArgumentCount());
+    for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
+      args->Add(new Value(call->ArgumentAt(i)));
+    }
+    InvokeMathCFunctionInstr* invoke =
+        new InvokeMathCFunctionInstr(args, call->deopt_id(), recognized_kind);
+    ReplaceCall(call, invoke);
   }
 }
 
@@ -3823,7 +3795,7 @@
   // TODO(fschneider): Avoid repeated deoptimization when
   // speculatively hoisting checks.
   if (FLAG_trace_optimization) {
-    OS::Print("Hoisting instruction %s:%"Pd" from B%"Pd" to B%"Pd"\n",
+    OS::Print("Hoisting instruction %s:%" Pd " from B%" Pd " to B%" Pd "\n",
               current->DebugName(),
               current->GetDeoptId(),
               current->GetBlock()->block_id(),
@@ -4172,17 +4144,18 @@
           return field_name;
         }
         return Isolate::Current()->current_zone()->PrintToString(
-            "<v%"Pd".%s>", instance()->ssa_temp_index(), field_name);
+            "<v%" Pd ".%s>", instance()->ssa_temp_index(), field_name);
       }
 
       case kVMField: {
         return Isolate::Current()->current_zone()->PrintToString(
-            "<v%"Pd"@%"Pd">", instance()->ssa_temp_index(), offset_in_bytes());
+            "<v%" Pd "@%" Pd ">",
+            instance()->ssa_temp_index(), offset_in_bytes());
       }
 
       case kIndexed: {
         return Isolate::Current()->current_zone()->PrintToString(
-            "<v%"Pd"[v%"Pd"]>",
+            "<v%" Pd "[v%" Pd "]>",
             instance()->ssa_temp_index(),
             index()->ssa_temp_index());
       }
@@ -4637,7 +4610,7 @@
           map->Insert(result);
           places->Add(result);
           if (FLAG_trace_optimization) {
-            OS::Print("  adding place %s as %"Pd"\n",
+            OS::Print("  adding place %s as %" Pd "\n",
                       result->ToCString(),
                       result->id());
           }
@@ -4683,7 +4656,7 @@
         places->Add(result);
 
         if (FLAG_trace_optimization) {
-          OS::Print("numbering %s as %"Pd"\n",
+          OS::Print("numbering %s as %" Pd "\n",
                     result->ToCString(),
                     result->id());
         }
@@ -4929,7 +4902,7 @@
           Definition* replacement = (*out_values)[place_id];
           EnsureSSATempIndex(graph_, defn, replacement);
           if (FLAG_trace_optimization) {
-            OS::Print("Replacing load v%"Pd" with v%"Pd"\n",
+            OS::Print("Replacing load v%" Pd " with v%" Pd "\n",
                       defn->ssa_temp_index(),
                       replacement->ssa_temp_index());
           }
@@ -5139,7 +5112,7 @@
       }
 
       if (FLAG_trace_load_optimization) {
-        OS::Print("B%"Pd"\n", block->block_id());
+        OS::Print("B%" Pd "\n", block->block_id());
         OS::Print("  IN: ");
         aliased_set_->PrintSet(in_[preorder_number]);
         OS::Print("\n");
@@ -5203,7 +5176,7 @@
 
       if (FLAG_trace_optimization) {
         for (BitVector::Iterator it(loop_gen); !it.Done(); it.Advance()) {
-          OS::Print("place %s is loop invariant for B%"Pd"\n",
+          OS::Print("place %s is loop invariant for B%" Pd "\n",
                     aliased_set_->places()[it.Current()]->ToCString(),
                     header->block_id());
         }
@@ -5274,7 +5247,7 @@
     phis_.Add(phi);  // Postpone phi insertion until after load forwarding.
 
     if (FLAG_trace_load_optimization) {
-      OS::Print("created pending phi %s for %s at B%"Pd"\n",
+      OS::Print("created pending phi %s for %s at B%" Pd "\n",
                 phi->ToCString(),
                 aliased_set_->places()[place_id]->ToCString(),
                 block->block_id());
@@ -5313,7 +5286,7 @@
           EnsureSSATempIndex(graph_, load, replacement);
 
           if (FLAG_trace_optimization) {
-            OS::Print("Replacing load v%"Pd" with v%"Pd"\n",
+            OS::Print("Replacing load v%" Pd " with v%" Pd "\n",
                       load->ssa_temp_index(),
                       replacement->ssa_temp_index());
           }
@@ -6510,6 +6483,12 @@
 }
 
 
+void ConstantPropagator::VisitSimd32x4GetSignMask(
+    Simd32x4GetSignMaskInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
+
 void ConstantPropagator::VisitFloat32x4Zero(Float32x4ZeroInstr* instr) {
   SetValue(instr, non_constant_);
 }
@@ -6561,6 +6540,7 @@
   SetValue(instr, non_constant_);
 }
 
+
 void ConstantPropagator::VisitFloat32x4TwoArgShuffle(
     Float32x4TwoArgShuffleInstr* instr) {
   SetValue(instr, non_constant_);
@@ -6771,7 +6751,7 @@
     JoinEntryInstr* join = block->AsJoinEntry();
     if (!reachable_->Contains(block->preorder_number())) {
       if (FLAG_trace_constant_propagation) {
-        OS::Print("Unreachable B%"Pd"\n", block->block_id());
+        OS::Print("Unreachable B%" Pd "\n", block->block_id());
       }
       // Remove all uses in unreachable blocks.
       if (join != NULL) {
@@ -6851,7 +6831,7 @@
           !defn->IsStoreStaticField() &&
           !defn->IsStoreVMField()) {
         if (FLAG_trace_constant_propagation) {
-          OS::Print("Constant v%"Pd" = %s\n",
+          OS::Print("Constant v%" Pd " = %s\n",
                     defn->ssa_temp_index(),
                     defn->constant_value().ToCString());
         }
@@ -7321,7 +7301,7 @@
   ASSERT(IsAllocationSinkingCandidate(alloc));
 
   if (FLAG_trace_optimization) {
-    OS::Print("removing allocation from the graph: v%"Pd"\n",
+    OS::Print("removing allocation from the graph: v%" Pd "\n",
               alloc->ssa_temp_index());
   }
 
@@ -7360,7 +7340,7 @@
       AllocateObjectInstr* alloc = it.Current()->AsAllocateObject();
       if ((alloc != NULL) && IsAllocationSinkingCandidate(alloc)) {
         if (FLAG_trace_optimization) {
-          OS::Print("discovered allocation sinking candidate: v%"Pd"\n",
+          OS::Print("discovered allocation sinking candidate: v%" Pd "\n",
                     alloc->ssa_temp_index());
         }
 
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index d92ee29..117ea99 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -156,12 +156,7 @@
   bool InlineUint32x4BinaryOp(InstanceCallInstr* call,
                               Token::Kind op_kind);
   void InlineImplicitInstanceGetter(InstanceCallInstr* call);
-  void InlineArrayLengthGetter(InstanceCallInstr* call,
-                               intptr_t length_offset,
-                               bool is_immutable,
-                               MethodRecognizer::Kind kind);
   void InlineGrowableArrayCapacityGetter(InstanceCallInstr* call);
-  void InlineStringLengthGetter(InstanceCallInstr* call);
   void InlineStringIsEmptyGetter(InstanceCallInstr* call);
   void InlineObjectCid(InstanceCallInstr* call);
 
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 41e83b6..2ea65ba 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -65,7 +65,7 @@
   while (!worklist_.is_empty()) {
     Definition* def = RemoveLastFromWorklist();
     if (FLAG_trace_type_propagation) {
-      OS::Print("recomputing type of v%"Pd": %s\n",
+      OS::Print("recomputing type of v%" Pd ": %s\n",
                 def->ssa_temp_index(),
                 def->Type()->ToCString());
     }
@@ -234,7 +234,7 @@
   value->SetReachingType(type);
 
   if (FLAG_trace_type_propagation) {
-    OS::Print("reaching type to v%"Pd" for v%"Pd" is %s\n",
+    OS::Print("reaching type to v%" Pd " for v%" Pd " is %s\n",
               value->instruction()->IsDefinition() ?
                   value->instruction()->AsDefinition()->ssa_temp_index() : -1,
               value->definition()->ssa_temp_index(),
@@ -646,7 +646,7 @@
   CompileType result = CompileType::None();
   for (intptr_t i = 0; i < InputCount(); i++) {
     if (FLAG_trace_type_propagation) {
-      OS::Print("  phi %"Pd" input %"Pd": v%"Pd" has reaching type %s\n",
+      OS::Print("  phi %" Pd " input %" Pd ": v%" Pd " has reaching type %s\n",
                 ssa_temp_index(),
                 i,
                 InputAt(i)->definition()->ssa_temp_index(),
@@ -1044,6 +1044,11 @@
 }
 
 
+CompileType Simd32x4GetSignMaskInstr::ComputeType() const {
+  return CompileType::Int();
+}
+
+
 CompileType Float32x4ConstructorInstr::ComputeType() const {
   return CompileType::FromCid(kFloat32x4Cid);
 }
@@ -1108,6 +1113,7 @@
   return CompileType::FromCid(kUint32x4Cid);
 }
 
+
 CompileType Uint32x4GetFlagInstr::ComputeType() const {
   return CompileType::FromCid(kBoolCid);
 }
diff --git a/runtime/vm/freelist.cc b/runtime/vm/freelist.cc
index bbd1bea..54f2bdd 100644
--- a/runtime/vm/freelist.cc
+++ b/runtime/vm/freelist.cc
@@ -163,7 +163,7 @@
     intptr_t list_bytes = list_length * i * kObjectAlignment;
     small_bytes += list_bytes;
     OS::Print("small %3d [%8d bytes] : "
-              "%8"Pd" objs; %8.1f KB; %8.1f cum KB\n",
+              "%8" Pd " objs; %8.1f KB; %8.1f cum KB\n",
               i,
               i * kObjectAlignment,
               list_length,
@@ -195,8 +195,8 @@
     intptr_t list_length = it->second;
     intptr_t list_bytes = list_length * size;
     large_bytes += list_bytes;
-    OS::Print("large %3"Pd" [%8"Pd" bytes] : "
-              "%8"Pd" objs; %8.1f KB; %8.1f cum KB\n",
+    OS::Print("large %3" Pd " [%8" Pd " bytes] : "
+              "%8" Pd " objs; %8.1f KB; %8.1f cum KB\n",
               size / kObjectAlignment,
               size,
               list_length,
diff --git a/runtime/vm/handles.cc b/runtime/vm/handles.cc
index 66f87e6..a7564db 100644
--- a/runtime/vm/handles.cc
+++ b/runtime/vm/handles.cc
@@ -25,10 +25,11 @@
 VMHandles::~VMHandles() {
 #ifdef DEBUG
     if (FLAG_trace_handles) {
-      OS::PrintErr("***   Handle Counts for 0x(%"Px"):Zone = %d,Scoped = %d\n",
+      OS::PrintErr("***   Handle Counts for 0x(%" Px
+                   "):Zone = %d,Scoped = %d\n",
                    reinterpret_cast<intptr_t>(this),
                    CountZoneHandles(), CountScopedHandles());
-      OS::PrintErr("*** Deleting VM handle block 0x%"Px"\n",
+      OS::PrintErr("*** Deleting VM handle block 0x%" Px "\n",
                    reinterpret_cast<intptr_t>(this));
     }
 #endif
diff --git a/runtime/vm/handles.h b/runtime/vm/handles.h
index be1133b..612682c 100644
--- a/runtime/vm/handles.h
+++ b/runtime/vm/handles.h
@@ -251,7 +251,7 @@
                         kOffsetOfRawPtr>() {
 #ifdef DEBUG
     if (FLAG_trace_handles) {
-      OS::PrintErr("*** Starting a new VM handle block 0x%"Px"\n",
+      OS::PrintErr("*** Starting a new VM handle block 0x%" Px "\n",
                    reinterpret_cast<intptr_t>(this));
     }
 #endif
diff --git a/runtime/vm/handles_impl.h b/runtime/vm/handles_impl.h
index 7f21c32..a40a671 100644
--- a/runtime/vm/handles_impl.h
+++ b/runtime/vm/handles_impl.h
@@ -176,7 +176,7 @@
              kOffsetOfRawPtr>::SetupNextScopeBlock() {
 #if defined(DEBUG)
   if (FLAG_trace_handles) {
-    OS::PrintErr("***   Handle Counts for (0x%"Px"):Zone = %d,Scoped = %d\n",
+    OS::PrintErr("***   Handle Counts for (0x%" Px "):Zone = %d,Scoped = %d\n",
                  reinterpret_cast<intptr_t>(this),
                  CountZoneHandles(), CountScopedHandles());
   }
@@ -231,7 +231,7 @@
              kOffsetOfRawPtr>::SetupNextZoneBlock() {
 #if defined(DEBUG)
   if (FLAG_trace_handles) {
-    OS::PrintErr("***   Handle Counts for (0x%"Px"):Zone = %d,Scoped = %d\n",
+    OS::PrintErr("***   Handle Counts for (0x%" Px "):Zone = %d,Scoped = %d\n",
                  reinterpret_cast<intptr_t>(this),
                  CountZoneHandles(), CountScopedHandles());
   }
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 851f6a6..8f6633c 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -84,7 +84,7 @@
     CollectAllGarbage();
     addr = old_space_->TryAllocate(size, type, PageSpace::kForceGrowth);
     if (addr == 0) {
-      OS::PrintErr("Exhausted heap space, trying to allocate %"Pd" bytes.\n",
+      OS::PrintErr("Exhausted heap space, trying to allocate %" Pd " bytes.\n",
                    size);
       return 0;
     }
@@ -296,8 +296,8 @@
 
 
 void Heap::PrintSizes() const {
-  OS::PrintErr("New space (%"Pd"k of %"Pd"k) "
-               "Old space (%"Pd"k of %"Pd"k)\n",
+  OS::PrintErr("New space (%" Pd "k of %" Pd "k) "
+               "Old space (%" Pd "k of %" Pd "k)\n",
                (Used(kNew) / KB), (Capacity(kNew) / KB),
                (Used(kOld) / KB), (Capacity(kOld) / KB));
 }
@@ -467,14 +467,16 @@
 
   const char* space_str = stats_.space_ == kNew ? "Scavenge" : "Mark-Sweep";
   OS::PrintErr(
-    "[ GC(%"Pd64"): %s(%s), "  // GC(isolate), space(reason)
-    "%"Pd", "  // count
+    "[ GC(%" Pd64 "): %s(%s), "  // GC(isolate), space(reason)
+    "%" Pd ", "  // count
     "%.3f, "  // start time
     "%.3f, "  // total time
-    "%"Pd", %"Pd", %"Pd", %"Pd", "  // new gen: in use, capacity before/after
-    "%"Pd", %"Pd", %"Pd", %"Pd", "  // old gen: in use, capacity before/after
+    "%" Pd ", %" Pd ", "  // new gen: in use before/after
+    "%" Pd ", %" Pd ", "  // new gen: capacity before/after
+    "%" Pd ", %" Pd ", "  // old gen: in use before/after
+    "%" Pd ", %" Pd ", "  // old gen: capacity before/after
     "%.3f, %.3f, %.3f, %.3f, "  // times
-    "%"Pd", %"Pd", %"Pd", %"Pd", "  // data
+    "%" Pd ", %" Pd ", %" Pd ", %" Pd ", "  // data
     "]\n",  // End with a comma to make it easier to import in spreadsheets.
     isolate->main_port(), space_str, GCReasonToString(stats_.reason_),
     stats_.num_,
diff --git a/runtime/vm/heap_histogram.cc b/runtime/vm/heap_histogram.cc
index bfd7e61..0ea4139 100644
--- a/runtime/vm/heap_histogram.cc
+++ b/runtime/vm/heap_histogram.cc
@@ -124,7 +124,7 @@
       cls = isolate_->class_table()->At(e->class_id_);
       str = cls.Name();
       lib = cls.library();
-      OS::Print("%9"Pd" %7"Pd" ",
+      OS::Print("%9" Pd " %7" Pd " ",
                 e->size_ / major_gc_count_,
                 e->count_ / major_gc_count_);
       if (e->class_id_ < kInstanceCid) {
diff --git a/runtime/vm/heap_profiler.cc b/runtime/vm/heap_profiler.cc
index 174a61a..bdfdd83 100644
--- a/runtime/vm/heap_profiler.cc
+++ b/runtime/vm/heap_profiler.cc
@@ -784,7 +784,7 @@
       uword obj_addr = RawObject::ToAddr(raw_obj);
       if (!Isolate::Current()->heap()->Contains(obj_addr) &&
           !Dart::vm_isolate()->heap()->Contains(obj_addr)) {
-        FATAL1("Invalid object pointer encountered %#"Px"\n", obj_addr);
+        FATAL1("Invalid object pointer encountered %#" Px "\n", obj_addr);
       }
     }
     profiler_->WriteRoot(raw_obj);
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index 2aab9ba..715b695 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -83,7 +83,7 @@
     instr->locs()->PrintTo(&f);
   }
   if (instr->lifetime_position() != -1) {
-    OS::Print("%3"Pd": ", instr->lifetime_position());
+    OS::Print("%3" Pd ": ", instr->lifetime_position());
   }
   if (!instr->IsBlockEntry()) OS::Print("    ");
   OS::Print("%s", str);
@@ -133,7 +133,7 @@
 
 
 static void PrintICData(BufferFormatter* f, const ICData& ic_data) {
-  f->Print(" IC[%"Pd": ", ic_data.NumberOfChecks());
+  f->Print(" IC[%" Pd ": ", ic_data.NumberOfChecks());
   Function& target = Function::Handle();
   for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
     GrowableArray<intptr_t> class_ids;
@@ -151,7 +151,7 @@
       f->Print("%s", String::Handle(cls.Name()).ToCString());
     }
     if (count > 0) {
-      f->Print(" #%"Pd, count);
+      f->Print(" #%" Pd, count);
     }
     f->Print(" <%p>", static_cast<void*>(target.raw()));
   }
@@ -162,9 +162,9 @@
 static void PrintUse(BufferFormatter* f, const Definition& definition) {
   if (definition.is_used()) {
     if (definition.HasSSATemp()) {
-      f->Print("v%"Pd, definition.ssa_temp_index());
+      f->Print("v%" Pd, definition.ssa_temp_index());
     } else if (definition.temp_index() != -1) {
-      f->Print("t%"Pd, definition.temp_index());
+      f->Print("t%" Pd, definition.temp_index());
     }
   }
 }
@@ -180,7 +180,7 @@
 
 void Instruction::PrintTo(BufferFormatter* f) const {
   if (GetDeoptId() != Isolate::kNoDeoptId) {
-    f->Print("%s:%"Pd"(", DebugName(), GetDeoptId());
+    f->Print("%s:%" Pd "(", DebugName(), GetDeoptId());
   } else {
     f->Print("%s(", DebugName());
   }
@@ -203,7 +203,7 @@
     if (HasSSATemp() || (temp_index() != -1)) f->Print(" <- ");
   }
   if (GetDeoptId() != Isolate::kNoDeoptId) {
-    f->Print("%s:%"Pd"(", DebugName(), GetDeoptId());
+    f->Print("%s:%" Pd "(", DebugName(), GetDeoptId());
   } else {
     f->Print("%s(", DebugName());
   }
@@ -283,8 +283,9 @@
 void RangeBoundary::PrintTo(BufferFormatter* f) const {
   switch (kind_) {
     case kSymbol:
-      f->Print("v%"Pd, reinterpret_cast<Definition*>(value_)->ssa_temp_index());
-      if (offset_ != 0) f->Print("%+"Pd, offset_);
+      f->Print("v%" Pd,
+               reinterpret_cast<Definition*>(value_)->ssa_temp_index());
+      if (offset_ != 0) f->Print("%+" Pd, offset_);
       break;
     case kConstant:
       if (value_ == kMinusInfinity) {
@@ -292,7 +293,7 @@
       } else if (value_ == kPlusInfinity) {
         f->Print("+inf");
       } else {
-        f->Print("%"Pd, value_);
+        f->Print("%" Pd, value_);
       }
       break;
     case kUnknown:
@@ -419,7 +420,7 @@
 
 
 void StoreInstanceFieldInstr::PrintOperandsTo(BufferFormatter* f) const {
-  f->Print("%s {%"Pd"}, ",
+  f->Print("%s {%" Pd "}, ",
            String::Handle(field().name()).ToCString(),
            field().Offset());
   instance()->PrintTo(f);
@@ -432,7 +433,7 @@
   left()->PrintTo(f);
   f->Print(" %s ", Token::Str(kind_));
   right()->PrintTo(f);
-  f->Print(" ? %"Pd" : %"Pd,
+  f->Print(" ? %" Pd " : %" Pd,
            if_true_,
            if_false_);
 }
@@ -524,7 +525,7 @@
 
 void LoadFieldInstr::PrintOperandsTo(BufferFormatter* f) const {
   instance()->PrintTo(f);
-  f->Print(", %"Pd, offset_in_bytes());
+  f->Print(", %" Pd, offset_in_bytes());
 
   if (field() != NULL) {
     f->Print(" {%s}", String::Handle(field()->name()).ToCString());
@@ -546,7 +547,7 @@
 
 void StoreVMFieldInstr::PrintOperandsTo(BufferFormatter* f) const {
   dest()->PrintTo(f);
-  f->Print(", %"Pd", ", offset_in_bytes());
+  f->Print(", %" Pd ", ", offset_in_bytes());
   value()->PrintTo(f);
 }
 
@@ -574,7 +575,7 @@
 
 
 void AllocateContextInstr::PrintOperandsTo(BufferFormatter* f) const {
-  f->Print("%"Pd"", num_context_variables());
+  f->Print("%" Pd "", num_context_variables());
 }
 
 
@@ -616,6 +617,17 @@
 }
 
 
+void Simd32x4GetSignMaskInstr::PrintOperandsTo(BufferFormatter* f) const {
+  if (op_kind() == MethodRecognizer::kFloat32x4GetSignMask) {
+    f->Print("Float32x4.getSignMask ");
+  } else {
+    ASSERT(op_kind() == MethodRecognizer::kUint32x4GetSignMask);
+    f->Print("Uint32x4.getSignMask ");
+  }
+  value()->PrintTo(f);
+}
+
+
 void Float32x4ZeroInstr::PrintOperandsTo(BufferFormatter* f) const {
   f->Print("ZERO ");
 }
@@ -806,7 +818,7 @@
 
 void GraphEntryInstr::PrintTo(BufferFormatter* f) const {
   const GrowableArray<Definition*>& defns = initial_definitions_;
-  f->Print("B%"Pd"[graph]:%"Pd, block_id(), GetDeoptId());
+  f->Print("B%" Pd "[graph]:%" Pd, block_id(), GetDeoptId());
   if (defns.length() > 0) {
     f->Print(" {");
     for (intptr_t i = 0; i < defns.length(); ++i) {
@@ -821,14 +833,14 @@
 
 void JoinEntryInstr::PrintTo(BufferFormatter* f) const {
   if (try_index() != CatchClauseNode::kInvalidTryIndex) {
-    f->Print("B%"Pd"[join try_idx %"Pd"]:%"Pd" pred(",
+    f->Print("B%" Pd "[join try_idx %" Pd "]:%" Pd " pred(",
              block_id(), try_index(), GetDeoptId());
   } else {
-    f->Print("B%"Pd"[join]:%"Pd" pred(", block_id(), GetDeoptId());
+    f->Print("B%" Pd "[join]:%" Pd " pred(", block_id(), GetDeoptId());
   }
   for (intptr_t i = 0; i < predecessors_.length(); ++i) {
     if (i > 0) f->Print(", ");
-    f->Print("B%"Pd, predecessors_[i]->block_id());
+    f->Print("B%" Pd, predecessors_[i]->block_id());
   }
   f->Print(")");
   if (phis_ != NULL) {
@@ -848,7 +860,7 @@
 
 
 void PhiInstr::PrintTo(BufferFormatter* f) const {
-  f->Print("v%"Pd" <- phi(", ssa_temp_index());
+  f->Print("v%" Pd " <- phi(", ssa_temp_index());
   for (intptr_t i = 0; i < inputs_.length(); ++i) {
     if (inputs_[i] != NULL) inputs_[i]->PrintTo(f);
     if (i < inputs_.length() - 1) f->Print(", ");
@@ -871,21 +883,21 @@
 
 
 void ParameterInstr::PrintOperandsTo(BufferFormatter* f) const {
-  f->Print("%"Pd, index());
+  f->Print("%" Pd, index());
 }
 
 
 void CheckStackOverflowInstr::PrintOperandsTo(BufferFormatter* f) const {
-  if (in_loop()) f->Print("depth %"Pd, loop_depth());
+  if (in_loop()) f->Print("depth %" Pd, loop_depth());
 }
 
 
 void TargetEntryInstr::PrintTo(BufferFormatter* f) const {
   if (try_index() != CatchClauseNode::kInvalidTryIndex) {
-    f->Print("B%"Pd"[target try_idx %"Pd"]:%"Pd,
+    f->Print("B%" Pd "[target try_idx %" Pd "]:%" Pd,
              block_id(), try_index(), GetDeoptId());
   } else {
-    f->Print("B%"Pd"[target]:%"Pd, block_id(), GetDeoptId());
+    f->Print("B%" Pd "[target]:%" Pd, block_id(), GetDeoptId());
   }
   if (HasParallelMove()) {
     f->Print(" ");
@@ -895,7 +907,7 @@
 
 
 void CatchBlockEntryInstr::PrintTo(BufferFormatter* f) const {
-  f->Print("B%"Pd"[target catch try_idx %"Pd" catch_try_idx %"Pd"]",
+  f->Print("B%" Pd "[target catch try_idx %" Pd " catch_try_idx %" Pd "]",
            block_id(), try_index(), catch_try_index());
   if (HasParallelMove()) {
     f->Print("\n");
@@ -926,9 +938,9 @@
     f->Print(" ");
   }
   if (GetDeoptId() != Isolate::kNoDeoptId) {
-    f->Print("goto:%"Pd" %"Pd"", GetDeoptId(), successor()->block_id());
+    f->Print("goto:%" Pd " %" Pd "", GetDeoptId(), successor()->block_id());
   } else {
-    f->Print("goto: %"Pd"", successor()->block_id());
+    f->Print("goto: %" Pd "", successor()->block_id());
   }
 }
 
@@ -938,7 +950,7 @@
   f->Print("if ");
   comparison()->PrintTo(f);
 
-  f->Print(" goto (%"Pd", %"Pd")",
+  f->Print(" goto (%" Pd ", %" Pd ")",
             true_successor()->block_id(),
             false_successor()->block_id());
 }
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 2fdb792..06c3d3a 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -1427,6 +1427,52 @@
 }
 
 
+Definition* BoxFloat32x4Instr::Canonicalize(FlowGraph* flow_graph) {
+  if (input_use_list() == NULL) {
+    // Environments can accomodate any representation. No need to box.
+    return value()->definition();
+  }
+
+  // Fold away BoxFloat32x4(UnboxFloat32x4(v)).
+  UnboxFloat32x4Instr* defn = value()->definition()->AsUnboxFloat32x4();
+  if ((defn != NULL) && (defn->value()->Type()->ToCid() == kFloat32x4Cid)) {
+    return defn->value()->definition();
+  }
+
+  return this;
+}
+
+
+Definition* UnboxFloat32x4Instr::Canonicalize(FlowGraph* flow_graph) {
+  // Fold away UnboxFloat32x4(BoxFloat32x4(v)).
+  BoxFloat32x4Instr* defn = value()->definition()->AsBoxFloat32x4();
+  return (defn != NULL) ? defn->value()->definition() : this;
+}
+
+
+Definition* BoxUint32x4Instr::Canonicalize(FlowGraph* flow_graph) {
+  if (input_use_list() == NULL) {
+    // Environments can accomodate any representation. No need to box.
+    return value()->definition();
+  }
+
+  // Fold away BoxUint32x4(UnboxUint32x4(v)).
+  UnboxUint32x4Instr* defn = value()->definition()->AsUnboxUint32x4();
+  if ((defn != NULL) && (defn->value()->Type()->ToCid() == kUint32x4Cid)) {
+    return defn->value()->definition();
+  }
+
+  return this;
+}
+
+
+Definition* UnboxUint32x4Instr::Canonicalize(FlowGraph* flow_graph) {
+  // Fold away UnboxUint32x4(BoxUint32x4(v)).
+  BoxUint32x4Instr* defn = value()->definition()->AsBoxUint32x4();
+  return (defn != NULL) ? defn->value()->definition() : this;
+}
+
+
 Instruction* BranchInstr::Canonicalize(FlowGraph* flow_graph) {
   // Only handle strict-compares.
   if (comparison()->IsStrictCompare()) {
@@ -1458,7 +1504,7 @@
       comp->RemoveFromGraph();
       SetComparison(comp);
       if (FLAG_trace_optimization) {
-        OS::Print("Merging comparison v%"Pd"\n", comp->ssa_temp_index());
+        OS::Print("Merging comparison v%" Pd "\n", comp->ssa_temp_index());
       }
       // Clear the comparison's temp index and ssa temp index since the
       // value of the comparison is not used outside the branch anymore.
@@ -1776,6 +1822,14 @@
 }
 
 
+bool PolymorphicInstanceCallInstr::HasRecognizedTarget() const {
+  return ic_data().HasOneTarget() &&
+      (MethodRecognizer::RecognizeKind(
+          Function::Handle(ic_data().GetTargetAt(0))) !=
+       MethodRecognizer::kUnknown);
+}
+
+
 LocationSummary* StaticCallInstr::MakeLocationSummary() const {
   return MakeCallSummary();
 }
@@ -2174,7 +2228,7 @@
     if (target() == branch->true_successor()) {
       // True unreachable.
       if (FLAG_trace_constant_propagation) {
-        OS::Print("Range analysis: True unreachable (B%"Pd")\n",
+        OS::Print("Range analysis: True unreachable (B%" Pd ")\n",
                   branch->true_successor()->block_id());
       }
       branch->set_constant_target(branch->false_successor());
@@ -2182,7 +2236,7 @@
       ASSERT(target() == branch->false_successor());
       // False unreachable.
       if (FLAG_trace_constant_propagation) {
-        OS::Print("Range analysis: False unreachable (B%"Pd")\n",
+        OS::Print("Range analysis: False unreachable (B%" Pd ")\n",
                   branch->false_successor()->block_id());
       }
       branch->set_constant_target(branch->true_successor());
@@ -2520,7 +2574,7 @@
 
 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr(
     ZoneGrowableArray<Value*>* inputs,
-    InstanceCallInstr* instance_call,
+    intptr_t original_deopt_id,
     MethodRecognizer::Kind recognized_kind)
     : inputs_(inputs),
       locs_(NULL),
@@ -2531,7 +2585,7 @@
     (*inputs)[i]->set_instruction(this);
     (*inputs)[i]->set_use_index(i);
   }
-  deopt_id_ = instance_call->deopt_id();
+  deopt_id_ = original_deopt_id;
 }
 
 
@@ -2547,7 +2601,7 @@
     case MethodRecognizer::kDoubleRound:
       return 1;
     case MethodRecognizer::kDoubleMod:
-    case MethodRecognizer::kDoublePow:
+    case MethodRecognizer::kMathDoublePow:
       return 2;
     default:
       UNREACHABLE();
@@ -2594,7 +2648,7 @@
       return kFloorRuntimeEntry;
     case MethodRecognizer::kDoubleCeil:
       return kCeilRuntimeEntry;
-    case MethodRecognizer::kDoublePow:
+    case MethodRecognizer::kMathDoublePow:
       return kPowRuntimeEntry;
     case MethodRecognizer::kDoubleMod:
       return kModRuntimeEntry;
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index a3b7fc7..644cb99 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -79,13 +79,13 @@
   V(_Double, roundToDouble, DoubleRound, 500368418)                            \
   V(_Double, floorToDouble, DoubleFloor, 763548522)                            \
   V(_Double, ceilToDouble, DoubleCeil, 976697019)                              \
-  V(_Double, pow, DoublePow, 1240251670)                                       \
   V(_Double, _modulo, DoubleMod, 1850917533)                                   \
   V(::, sqrt, MathSqrt, 465520247)                                             \
   V(::, sin, MathSin, 730107143)                                               \
   V(::, cos, MathCos, 1282146521)                                              \
   V(::, min, MathMin, 1584022354)                                              \
   V(::, max, MathMax, 328632232)                                               \
+  V(::, _doublePow, MathDoublePow, 2002448359)                                 \
   V(Float32x4, Float32x4., Float32x4Constructor, 1876089990)                   \
   V(Float32x4, Float32x4.zero, Float32x4Zero, 1903586222)                      \
   V(Float32x4, Float32x4.splat, Float32x4Splat, 38462589)                      \
@@ -94,6 +94,7 @@
   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)              \
@@ -124,6 +125,7 @@
   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, select, Uint32x4Select, 881590808)                              \
   V(_Uint32x4, withFlagX, Uint32x4WithFlagX, 1987921054)                       \
   V(_Uint32x4, withFlagY, Uint32x4WithFlagY, 831632614)                        \
@@ -134,6 +136,11 @@
 
 // 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(ListIterator, moveNext, ListIteratorMoveNext, 657540761)                   \
   V(_GrowableObjectArray, get:iterator, GrowableArrayIterator, 281980741)      \
   V(_GrowableObjectArray, forEach, GrowableArrayForEach, 334448248)
@@ -613,6 +620,7 @@
   M(IfThenElse)                                                                \
   M(BinaryFloat32x4Op)                                                         \
   M(Float32x4Shuffle)                                                          \
+  M(Simd32x4GetSignMask)                                                       \
   M(Float32x4Constructor)                                                      \
   M(Float32x4Zero)                                                             \
   M(Float32x4Splat)                                                            \
@@ -902,6 +910,7 @@
   friend class Float32x4ZeroInstr;
   friend class Float32x4SplatInstr;
   friend class Float32x4ShuffleInstr;
+  friend class Simd32x4GetSignMaskInstr;
   friend class Float32x4ConstructorInstr;
   friend class Float32x4ComparisonInstr;
   friend class Float32x4MinMaxInstr;
@@ -2699,6 +2708,8 @@
     return instance_call()->PushArgumentAt(index);
   }
 
+  bool HasRecognizedTarget() const;
+
   DECLARE_INSTRUCTION(PolymorphicInstanceCall)
 
   const ICData& ic_data() const { return ic_data_; }
@@ -4398,6 +4409,8 @@
 
   virtual bool MayThrow() const { return false; }
 
+  Definition* Canonicalize(FlowGraph* flow_graph);
+
  private:
   DISALLOW_COPY_AND_ASSIGN(BoxFloat32x4Instr);
 };
@@ -4428,6 +4441,8 @@
 
   virtual bool MayThrow() const { return false; }
 
+  Definition* Canonicalize(FlowGraph* flow_graph);
+
  private:
   DISALLOW_COPY_AND_ASSIGN(BoxUint32x4Instr);
 };
@@ -4525,6 +4540,8 @@
 
   virtual bool MayThrow() const { return false; }
 
+  Definition* Canonicalize(FlowGraph* flow_graph);
+
  private:
   DISALLOW_COPY_AND_ASSIGN(UnboxFloat32x4Instr);
 };
@@ -4557,6 +4574,8 @@
 
   virtual bool MayThrow() const { return false; }
 
+  Definition* Canonicalize(FlowGraph* flow_graph);
+
  private:
   DISALLOW_COPY_AND_ASSIGN(UnboxUint32x4Instr);
 };
@@ -5527,6 +5546,60 @@
 };
 
 
+class Simd32x4GetSignMaskInstr : public TemplateDefinition<1> {
+ public:
+  Simd32x4GetSignMaskInstr(MethodRecognizer::Kind op_kind, Value* value,
+                           intptr_t deopt_id) : op_kind_(op_kind) {
+    SetInputAt(0, value);
+    deopt_id_ = deopt_id;
+  }
+
+  Value* value() const { return inputs_[0]; }
+
+  MethodRecognizer::Kind op_kind() const { return op_kind_; }
+
+  virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual Representation representation() const {
+    return kTagged;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT(idx == 0);
+    if (op_kind_ == MethodRecognizer::kFloat32x4GetSignMask) {
+      return kUnboxedFloat32x4;
+    }
+    ASSERT(op_kind_ == MethodRecognizer::kUint32x4GetSignMask);
+    return kUnboxedUint32x4;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const {
+    // Direct access since this instruction cannot deoptimize, and the deopt-id
+    // was inherited from another instruction that could deoptimize.
+    return deopt_id_;
+  }
+
+  DECLARE_INSTRUCTION(Simd32x4GetSignMask)
+  virtual CompileType ComputeType() const;
+
+  virtual bool AllowsCSE() const { return true; }
+  virtual EffectSet Effects() const { return EffectSet::None(); }
+  virtual EffectSet Dependencies() const { return EffectSet::None(); }
+  virtual bool AttributesEqual(Instruction* other) const {
+    return other->AsSimd32x4GetSignMask()->op_kind() == op_kind();
+  }
+
+  virtual bool MayThrow() const { return false; }
+
+ private:
+  const MethodRecognizer::Kind op_kind_;
+
+  DISALLOW_COPY_AND_ASSIGN(Simd32x4GetSignMaskInstr);
+};
+
+
 class Float32x4TwoArgShuffleInstr : public TemplateDefinition<2> {
  public:
   Float32x4TwoArgShuffleInstr(MethodRecognizer::Kind op_kind, Value* left,
@@ -6279,7 +6352,7 @@
 class InvokeMathCFunctionInstr : public Definition {
  public:
   InvokeMathCFunctionInstr(ZoneGrowableArray<Value*>* inputs,
-                           InstanceCallInstr* instance_call,
+                           intptr_t original_deopt_id,
                            MethodRecognizer::Kind recognized_kind);
 
   static intptr_t ArgumentCountFor(MethodRecognizer::Kind recognized_kind_);
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 04edbc1..88ebbab 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -1517,11 +1517,17 @@
   LocationSummary* summary =
       new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresRegister());
-  if ((value()->Type()->ToCid() == kDynamicCid) &&
-      (field().guarded_cid() != kSmiCid)) {
+  const bool field_has_length = field().needs_length_check();
+  const bool need_value_temp_reg =
+      (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) &&
+                            (field().guarded_cid() != kSmiCid)));
+  if (need_value_temp_reg) {
+    summary->AddTemp(Location::RequiresRegister());
     summary->AddTemp(Location::RequiresRegister());
   }
-  if (field().guarded_cid() == kIllegalCid) {
+  const bool need_field_temp_reg =
+      field_has_length || (field().guarded_cid() == kIllegalCid);
+  if (need_field_temp_reg) {
     summary->AddTemp(Location::RequiresRegister());
   }
   return summary;
@@ -1531,6 +1537,17 @@
 void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const intptr_t field_cid = field().guarded_cid();
   const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid;
+  const intptr_t field_length = field().guarded_list_length();
+  const bool field_has_length = field().needs_length_check();
+  const bool needs_value_temp_reg =
+      (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) &&
+                            (field().guarded_cid() != kSmiCid)));
+  const bool needs_field_temp_reg =
+      field_has_length || (field().guarded_cid() == kIllegalCid);
+  if (field_has_length) {
+    // Currently, we should only see final fields that remember length.
+    ASSERT(field().is_final());
+  }
 
   if (field_cid == kDynamicCid) {
     ASSERT(!compiler->is_optimizing());
@@ -1541,10 +1558,12 @@
 
   Register value_reg = locs()->in(0).reg();
 
-  Register value_cid_reg = ((value_cid == kDynamicCid) &&
-      (field_cid != kSmiCid)) ? locs()->temp(0).reg() : kNoRegister;
+  Register value_cid_reg = needs_value_temp_reg ?
+      locs()->temp(0).reg() : kNoRegister;
+  Register temp_reg = needs_value_temp_reg ?
+      locs()->temp(1).reg() : kNoRegister;
 
-  Register field_reg = (field_cid == kIllegalCid) ?
+  Register field_reg = needs_field_temp_reg ?
       locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister;
 
   Label ok, fail_label;
@@ -1557,7 +1576,7 @@
   const bool ok_is_fall_through = (deopt != NULL);
 
   if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) {
-    if (!compiler->is_optimizing()) {
+    if (!compiler->is_optimizing() && (field_reg == kNoRegister)) {
       // Currently we can't have different location summaries for optimized
       // and non-optimized code. So instead we manually pick up a register
       // that is known to be free because we know how non-optimizing compiler
@@ -1571,6 +1590,8 @@
     FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset());
     FieldAddress field_nullability_operand(
         field_reg, Field::is_nullable_offset());
+    FieldAddress field_length_operand(
+        field_reg, Field::guarded_list_length_offset());
 
     if (value_cid_reg == kNoRegister) {
       ASSERT(!compiler->is_optimizing());
@@ -1580,17 +1601,56 @@
 
     if (value_cid == kDynamicCid) {
       LoadValueCid(compiler, value_cid_reg, value_reg);
+      Label skip_length_check;
       __ ldr(IP, field_cid_operand);
       __ cmp(value_cid_reg, ShifterOperand(IP));
-      __ b(&ok, EQ);
+      __ b(&skip_length_check, NE);
+      if (field_has_length) {
+        ASSERT(temp_reg != kNoRegister);
+        // Field guard may have remembered list length, check it.
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          __ ldr(temp_reg,
+                 FieldAddress(value_reg, Array::length_offset()));
+          __ CompareImmediate(temp_reg, field_length);
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          __ ldr(temp_reg,
+                 FieldAddress(value_reg, TypedData::length_offset()));
+          __ CompareImmediate(temp_reg, field_length);
+        } else {
+          ASSERT(field_cid == kIllegalCid);
+          // Following branch cannot not occur, fall through.
+        }
+        __ b(fail, NE);
+      }
+      __ Bind(&skip_length_check);
       __ ldr(IP, field_nullability_operand);
       __ cmp(value_cid_reg, ShifterOperand(IP));
     } else if (value_cid == kNullCid) {
       __ ldr(value_cid_reg, field_nullability_operand);
       __ CompareImmediate(value_cid_reg, value_cid);
     } else {
+      Label skip_length_check;
       __ ldr(value_cid_reg, field_cid_operand);
       __ CompareImmediate(value_cid_reg, value_cid);
+      __ b(&skip_length_check, NE);
+      if (field_has_length) {
+        ASSERT(value_cid_reg != kNoRegister);
+        ASSERT(temp_reg != kNoRegister);
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          __ ldr(temp_reg,
+                  FieldAddress(value_reg, Array::length_offset()));
+          __ CompareImmediate(temp_reg, field_length);
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          __ ldr(temp_reg,
+                  FieldAddress(value_reg, TypedData::length_offset()));
+          __ CompareImmediate(temp_reg, field_length);
+        } else {
+          ASSERT(field_cid == kIllegalCid);
+          // Following jump cannot not occur, fall through.
+        }
+      }
+      // Not identical, possibly null.
+      __ Bind(&skip_length_check);
     }
     __ b(&ok, EQ);
 
@@ -1601,16 +1661,65 @@
     if (value_cid == kDynamicCid) {
       __ str(value_cid_reg, field_cid_operand);
       __ str(value_cid_reg, field_nullability_operand);
+      if (field_has_length) {
+        Label check_array, local_exit, local_fail;
+        __ CompareImmediate(value_cid_reg, kNullCid);
+        __ b(&local_fail, EQ);
+        // Check for typed data array.
+        __ CompareImmediate(value_cid_reg, kTypedDataFloat32x4ArrayCid);
+        __ b(&local_fail, GT);
+        __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid);
+        __ b(&check_array, LT);  // Could still be a regular array.
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ ldr(value_cid_reg,
+               FieldAddress(value_reg, TypedData::length_offset()));
+        __ str(value_cid_reg, field_length_operand);
+        __ b(&local_exit);  // Updated field length typed data array.
+        // Check for regular array.
+        __ Bind(&check_array);
+        __ CompareImmediate(value_cid_reg, kImmutableArrayCid);
+        __ b(&local_fail, GT);
+        __ CompareImmediate(value_cid_reg, kArrayCid);
+        __ b(&local_fail, LT);
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ ldr(value_cid_reg,
+               FieldAddress(value_reg, Array::length_offset()));
+        __ str(value_cid_reg, field_length_operand);
+        __ b(&local_exit);  // Updated field length from regular array.
+
+        __ Bind(&local_fail);
+        __ LoadImmediate(IP, Field::kNoFixedLength);
+        __ str(IP, field_length_operand);
+
+        __ Bind(&local_exit);
+      }
     } else {
       __ LoadImmediate(IP, value_cid);
       __ str(IP, field_cid_operand);
       __ str(IP, field_nullability_operand);
+      if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ ldr(value_cid_reg,
+               FieldAddress(value_reg, Array::length_offset()));
+        __ str(value_cid_reg, field_length_operand);
+      } else if (RawObject::IsTypedDataClassId(value_cid)) {
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ ldr(value_cid_reg,
+                FieldAddress(value_reg, TypedData::length_offset()));
+        __ str(value_cid_reg, field_length_operand);
+      } else {
+        __ LoadImmediate(IP, Field::kNoFixedLength);
+        __ str(IP, field_length_operand);
+      }
     }
 
     if (!ok_is_fall_through) {
       __ b(&ok);
     }
   } else {
+    if (field_reg != kNoRegister) {
+      __ LoadObject(field_reg, Field::ZoneHandle(field().raw()));
+    }
     if (value_cid == kDynamicCid) {
       // Field's guarded class id is fixed by value's class id is not known.
       __ tst(value_reg, ShifterOperand(kSmiTagMask));
@@ -1621,6 +1730,26 @@
         __ CompareImmediate(value_cid_reg, field_cid);
       }
 
+      if (field_has_length) {
+        __ b(fail, NE);
+        // Classes are same, perform guarded list length check.
+        ASSERT(field_reg != kNoRegister);
+        ASSERT(value_cid_reg != kNoRegister);
+        FieldAddress field_length_operand(
+            field_reg, Field::guarded_list_length_offset());
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ ldr(value_cid_reg,
+                 FieldAddress(value_reg, Array::length_offset()));
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ ldr(value_cid_reg,
+                 FieldAddress(value_reg, TypedData::length_offset()));
+        }
+        __ ldr(IP, field_length_operand);
+        __ cmp(value_cid_reg, ShifterOperand(IP));
+      }
+
       if (field().is_nullable() && (field_cid != kNullCid)) {
         __ b(&ok, EQ);
         __ CompareImmediate(value_reg,
@@ -1638,6 +1767,22 @@
         if (ok_is_fall_through) {
           __ b(fail);
         }
+      } else if (field_has_length && (value_cid == field_cid)) {
+        ASSERT(value_cid_reg != kNoRegister);
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ ldr(value_cid_reg,
+                 FieldAddress(value_reg, Array::length_offset()));
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ ldr(value_cid_reg,
+                 FieldAddress(value_reg, TypedData::length_offset()));
+        }
+        __ LoadImmediate(IP, field_length);
+        __ cmp(value_cid_reg, ShifterOperand(IP));
+        if (ok_is_fall_through) {
+          __ b(fail, NE);
+        }
       } else {
         // Nothing to emit.
         ASSERT(!compiler->is_optimizing());
@@ -3030,6 +3175,46 @@
 }
 
 
+LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 1;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::FpuRegisterLocation(Q5));
+  summary->set_temp(0, Location::RequiresRegister());
+  summary->set_out(Location::RequiresRegister());
+  return summary;
+}
+
+
+void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  QRegister value = locs()->in(0).fpu_reg();
+  DRegister dvalue0 = EvenDRegisterOf(value);
+  DRegister dvalue1 = OddDRegisterOf(value);
+
+  Register out = locs()->out().reg();
+  Register temp = locs()->temp(0).reg();
+
+  // X lane.
+  __ vmovrs(out, EvenSRegisterOf(dvalue0));
+  __ Lsr(out, out, 31);
+  // Y lane.
+  __ vmovrs(temp, OddSRegisterOf(dvalue0));
+  __ Lsr(temp, temp, 31);
+  __ orr(out, out, ShifterOperand(temp, LSL, 1));
+  // Z lane.
+  __ vmovrs(temp, EvenSRegisterOf(dvalue1));
+  __ Lsr(temp, temp, 31);
+  __ orr(out, out, ShifterOperand(temp, LSL, 2));
+  // W lane.
+  __ vmovrs(temp, OddSRegisterOf(dvalue1));
+  __ Lsr(temp, temp, 31);
+  __ orr(out, out, ShifterOperand(temp, LSL, 3));
+  // Tag.
+  __ SmiTag(out);
+}
+
+
 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 4;
   const intptr_t kNumTemps = 0;
@@ -3632,6 +3817,12 @@
       __ veorq(result, left, right);
       break;
     }
+    case Token::kADD:
+      UNIMPLEMENTED();
+      break;
+    case Token::kSUB:
+      UNIMPLEMENTED();
+      break;
     default: UNREACHABLE();
   }
 }
@@ -3949,7 +4140,7 @@
 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   // For pow-function return NaN if exponent is NaN.
   Label do_call, skip_call;
-  if (recognized_kind() == MethodRecognizer::kDoublePow) {
+  if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
     DRegister exp = EvenDRegisterOf(locs()->in(1).fpu_reg());
     DRegister result = EvenDRegisterOf(locs()->out().fpu_reg());
     __ vcmpd(exp, exp);
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 412248c..a57cc42 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -1577,11 +1577,16 @@
   LocationSummary* summary =
       new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresRegister());
-  if ((value()->Type()->ToCid() == kDynamicCid) &&
-      (field().guarded_cid() != kSmiCid)) {
+  const bool field_has_length = field().needs_length_check();
+  const bool need_value_temp_reg =
+      (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) &&
+                            (field().guarded_cid() != kSmiCid)));
+  if (need_value_temp_reg) {
     summary->AddTemp(Location::RequiresRegister());
   }
-  if (field().guarded_cid() == kIllegalCid) {
+  const bool need_field_temp_reg =
+      field_has_length || (field().guarded_cid() == kIllegalCid);
+  if (need_field_temp_reg) {
     summary->AddTemp(Location::RequiresRegister());
   }
   return summary;
@@ -1591,6 +1596,17 @@
 void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const intptr_t field_cid = field().guarded_cid();
   const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid;
+  const intptr_t field_length = field().guarded_list_length();
+  const bool field_has_length = field().needs_length_check();
+  const bool needs_value_temp_reg =
+      (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) &&
+                            (field().guarded_cid() != kSmiCid)));
+  const bool needs_field_temp_reg =
+      field_has_length || (field().guarded_cid() == kIllegalCid);
+  if (field_has_length) {
+    // Currently, we should only see final fields that remember length.
+    ASSERT(field().is_final());
+  }
 
   if (field_cid == kDynamicCid) {
     ASSERT(!compiler->is_optimizing());
@@ -1601,10 +1617,10 @@
 
   Register value_reg = locs()->in(0).reg();
 
-  Register value_cid_reg = ((value_cid == kDynamicCid) &&
-      (field_cid != kSmiCid)) ? locs()->temp(0).reg() : kNoRegister;
+  Register value_cid_reg = needs_value_temp_reg ?
+      locs()->temp(0).reg() : kNoRegister;
 
-  Register field_reg = (field_cid == kIllegalCid) ?
+  Register field_reg = needs_field_temp_reg ?
       locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister;
 
   Label ok, fail_label;
@@ -1617,7 +1633,7 @@
   const bool ok_is_fall_through = (deopt != NULL);
 
   if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) {
-    if (!compiler->is_optimizing()) {
+    if (!compiler->is_optimizing() && (field_reg == kNoRegister)) {
       // Currently we can't have different location summaries for optimized
       // and non-optimized code. So instead we manually pick up a register
       // that is known to be free because we know how non-optimizing compiler
@@ -1631,6 +1647,8 @@
     FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset());
     FieldAddress field_nullability_operand(
         field_reg, Field::is_nullable_offset());
+    FieldAddress field_length_operand(
+        field_reg, Field::guarded_list_length_offset());
 
     if (value_cid == kDynamicCid) {
       if (value_cid_reg == kNoRegister) {
@@ -1641,33 +1659,154 @@
 
       LoadValueCid(compiler, value_cid_reg, value_reg);
 
+      Label skip_length_check;
       __ cmpl(value_cid_reg, field_cid_operand);
-      __ j(EQUAL, &ok);
+      // Value CID != Field guard CID, skip length check.
+      __ j(NOT_EQUAL, &skip_length_check);
+      if (field_has_length) {
+        // Field guard may have remembered list length, check it.
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          __ pushl(value_cid_reg);
+          __ movl(value_cid_reg,
+                  FieldAddress(value_reg, Array::length_offset()));
+          __ cmpl(value_cid_reg, Immediate(field_length));
+          __ popl(value_cid_reg);
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          __ pushl(value_cid_reg);
+          __ movl(value_cid_reg,
+                  FieldAddress(value_reg, TypedData::length_offset()));
+          __ cmpl(value_cid_reg, Immediate(field_length));
+          __ popl(value_cid_reg);
+        } else {
+          ASSERT(field_cid == kIllegalCid);
+          // Following jump cannot not occur, fall through.
+        }
+        __ j(NOT_EQUAL, fail);
+      }
+      __ Bind(&skip_length_check);
       __ cmpl(value_cid_reg, field_nullability_operand);
     } else if (value_cid == kNullCid) {
+      // Value in graph known to be null.
+      // Compare with null.
       __ cmpl(field_nullability_operand, Immediate(value_cid));
     } else {
+      // Value in graph known to be non-null.
+      Label skip_length_check;
+      // Compare class id with guard field class id.
       __ cmpl(field_cid_operand, Immediate(value_cid));
+      // If not equal, skip over length check.
+      __ j(NOT_EQUAL, &skip_length_check);
+      // Insert length check.
+      if (field_has_length) {
+        if (value_cid_reg == kNoRegister) {
+          ASSERT(!compiler->is_optimizing());
+          value_cid_reg = EDX;
+          ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
+        }
+        ASSERT(value_cid_reg != kNoRegister);
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          __ pushl(value_cid_reg);
+          __ movl(value_cid_reg,
+                  FieldAddress(value_reg, Array::length_offset()));
+          __ cmpl(value_cid_reg, Immediate(field_length));
+          __ popl(value_cid_reg);
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          __ pushl(value_cid_reg);
+          __ movl(value_cid_reg,
+                  FieldAddress(value_reg, TypedData::length_offset()));
+          __ cmpl(value_cid_reg, Immediate(field_length));
+          __ popl(value_cid_reg);
+        } else {
+          ASSERT(field_cid == kIllegalCid);
+          // Following jump cannot not occur, fall through.
+        }
+      }
+      // Not identical, possibly null.
+      __ Bind(&skip_length_check);
     }
+    // Jump when class id guard and list length guard are okay.
     __ j(EQUAL, &ok);
 
+
+    // Check if guard field is uninitialized.
     __ cmpl(field_cid_operand, Immediate(kIllegalCid));
+    // Jump to failure path when guard field has been initialized and
+    // the field and value class ids do not not match.
     __ j(NOT_EQUAL, fail);
 
+    // At this point the field guard is being initialized for the first time.
     if (value_cid == kDynamicCid) {
+      // Do not know value's class id.
       __ movl(field_cid_operand, value_cid_reg);
       __ movl(field_nullability_operand, value_cid_reg);
+      if (field_has_length) {
+        Label check_array, local_exit, local_fail;
+        __ cmpl(value_cid_reg, Immediate(kNullCid));
+        __ j(EQUAL, &local_fail);
+        // Check for typed data array.
+        __ cmpl(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid));
+        __ j(GREATER, &local_fail);  // Not a typed array or a regular array.
+        __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid));
+        __ j(LESS, &check_array);  // Could still be a regular array.
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ movl(value_cid_reg,
+                FieldAddress(value_reg, TypedData::length_offset()));
+        __ movl(field_length_operand, value_cid_reg);
+        __ jmp(&local_exit);  // Updated field length typed data array.
+        // Check for regular array.
+        __ Bind(&check_array);
+        __ cmpl(value_cid_reg, Immediate(kImmutableArrayCid));
+        __ j(GREATER, &local_fail);
+        __ cmpl(value_cid_reg, Immediate(kArrayCid));
+        __ j(LESS, &local_fail);
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ movl(value_cid_reg,
+                FieldAddress(value_reg, Array::length_offset()));
+        __ movl(field_length_operand, value_cid_reg);
+        __ jmp(&local_exit);  // Updated field length from regular array.
+
+        __ Bind(&local_fail);
+        __ movl(field_length_operand, Immediate(Field::kNoFixedLength));
+
+        __ Bind(&local_exit);
+      }
     } else {
+      if (value_cid_reg == kNoRegister) {
+          ASSERT(!compiler->is_optimizing());
+          value_cid_reg = EDX;
+          ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
+      }
+      ASSERT(value_cid_reg != kNoRegister);
+      ASSERT(field_reg != kNoRegister);
       __ movl(field_cid_operand, Immediate(value_cid));
       __ movl(field_nullability_operand, Immediate(value_cid));
+      if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ movl(value_cid_reg,
+                FieldAddress(value_reg, Array::length_offset()));
+        __ movl(field_length_operand, value_cid_reg);
+      } else if (RawObject::IsTypedDataClassId(value_cid)) {
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ movl(value_cid_reg,
+                FieldAddress(value_reg, TypedData::length_offset()));
+        __ movl(field_length_operand, value_cid_reg);
+      } else {
+        __ movl(field_length_operand, Immediate(Field::kNoFixedLength));
+      }
     }
 
     if (!ok_is_fall_through) {
       __ jmp(&ok);
     }
   } else {
+    // Field guard class has been initialized and is known.
+
+    if (field_reg != kNoRegister) {
+      __ LoadObject(field_reg, Field::ZoneHandle(field().raw()));
+    }
+
     if (value_cid == kDynamicCid) {
-      // Field's guarded class id is fixed by value's class id is not known.
+      // Value's class id is not known.
       __ testl(value_reg, Immediate(kSmiTagMask));
 
       if (field_cid != kSmiCid) {
@@ -1676,6 +1815,27 @@
         __ cmpl(value_cid_reg, Immediate(field_cid));
       }
 
+      if (field_has_length) {
+        // Jump when Value CID != Field guard CID
+        __ j(NOT_EQUAL, fail);
+
+        // Classes are same, perform guarded list length check.
+        ASSERT(field_reg != kNoRegister);
+        ASSERT(value_cid_reg != kNoRegister);
+        FieldAddress field_length_operand(
+            field_reg, Field::guarded_list_length_offset());
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ movl(value_cid_reg,
+                  FieldAddress(value_reg, Array::length_offset()));
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ movl(value_cid_reg,
+                  FieldAddress(value_reg, TypedData::length_offset()));
+        }
+        __ cmpl(value_cid_reg, field_length_operand);
+      }
+
       if (field().is_nullable() && (field_cid != kNullCid)) {
         __ j(EQUAL, &ok);
         const Immediate& raw_null =
@@ -1694,6 +1854,21 @@
         if (ok_is_fall_through) {
           __ jmp(fail);
         }
+      } else if (field_has_length && (value_cid == field_cid)) {
+        ASSERT(value_cid_reg != kNoRegister);
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ movl(value_cid_reg,
+                  FieldAddress(value_reg, Array::length_offset()));
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ movl(value_cid_reg,
+                  FieldAddress(value_reg, TypedData::length_offset()));
+        }
+        __ cmpl(value_cid_reg, Immediate(field_length));
+        if (ok_is_fall_through) {
+          __ j(NOT_EQUAL, fail);
+        }
       } else {
         // Nothing to emit.
         ASSERT(!compiler->is_optimizing());
@@ -3065,6 +3240,26 @@
 }
 
 
+LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_out(Location::RequiresRegister());
+  return summary;
+}
+
+
+void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister value = locs()->in(0).fpu_reg();
+  Register out = locs()->out().reg();
+
+  __ movmskps(out, value);
+  __ SmiTag(out);
+}
+
+
 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 4;
   const intptr_t kNumTemps = 0;
@@ -3687,6 +3882,12 @@
       __ xorps(left, right);
       break;
     }
+    case Token::kADD:
+      __ addpl(left, right);
+      break;
+    case Token::kSUB:
+      __ subpl(left, right);
+      break;
     default: UNREACHABLE();
   }
 }
@@ -4000,7 +4201,7 @@
   }
   // For pow-function return NaN if exponent is NaN.
   Label do_call, skip_call;
-  if (recognized_kind() == MethodRecognizer::kDoublePow) {
+  if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
     XmmRegister exp = locs()->in(1).fpu_reg();
     __ comisd(exp, exp);
     __ j(PARITY_ODD, &do_call, Assembler::kNearJump);  // NaN -> false;
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index e84f418..d32428a 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -1573,11 +1573,16 @@
   LocationSummary* summary =
       new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresRegister());
-  if ((value()->Type()->ToCid() == kDynamicCid) &&
-      (field().guarded_cid() != kSmiCid)) {
+  const bool field_has_length = field().needs_length_check();
+  const bool need_value_temp_reg =
+      (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) &&
+                            (field().guarded_cid() != kSmiCid)));
+  if (need_value_temp_reg) {
     summary->AddTemp(Location::RequiresRegister());
   }
-  if (field().guarded_cid() == kIllegalCid) {
+  const bool need_field_temp_reg =
+      field_has_length || (field().guarded_cid() == kIllegalCid);
+  if (need_field_temp_reg) {
     summary->AddTemp(Location::RequiresRegister());
   }
   return summary;
@@ -1588,6 +1593,17 @@
   __ TraceSimMsg("GuardFieldInstr");
   const intptr_t field_cid = field().guarded_cid();
   const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid;
+  const intptr_t field_length = field().guarded_list_length();
+  const bool field_has_length = field().needs_length_check();
+  const bool needs_value_temp_reg =
+      (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) &&
+                            (field().guarded_cid() != kSmiCid)));
+  const bool needs_field_temp_reg =
+      field_has_length || (field().guarded_cid() == kIllegalCid);
+  if (field_has_length) {
+    // Currently, we should only see final fields that remember length.
+    ASSERT(field().is_final());
+  }
 
   if (field_cid == kDynamicCid) {
     ASSERT(!compiler->is_optimizing());
@@ -1598,10 +1614,10 @@
 
   Register value_reg = locs()->in(0).reg();
 
-  Register value_cid_reg = ((value_cid == kDynamicCid) &&
-      (field_cid != kSmiCid)) ? locs()->temp(0).reg() : kNoRegister;
+  Register value_cid_reg = needs_value_temp_reg ?
+      locs()->temp(0).reg() : kNoRegister;
 
-  Register field_reg = (field_cid == kIllegalCid) ?
+  Register field_reg = needs_field_temp_reg ?
       locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister;
 
   Label ok, fail_label;
@@ -1614,7 +1630,7 @@
   const bool ok_is_fall_through = (deopt != NULL);
 
   if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) {
-    if (!compiler->is_optimizing()) {
+    if (!compiler->is_optimizing() && (field_reg == kNoRegister)) {
       // Currently we can't have different location summaries for optimized
       // and non-optimized code. So instead we manually pick up a register
       // that is known to be free because we know how non-optimizing compiler
@@ -1628,6 +1644,8 @@
     FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset());
     FieldAddress field_nullability_operand(
         field_reg, Field::is_nullable_offset());
+    FieldAddress field_length_operand(
+            field_reg, Field::guarded_list_length_offset());
 
     if (value_cid == kDynamicCid) {
       if (value_cid_reg == kNoRegister) {
@@ -1638,8 +1656,27 @@
 
       LoadValueCid(compiler, value_cid_reg, value_reg);
 
+      Label skip_length_check;
+
       __ lw(CMPRES1, field_cid_operand);
-      __ beq(value_cid_reg, CMPRES1, &ok);
+      __ bne(value_cid_reg, CMPRES1, &skip_length_check);
+      if (field_has_length) {
+        // Field guard may have remembered list length, check it.
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          __ lw(TMP, FieldAddress(value_reg, Array::length_offset()));
+          __ LoadImmediate(CMPRES1, field_length);
+          __ subu(CMPRES1, TMP, CMPRES1);
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset()));
+          __ LoadImmediate(CMPRES1, field_length);
+          __ subu(CMPRES1, TMP, CMPRES1);
+        } else {
+          ASSERT(field_cid == kIllegalCid);
+          __ LoadImmediate(CMPRES1, 0x1);
+        }
+        __ bne(CMPRES1, ZR, fail);
+      }
+      __ Bind(&skip_length_check);
       __ lw(TMP1, field_nullability_operand);
       __ subu(CMPRES, value_cid_reg, TMP1);
     } else if (value_cid == kNullCid) {
@@ -1648,10 +1685,34 @@
       __ LoadImmediate(CMPRES, value_cid);
       __ subu(CMPRES, TMP1, CMPRES);
     } else {
+      Label skip_length_check;
       // TODO(regis): TMP1 may conflict. Revisit.
       __ lw(TMP1, field_cid_operand);
       __ LoadImmediate(CMPRES, value_cid);
       __ subu(CMPRES, TMP1, CMPRES);
+      __ bne(CMPRES, ZR, &skip_length_check);
+      // Insert length check.
+      if (field_has_length) {
+        if (value_cid_reg == kNoRegister) {
+          ASSERT(!compiler->is_optimizing());
+          value_cid_reg = A1;
+          ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
+        }
+        ASSERT(value_cid_reg != kNoRegister);
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          __ lw(TMP, FieldAddress(value_reg, Array::length_offset()));
+          __ LoadImmediate(CMPRES, field_length);
+          __ subu(CMPRES, TMP, CMPRES);
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset()));
+          __ LoadImmediate(CMPRES, field_length);
+          __ subu(CMPRES, TMP, CMPRES);
+        } else {
+          ASSERT(field_cid == kIllegalCid);
+          __ LoadImmediate(CMPRES, 0x1);
+        }
+      }
+      __ Bind(&skip_length_check);
     }
     __ beq(CMPRES, ZR, &ok);
 
@@ -1661,16 +1722,72 @@
     if (value_cid == kDynamicCid) {
       __ sw(value_cid_reg, field_cid_operand);
       __ sw(value_cid_reg, field_nullability_operand);
+      if (field_has_length) {
+        Label check_array, local_exit, local_fail;
+        __ BranchEqual(value_cid_reg, kNullCid, &local_fail);
+        // Check for typed data array.
+        __ BranchSignedGreater(value_cid_reg, kTypedDataFloat32x4ArrayCid,
+                               &local_fail);
+        __ BranchSignedLess(value_cid_reg, kTypedDataInt8ArrayCid,
+                            &check_array);
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ lw(value_cid_reg,
+              FieldAddress(value_reg, TypedData::length_offset()));
+        __ sw(value_cid_reg, field_length_operand);
+        __ b(&local_exit);  // Updated field length typed data array.
+        // Check for regular array.
+        __ Bind(&check_array);
+        __ BranchSignedGreater(value_cid_reg, kImmutableArrayCid,
+                               &local_fail);
+        __ BranchSignedLess(value_cid_reg, kArrayCid, &local_fail);
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ lw(value_cid_reg,
+                FieldAddress(value_reg, Array::length_offset()));
+        __ sw(value_cid_reg, field_length_operand);
+        __ b(&local_exit);  // Updated field length from regular array.
+
+        __ Bind(&local_fail);
+        // TODO(regis): TMP1 may conflict. Revisit.
+        __ LoadImmediate(TMP1, Field::kNoFixedLength);
+        __ sw(TMP1, field_length_operand);
+
+        __ Bind(&local_exit);
+      }
     } else {
+      if (value_cid_reg == kNoRegister) {
+        ASSERT(!compiler->is_optimizing());
+        value_cid_reg = A1;
+        ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
+      }
+      ASSERT(value_cid_reg != kNoRegister);
+      ASSERT(field_reg != kNoRegister);
       __ LoadImmediate(TMP1, value_cid);
       __ sw(TMP1, field_cid_operand);
       __ sw(TMP1, field_nullability_operand);
+      if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ lw(value_cid_reg,
+              FieldAddress(value_reg, Array::length_offset()));
+        __ sw(value_cid_reg, field_length_operand);
+      } else if (RawObject::IsTypedDataClassId(value_cid)) {
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ lw(value_cid_reg,
+              FieldAddress(value_reg, TypedData::length_offset()));
+        __ sw(value_cid_reg, field_length_operand);
+      } else {
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ LoadImmediate(value_cid_reg, Field::kNoFixedLength);
+        __ sw(value_cid_reg, field_length_operand);
+      }
     }
 
     if (!ok_is_fall_through) {
       __ b(&ok);
     }
   } else {
+    if (field_reg != kNoRegister) {
+      __ LoadObject(field_reg, Field::ZoneHandle(field().raw()));
+    }
     if (value_cid == kDynamicCid) {
       // Field's guarded class id is fixed by value's class id is not known.
       __ andi(CMPRES, value_reg, Immediate(kSmiTagMask));
@@ -1682,6 +1799,27 @@
         __ subu(CMPRES, value_cid_reg, TMP1);
       }
 
+      if (field_has_length) {
+        // Jump when Value CID != Field guard CID
+        __ bne(CMPRES, ZR, fail);
+        // Classes are same, perform guarded list length check.
+        ASSERT(field_reg != kNoRegister);
+        ASSERT(value_cid_reg != kNoRegister);
+        FieldAddress field_length_operand(
+            field_reg, Field::guarded_list_length_offset());
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ lw(value_cid_reg,
+                FieldAddress(value_reg, Array::length_offset()));
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ lw(value_cid_reg,
+                FieldAddress(value_reg, TypedData::length_offset()));
+        }
+        __ lw(TMP1, field_length_operand);
+        __ subu(CMPRES, value_cid_reg, TMP1);
+      }
+
       if (field().is_nullable() && (field_cid != kNullCid)) {
         __ beq(CMPRES, ZR, &ok);
         __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null()));
@@ -1699,6 +1837,22 @@
         if (ok_is_fall_through) {
           __ b(fail);
         }
+      } else if (field_has_length && (value_cid == field_cid)) {
+        ASSERT(value_cid_reg != kNoRegister);
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ lw(value_cid_reg,
+                FieldAddress(value_reg, Array::length_offset()));
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ lw(value_cid_reg,
+                FieldAddress(value_reg, TypedData::length_offset()));
+        }
+        __ LoadImmediate(TMP1, field_length);
+        __ subu(CMPRES, value_cid_reg, TMP1);
+        if (ok_is_fall_through) {
+          __ bne(CMPRES, ZR, fail);
+        }
       } else {
         // Nothing to emit.
         ASSERT(!compiler->is_optimizing());
@@ -3041,6 +3195,17 @@
 }
 
 
+LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
 LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const {
   UNIMPLEMENTED();
   return NULL;
@@ -3375,7 +3540,7 @@
 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   // For pow-function return NaN if exponent is NaN.
   Label do_call, skip_call;
-  if (recognized_kind() == MethodRecognizer::kDoublePow) {
+  if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
     DRegister exp = locs()->in(1).fpu_reg();
     __ cund(exp, exp);
     __ bc1f(&do_call);
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 2a1a546..c5a1bf3 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -1536,11 +1536,16 @@
   LocationSummary* summary =
       new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresRegister());
-  if ((value()->Type()->ToCid() == kDynamicCid) &&
-      (field().guarded_cid() != kSmiCid)) {
+  const bool field_has_length = field().needs_length_check();
+  const bool need_value_temp_reg =
+      (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) &&
+                            (field().guarded_cid() != kSmiCid)));
+  if (need_value_temp_reg) {
     summary->AddTemp(Location::RequiresRegister());
   }
-  if (field().guarded_cid() == kIllegalCid) {
+  const bool need_field_temp_reg =
+      field_has_length || (field().guarded_cid() == kIllegalCid);
+  if (need_field_temp_reg) {
     summary->AddTemp(Location::RequiresRegister());
   }
   return summary;
@@ -1550,6 +1555,17 @@
 void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const intptr_t field_cid = field().guarded_cid();
   const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid;
+  const intptr_t field_length = field().guarded_list_length();
+  const bool field_has_length = field().needs_length_check();
+  const bool needs_value_temp_reg =
+      (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) &&
+                            (field().guarded_cid() != kSmiCid)));
+  const bool needs_field_temp_reg =
+      field_has_length || (field().guarded_cid() == kIllegalCid);
+  if (field_has_length) {
+    // Currently, we should only see final fields that remember length.
+    ASSERT(field().is_final());
+  }
 
   if (field_cid == kDynamicCid) {
     ASSERT(!compiler->is_optimizing());
@@ -1560,10 +1576,10 @@
 
   Register value_reg = locs()->in(0).reg();
 
-  Register value_cid_reg = ((value_cid == kDynamicCid) &&
-      (field_cid != kSmiCid)) ? locs()->temp(0).reg() : kNoRegister;
+  Register value_cid_reg = needs_value_temp_reg ?
+      locs()->temp(0).reg() : kNoRegister;
 
-  Register field_reg = (field_cid == kIllegalCid) ?
+  Register field_reg = needs_field_temp_reg ?
       locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister;
 
   Label ok, fail_label;
@@ -1576,7 +1592,7 @@
   const bool ok_is_fall_through = (deopt != NULL);
 
   if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) {
-    if (!compiler->is_optimizing()) {
+    if (!compiler->is_optimizing() && (field_reg == kNoRegister)) {
       // Currently we can't have different location summaries for optimized
       // and non-optimized code. So instead we manually pick up a register
       // that is known to be free because we know how non-optimizing compiler
@@ -1590,6 +1606,8 @@
     FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset());
     FieldAddress field_nullability_operand(
         field_reg, Field::is_nullable_offset());
+    FieldAddress field_length_operand(
+        field_reg, Field::guarded_list_length_offset());
 
     if (value_cid == kDynamicCid) {
       if (value_cid_reg == kNoRegister) {
@@ -1600,13 +1618,65 @@
 
       LoadValueCid(compiler, value_cid_reg, value_reg);
 
+      Label skip_length_check;
       __ cmpq(value_cid_reg, field_cid_operand);
-      __ j(EQUAL, &ok);
+      __ j(NOT_EQUAL, &skip_length_check);
+      if (field_has_length) {
+        // Field guard may have remembered list length, check it.
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          __ pushq(value_cid_reg);
+          __ movq(value_cid_reg,
+                  FieldAddress(value_reg, Array::length_offset()));
+          __ cmpq(value_cid_reg, Immediate(field_length));
+          __ popq(value_cid_reg);
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          __ pushq(value_cid_reg);
+          __ movq(value_cid_reg,
+                  FieldAddress(value_reg, TypedData::length_offset()));
+          __ cmpq(value_cid_reg, Immediate(field_length));
+          __ popq(value_cid_reg);
+        } else {
+          ASSERT(field_cid == kIllegalCid);
+          // Following jump cannot not occur, fall through.
+        }
+        __ j(NOT_EQUAL, fail);
+      }
+      __ Bind(&skip_length_check);
       __ cmpq(value_cid_reg, field_nullability_operand);
     } else if (value_cid == kNullCid) {
       __ cmpq(field_nullability_operand, Immediate(value_cid));
     } else {
+      Label skip_length_check;
       __ cmpq(field_cid_operand, Immediate(value_cid));
+      // If not equal, skip over length check.
+      __ j(NOT_EQUAL, &skip_length_check);
+      // Insert length check.
+      if (field_has_length) {
+        if (value_cid_reg == kNoRegister) {
+          ASSERT(!compiler->is_optimizing());
+          value_cid_reg = RDX;
+          ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
+        }
+        ASSERT(value_cid_reg != kNoRegister);
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          __ pushq(value_cid_reg);
+          __ movq(value_cid_reg,
+                  FieldAddress(value_reg, Array::length_offset()));
+          __ cmpq(value_cid_reg, Immediate(field_length));
+          __ popq(value_cid_reg);
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          __ pushq(value_cid_reg);
+          __ movq(value_cid_reg,
+                  FieldAddress(value_reg, TypedData::length_offset()));
+          __ cmpq(value_cid_reg, Immediate(field_length));
+          __ popq(value_cid_reg);
+        } else {
+          ASSERT(field_cid == kIllegalCid);
+          // Following jump cannot not occur, fall through.
+        }
+      }
+      // Not identical, possibly null.
+      __ Bind(&skip_length_check);
     }
     __ j(EQUAL, &ok);
 
@@ -1616,15 +1686,70 @@
     if (value_cid == kDynamicCid) {
       __ movq(field_cid_operand, value_cid_reg);
       __ movq(field_nullability_operand, value_cid_reg);
+      if (field_has_length) {
+        Label check_array, local_exit, local_fail;
+        __ cmpq(value_cid_reg, Immediate(kNullCid));
+        __ j(EQUAL, &local_fail);
+        // Check for typed data array.
+        __ cmpq(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid));
+        __ j(GREATER, &local_fail);  // Not a typed array or a regular array.
+        __ cmpq(value_cid_reg, Immediate(kTypedDataInt8ArrayCid));
+        __ j(LESS, &check_array);  // Could still be a regular array.
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ movq(value_cid_reg,
+                FieldAddress(value_reg, TypedData::length_offset()));
+        __ movq(field_length_operand, value_cid_reg);
+        __ jmp(&local_exit);  // Updated field length typed data array.
+        // Check for regular array.
+        __ Bind(&check_array);
+        __ cmpq(value_cid_reg, Immediate(kImmutableArrayCid));
+        __ j(GREATER, &local_fail);
+        __ cmpq(value_cid_reg, Immediate(kArrayCid));
+        __ j(LESS, &local_fail);
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ movq(value_cid_reg,
+                FieldAddress(value_reg, Array::length_offset()));
+        __ movq(field_length_operand, value_cid_reg);
+        __ jmp(&local_exit);  // Updated field length from regular array.
+
+        __ Bind(&local_fail);
+        __ movq(field_length_operand, Immediate(Field::kNoFixedLength));
+
+        __ Bind(&local_exit);
+      }
     } else {
+      if (value_cid_reg == kNoRegister) {
+          ASSERT(!compiler->is_optimizing());
+          value_cid_reg = RDX;
+          ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
+      }
+      ASSERT(value_cid_reg != kNoRegister);
+      ASSERT(field_reg != kNoRegister);
       __ movq(field_cid_operand, Immediate(value_cid));
       __ movq(field_nullability_operand, Immediate(value_cid));
+      if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ movq(value_cid_reg,
+                FieldAddress(value_reg, Array::length_offset()));
+        __ movq(field_length_operand, value_cid_reg);
+      } else if (RawObject::IsTypedDataClassId(value_cid)) {
+        // Destroy value_cid_reg (safe because we are finished with it).
+        __ movq(value_cid_reg,
+                FieldAddress(value_reg, TypedData::length_offset()));
+        __ movq(field_length_operand, value_cid_reg);
+      } else {
+        __ movq(field_length_operand, Immediate(Field::kNoFixedLength));
+      }
     }
 
     if (!ok_is_fall_through) {
       __ jmp(&ok);
     }
   } else {
+    if (field_reg != kNoRegister) {
+      __ LoadObject(field_reg, Field::ZoneHandle(field().raw()));
+    }
+
     if (value_cid == kDynamicCid) {
       // Field's guarded class id is fixed but value's class id is not known.
       __ testq(value_reg, Immediate(kSmiTagMask));
@@ -1635,6 +1760,27 @@
         __ cmpq(value_cid_reg, Immediate(field_cid));
       }
 
+      if (field_has_length) {
+        // Jump when Value CID != Field guard CID
+        __ j(NOT_EQUAL, fail);
+
+        // Classes are same, perform guarded list length check.
+        ASSERT(field_reg != kNoRegister);
+        ASSERT(value_cid_reg != kNoRegister);
+        FieldAddress field_length_operand(
+            field_reg, Field::guarded_list_length_offset());
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ movq(value_cid_reg,
+                  FieldAddress(value_reg, Array::length_offset()));
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ movq(value_cid_reg,
+                  FieldAddress(value_reg, TypedData::length_offset()));
+        }
+        __ cmpq(value_cid_reg, field_length_operand);
+      }
+
       if (field().is_nullable() && (field_cid != kNullCid)) {
         __ j(EQUAL, &ok);
         const Immediate& raw_null =
@@ -1653,6 +1799,21 @@
         if (ok_is_fall_through) {
           __ jmp(fail);
         }
+      } else if (field_has_length && (value_cid == field_cid)) {
+        ASSERT(value_cid_reg != kNoRegister);
+        if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ movq(value_cid_reg,
+                  FieldAddress(value_reg, Array::length_offset()));
+        } else if (RawObject::IsTypedDataClassId(field_cid)) {
+          // Destroy value_cid_reg (safe because we are finished with it).
+          __ movq(value_cid_reg,
+                  FieldAddress(value_reg, TypedData::length_offset()));
+        }
+        __ cmpq(value_cid_reg, Immediate(field_length));
+        if (ok_is_fall_through) {
+          __ j(NOT_EQUAL, fail);
+        }
       } else {
         // Nothing to emit.
         ASSERT(!compiler->is_optimizing());
@@ -3089,6 +3250,26 @@
 }
 
 
+LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_out(Location::RequiresRegister());
+  return summary;
+}
+
+
+void Simd32x4GetSignMaskInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister value = locs()->in(0).fpu_reg();
+  Register out = locs()->out().reg();
+
+  __ movmskps(out, value);
+  __ SmiTag(out);
+}
+
+
 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 4;
   const intptr_t kNumTemps = 0;
@@ -3728,6 +3909,12 @@
       __ xorps(left, right);
       break;
     }
+    case Token::kADD:
+      __ addpl(left, right);
+      break;
+    case Token::kSUB:
+      __ subpl(left, right);
+      break;
     default: UNREACHABLE();
   }
 }
@@ -4069,7 +4256,7 @@
   }
   // For pow-function return NaN if exponent is NaN.
   Label do_call, skip_call;
-  if (recognized_kind() == MethodRecognizer::kDoublePow) {
+  if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
     XmmRegister exp = locs()->in(1).fpu_reg();
     __ comisd(exp, exp);
     __ j(PARITY_ODD, &do_call, Assembler::kNearJump);  // NaN -> false;
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index 3f22ad0..0391beb 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -66,8 +66,9 @@
   V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger,           \
     1145805333)                                                                \
   V(_IntegerImplementation, *, Integer_mul, 1935440252)                        \
-  V(_IntegerImplementation, %, Integer_modulo, 1121942909)                     \
   V(_IntegerImplementation, remainder, Integer_remainder, 2140653009)          \
+  V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger,     \
+    713610917)                                                                 \
   V(_IntegerImplementation, ~/, Integer_truncDivide, 250357385)                \
   V(_IntegerImplementation, unary-, Integer_negate, 732448114)                 \
   V(_IntegerImplementation, _bitAndFromInteger,                                \
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index b042601..312912e 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -712,10 +712,14 @@
 //      res = res + right;
 //    }
 //  }
-bool Intrinsifier::Integer_modulo(Assembler* assembler) {
+bool Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
   // Check to see if we have integer division
   Label fall_through, subtract;
-  TestBothArgumentsSmis(assembler, &fall_through);
+  __ ldr(R1, Address(SP, + 0 * kWordSize));
+  __ ldr(R0, Address(SP, + 1 * kWordSize));
+  __ orr(TMP, R0, ShifterOperand(R1));
+  __ tst(TMP, ShifterOperand(kSmiTagMask));
+  __ b(&fall_through, NE);
   // R1: Tagged left (dividend).
   // R0: Tagged right (divisor).
   // Check if modulo by zero -> exception thrown in main function.
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 650769a..07932b0 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -715,12 +715,10 @@
 //      res = res + right;
 //    }
 //  }
-bool Intrinsifier::Integer_modulo(Assembler* assembler) {
+bool Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
   Label fall_through, subtract;
   TestBothArgumentsSmis(assembler, &fall_through);
-  // EAX: right argument (divisor)
-  __ movl(EBX, EAX);
-  __ movl(EAX, Address(ESP, + 2 * kWordSize));  // Left argument (dividend).
+  __ movl(EBX, Address(ESP, + 2 * kWordSize));
   // EAX: Tagged left (dividend).
   // EBX: Tagged right (divisor).
   // Check if modulo by zero -> exception thrown in main function.
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index 61c0a82..517e89b 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -721,9 +721,14 @@
 //      res = res + right;
 //    }
 //  }
-bool Intrinsifier::Integer_modulo(Assembler* assembler) {
+bool Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
   Label fall_through, subtract;
-  TestBothArgumentsSmis(assembler, &fall_through);
+  // Test arguments for smi.
+  __ lw(T1, Address(SP, 0 * kWordSize));
+  __ lw(T0, Address(SP, 1 * kWordSize));
+  __ or_(CMPRES, T0, T1);
+  __ andi(CMPRES, CMPRES, Immediate(kSmiTagMask));
+  __ bne(CMPRES, ZR, &fall_through);
   // T1: Tagged left (dividend).
   // T0: Tagged right (divisor).
   // Check if modulo by zero -> exception thrown in main function.
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index c6916ec..aa3ebff 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -703,12 +703,10 @@
 //      res = res + right;
 //    }
 //  }
-bool Intrinsifier::Integer_modulo(Assembler* assembler) {
+bool Intrinsifier::Integer_moduloFromInteger(Assembler* assembler) {
   Label fall_through, negative_result;
   TestBothArgumentsSmis(assembler, &fall_through);
-  // RAX: right argument (divisor)
-  __ movq(RCX, RAX);
-  __ movq(RAX, Address(RSP, + 2 * kWordSize));  // Left argument (dividend).
+  __ movq(RCX, Address(RSP, + 2 * kWordSize));
   // RAX: Tagged left (dividend).
   // RCX: Tagged right (divisor).
   __ cmpq(RCX, Immediate(0));
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 780f419..a572e76 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -273,7 +273,7 @@
   *double_slot = Double::New(value());
 
   if (FLAG_trace_deoptimization_verbose) {
-    OS::PrintErr("materializing double at %"Px": %g\n",
+    OS::PrintErr("materializing double at %" Px ": %g\n",
                  reinterpret_cast<uword>(slot()), value());
   }
 }
@@ -287,7 +287,7 @@
   *mint_slot = mint.raw();
 
   if (FLAG_trace_deoptimization_verbose) {
-    OS::PrintErr("materializing mint at %"Px": %"Pd64"\n",
+    OS::PrintErr("materializing mint at %" Px ": %" Pd64 "\n",
                  reinterpret_cast<uword>(slot()), value());
   }
 }
@@ -303,7 +303,7 @@
     float y = raw_float32x4->y();
     float z = raw_float32x4->z();
     float w = raw_float32x4->w();
-    OS::PrintErr("materializing Float32x4 at %"Px": %g,%g,%g,%g\n",
+    OS::PrintErr("materializing Float32x4 at %" Px ": %g,%g,%g,%g\n",
                  reinterpret_cast<uword>(slot()), x, y, z, w);
   }
 }
@@ -319,7 +319,7 @@
     uint32_t y = raw_uint32x4->y();
     uint32_t z = raw_uint32x4->z();
     uint32_t w = raw_uint32x4->w();
-    OS::PrintErr("materializing Uint32x4 at %"Px": %x,%x,%x,%x\n",
+    OS::PrintErr("materializing Uint32x4 at %" Px ": %x,%x,%x,%x\n",
                  reinterpret_cast<uword>(slot()), x, y, z, w);
   }
 }
@@ -329,7 +329,7 @@
   DeferredObject* obj = Isolate::Current()->GetDeferredObject(index());
   *slot() = obj->object();
   if (FLAG_trace_deoptimization_verbose) {
-    OS::PrintErr("writing instance ref at %"Px": %s\n",
+    OS::PrintErr("writing instance ref at %" Px ": %s\n",
                  reinterpret_cast<uword>(slot()),
                  Instance::Handle(obj->object()).ToCString());
   }
@@ -349,7 +349,7 @@
   cls ^= GetClass();
 
   if (FLAG_trace_deoptimization_verbose) {
-    OS::PrintErr("materializing instance of %s (%"Px", %"Pd" fields)\n",
+    OS::PrintErr("materializing instance of %s (%" Px ", %" Pd " fields)\n",
                  cls.ToCString(),
                  reinterpret_cast<uword>(args_),
                  field_count_);
@@ -730,7 +730,7 @@
   }
   invoked_functions.Sort(MostUsedFunctionFirst);
   for (int i = 0; i < invoked_functions.length(); i++) {
-    OS::Print("%10"Pd" x %s\n",
+    OS::Print("%10" Pd " x %s\n",
         invoked_functions[i]->usage_counter(),
         invoked_functions[i]->ToFullyQualifiedCString());
   }
@@ -881,7 +881,7 @@
   MonitorLocker ml(status_sync);
   DebuggerStackTrace* stack = Debugger::CollectStackTrace();
   TextBuffer buffer(256);
-  buffer.Printf("{ \"handle\": \"0x%"Px64"\", \"stacktrace\": [ ",
+  buffer.Printf("{ \"handle\": \"0x%" Px64 "\", \"stacktrace\": [ ",
                 reinterpret_cast<int64_t>(isolate));
   intptr_t n_frames = stack->Length();
   String& url = String::Handle();
@@ -890,11 +890,11 @@
     if (i > 0) {
       buffer.Printf(", ");
     }
-    ActivationFrame* frame = stack->ActivationFrameAt(i);
+    ActivationFrame* frame = stack->FrameAt(i);
     url ^= frame->SourceUrl();
     function ^= frame->function().UserVisibleName();
     buffer.Printf("{ \"url\": \"%s\", ", url.ToCString());
-    buffer.Printf("\"line\": %"Pd", ", frame->LineNumber());
+    buffer.Printf("\"line\": %" Pd ", ", frame->LineNumber());
     buffer.Printf("\"function\": \"%s\", ", function.ToCString());
 
     const Code& code = frame->code();
@@ -920,13 +920,13 @@
     // Frame no longer available.
     return NULL;
   }
-  ActivationFrame* frame = stack->ActivationFrameAt(frame_index);
+  ActivationFrame* frame = stack->FrameAt(frame_index);
   TextBuffer buffer(256);
-  buffer.Printf("{ \"handle\": \"0x%"Px64"\", \"frame_index\": %"Pd", ",
+  buffer.Printf("{ \"handle\": \"0x%" Px64 "\", \"frame_index\": %" Pd ", ",
        reinterpret_cast<int64_t>(isolate), frame_index);
 
   const Code& code = frame->code();
-  buffer.Printf("\"code\": { \"size\": %"Pd", ", code.Size());
+  buffer.Printf("\"code\": { \"size\": %" Pd ", ", code.Size());
   buffer.Printf("\"alive\": %s, ", code.is_alive() ? "false" : "true");
   buffer.Printf("\"optimized\": %s }, ",
       code.is_optimized() ? "false" : "true");
@@ -943,7 +943,7 @@
     intptr_t token_pos, end_pos;
     frame->VariableAt(i, &var_name, &token_pos, &end_pos, &value);
     buffer.Printf(
-        "{ \"name\": \"%s\", \"pos\": %"Pd", \"end_pos\": %"Pd", "
+        "{ \"name\": \"%s\", \"pos\": %" Pd ", \"end_pos\": %" Pd ", "
         "\"value\": \"%s\" }",
         var_name.ToCString(), token_pos, end_pos, value.ToCString());
   }
@@ -975,7 +975,7 @@
   if (result == NULL) {
     // Return empty stack.
     TextBuffer buffer(256);
-    buffer.Printf("{ \"handle\": \"0x%"Px64"\", \"stacktrace\": []}",
+    buffer.Printf("{ \"handle\": \"0x%" Px64 "\", \"stacktrace\": []}",
                   reinterpret_cast<int64_t>(this));
 
     result = OS::StrNDup(buffer.buf(), buffer.length());
@@ -1002,18 +1002,18 @@
 // Returns the isolate's general detail information.
 char* Isolate::GetStatusDetails() {
   const char* format = "{\n"
-      "  \"handle\": \"0x%"Px64"\",\n"
+      "  \"handle\": \"0x%" Px64 "\",\n"
       "  \"name\": \"%s\",\n"
-      "  \"port\": %"Pd",\n"
-      "  \"starttime\": %"Pd",\n"
-      "  \"stacklimit\": %"Pd",\n"
+      "  \"port\": %" Pd ",\n"
+      "  \"starttime\": %" Pd ",\n"
+      "  \"stacklimit\": %" Pd ",\n"
       "  \"newspace\": {\n"
-      "    \"used\": %"Pd",\n"
-      "    \"capacity\": %"Pd"\n"
+      "    \"used\": %" Pd ",\n"
+      "    \"capacity\": %" Pd "\n"
       "  },\n"
       "  \"oldspace\": {\n"
-      "    \"used\": %"Pd",\n"
-      "    \"capacity\": %"Pd"\n"
+      "    \"used\": %" Pd ",\n"
+      "    \"capacity\": %" Pd "\n"
       "  }\n"
       "}";
   char buffer[300];
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 1aec0bc..ace783e 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -73,7 +73,7 @@
 
 void JSONStream::PrintValue(intptr_t i) {
   PrintCommaIfNeeded();
-  buffer_->Printf("%"Pd"", i);
+  buffer_->Printf("%" Pd "", i);
 }
 
 
diff --git a/runtime/vm/locations.cc b/runtime/vm/locations.cc
index 23ab978..fb19c1f 100644
--- a/runtime/vm/locations.cc
+++ b/runtime/vm/locations.cc
@@ -145,9 +145,9 @@
 
 void Location::PrintTo(BufferFormatter* f) const {
   if (kind() == kStackSlot) {
-    f->Print("S%+"Pd"", stack_index());
+    f->Print("S%+" Pd "", stack_index());
   } else if (kind() == kDoubleStackSlot) {
-    f->Print("DS%+"Pd"", stack_index());
+    f->Print("DS%+" Pd "", stack_index());
   } else {
     f->Print("%s", Name());
   }
@@ -156,7 +156,7 @@
 
 void Location::Print() const {
   if (kind() == kStackSlot) {
-    OS::Print("S%+"Pd"", stack_index());
+    OS::Print("S%+" Pd "", stack_index());
   } else {
     OS::Print("%s", Name());
   }
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 6e6ed43..91272a1 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -92,7 +92,8 @@
     size += MegamorphicCache::InstanceSize();
     size += Array::InstanceSize(buckets.Length());
   }
-  OS::Print("%"Pd" megamorphic caches using %"Pd"KB.\n", length_, size / 1024);
+  OS::Print("%" Pd " megamorphic caches using %" Pd "KB.\n",
+            length_, size / 1024);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index a3e2170..f5c068e 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -96,9 +96,9 @@
     }
     OS::Print("[>] Posting message:\n"
               "\tsource:     %s\n"
-              "\treply_port: %"Pd64"\n"
+              "\treply_port: %" Pd64 "\n"
               "\tdest:       %s\n"
-              "\tdest_port:  %"Pd64"\n",
+              "\tdest_port:  %" Pd64 "\n",
               source_name, message->reply_port(), name(), message->dest_port());
   }
 
@@ -142,7 +142,7 @@
     if (FLAG_trace_isolates) {
       OS::Print("[<] Handling message:\n"
                 "\thandler:    %s\n"
-                "\tport:       %"Pd64"\n",
+                "\tport:       %" Pd64 "\n",
                 name(), message->dest_port());
     }
 
@@ -234,7 +234,7 @@
   if (FLAG_trace_isolates) {
     OS::Print("[-] Closing port:\n"
               "\thandler:    %s\n"
-              "\tport:       %"Pd64"\n",
+              "\tport:       %" Pd64 "\n",
               name(), port);
   }
 }
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index ca2a64d..af1c5e6 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -59,6 +59,8 @@
 DECLARE_FLAG(bool, trace_compiler);
 DECLARE_FLAG(bool, eliminate_type_checks);
 DECLARE_FLAG(bool, enable_type_checks);
+DECLARE_FLAG(bool, trace_deoptimization);
+DECLARE_FLAG(bool, trace_deoptimization_verbose);
 DECLARE_FLAG(bool, error_on_bad_override);
 
 static const char* kGetterPrefix = "get:";
@@ -1887,7 +1889,7 @@
   for (; i < desc.PositionalCount(); i++) {
     invocation.SetParameterTypeAt(i, Type::Handle(Type::DynamicType()));
     char name[64];
-    OS::SNPrint(name, 64, ":p%"Pd, i);
+    OS::SNPrint(name, 64, ":p%" Pd, i);
     invocation.SetParameterNameAt(i, String::Handle(Symbols::New(name)));
   }
 
@@ -2511,6 +2513,11 @@
   Error& args_malformed_error = Error::Handle();
   for (intptr_t i = 0; i < interfaces.Length(); i++) {
     interface ^= interfaces.At(i);
+    if (!interface.IsFinalized()) {
+      // We may be checking bounds at finalization time. Skipping this
+      // unfinalized interface will postpone bound checking to run time.
+      continue;
+    }
     interface_class = interface.type_class();
     interface_args = interface.arguments();
     if (!interface_args.IsNull() && !interface_args.IsInstantiated()) {
@@ -2522,7 +2529,6 @@
       // 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.
-      ASSERT(interface.IsFinalized());
       args_malformed_error = Error::null();
       interface_args = interface_args.InstantiateFrom(type_arguments,
                                                       &args_malformed_error);
@@ -3365,7 +3371,7 @@
 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) {
   if (len < 0 || len > kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in TypeArguments::New: invalid len %"Pd"\n", len);
+    FATAL1("Fatal error in TypeArguments::New: invalid len %" Pd "\n", len);
   }
   TypeArguments& result = TypeArguments::Handle();
   {
@@ -3693,7 +3699,7 @@
   }
 
   if (FLAG_trace_disabling_optimized_code) {
-    OS::Print("Disabling optimized code: '%s' entry: %#"Px"\n",
+    OS::Print("Disabling optimized code: '%s' entry: %#" Px "\n",
       ToFullyQualifiedCString(),
       current_code.EntryPoint());
   }
@@ -4076,7 +4082,6 @@
 bool Function::is_optimizable() const {
   if (OptimizableBit::decode(raw_ptr()->kind_tag_) &&
       (script() != Script::null()) &&
-      !is_native() &&
       ((end_token_pos() - token_pos()) < FLAG_huge_method_cutoff_in_tokens)) {
     // Additional check needed for implicit getters.
     if (HasCode() &&
@@ -4169,7 +4174,7 @@
       char message_buffer[kMessageBufferSize];
       OS::SNPrint(message_buffer,
                   kMessageBufferSize,
-                  "%"Pd" named passed, at most %"Pd" expected",
+                  "%" Pd " named passed, at most %" Pd " expected",
                   num_named_arguments,
                   NumOptionalNamedParameters());
       *error_message = String::New(message_buffer);
@@ -4187,7 +4192,7 @@
       const intptr_t num_hidden_params = NumImplicitParameters();
       OS::SNPrint(message_buffer,
                   kMessageBufferSize,
-                  "%"Pd"%s passed, %s%"Pd" expected",
+                  "%" Pd "%s passed, %s%" Pd " expected",
                   num_pos_args - num_hidden_params,
                   num_opt_pos_params > 0 ? " positional" : "",
                   num_opt_pos_params > 0 ? "at most " : "",
@@ -4204,7 +4209,7 @@
       const intptr_t num_hidden_params = NumImplicitParameters();
       OS::SNPrint(message_buffer,
                   kMessageBufferSize,
-                  "%"Pd"%s passed, %s%"Pd" expected",
+                  "%" Pd "%s passed, %s%" Pd " expected",
                   num_pos_args - num_hidden_params,
                   num_opt_pos_params > 0 ? " positional" : "",
                   num_opt_pos_params > 0 ? "at least " : "",
@@ -5301,6 +5306,7 @@
   result.set_has_initializer(false);
   result.set_guarded_cid(kIllegalCid);
   result.set_is_nullable(false);
+  result.set_guarded_list_length(Field::kUnknownFixedLength);
   result.set_dependent_code(Object::null_array());
   return result.raw();
 }
@@ -5424,6 +5430,12 @@
     while (frame != NULL) {
       code = frame->LookupDartCode();
       if (IsDependentCode(code_objects, code)) {
+        if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
+          Function& function = Function::Handle(code.function());
+          OS::PrintErr("Deoptimizing %s because guard on field %s failed.\n",
+              function.ToFullyQualifiedCString(),
+              ToCString());
+        }
         DeoptimizeAt(code, frame->pc());
       }
       frame = iterator.NextFrame();
@@ -5445,6 +5457,12 @@
     // If function uses dependent code switch it to unoptimized.
     if (function.CurrentCode() == code.raw()) {
       ASSERT(function.HasOptimizedCode());
+      if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
+        OS::PrintErr("Switching %s to unoptimized code because guard"
+                     " on field %s was violated.\n",
+                     function.ToFullyQualifiedCString(),
+                     ToCString());
+      }
       function.SwitchToUnoptimizedCode();
     }
   }
@@ -5484,6 +5502,37 @@
 }
 
 
+void Field::UpdateLength(intptr_t list_length) const {
+  ASSERT(is_final() || (!is_final() &&
+                        (list_length < Field::kUnknownFixedLength)));
+  ASSERT((list_length == Field::kNoFixedLength) ||
+         (list_length > Field::kUnknownFixedLength));
+  ASSERT(guarded_cid() != kIllegalCid);
+
+  const bool force_invalidate = (guarded_cid() == kDynamicCid) &&
+                                (list_length != Field::kNoFixedLength);
+
+  const bool list_length_unknown =
+      (guarded_list_length() == Field::kUnknownFixedLength);
+  const bool list_length_changed = (guarded_list_length() != list_length);
+
+  if (list_length_unknown && list_length_changed && !force_invalidate) {
+    // List length set for first time.
+    set_guarded_list_length(list_length);
+    return;
+  }
+
+  if (!list_length_changed && !force_invalidate) {
+    // List length unchanged.
+    return;
+  }
+
+  // Multiple list lengths assigned here, stop tracking length.
+  set_guarded_list_length(Field::kNoFixedLength);
+  DeoptimizeDependentCode();
+}
+
+
 void LiteralToken::set_literal(const String& literal) const {
   StorePointer(&raw_ptr()->literal_, literal.raw());
 }
@@ -5745,7 +5794,7 @@
 RawTokenStream* TokenStream::New(intptr_t len) {
   if (len < 0 || len > kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in TokenStream::New: invalid len %"Pd"\n", len);
+    FATAL1("Fatal error in TokenStream::New: invalid len %" Pd "\n", len);
   }
   uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(len));
   ASSERT(data != NULL);
@@ -7641,57 +7690,85 @@
 };
 
 
+
+// Return Function::null() if function does not exist in lib.
+static RawFunction* GetFunction(const GrowableArray<Library*>& libs,
+                                const char* class_name,
+                                const char* function_name) {
+  Function& func = Function::Handle();
+  String& class_str = String::Handle();
+  String& func_str = String::Handle();
+  Class& cls = Class::Handle();
+  for (intptr_t l = 0; l < libs.length(); l++) {
+    const Library& lib = *libs[l];
+    if (strcmp(class_name, "::") == 0) {
+      func_str = Symbols::New(function_name);
+      func = lib.LookupFunctionAllowPrivate(func_str, NULL);
+    } else {
+      class_str = String::New(class_name);
+      cls = lib.LookupClassAllowPrivate(class_str, NULL);
+      if (!cls.IsNull()) {
+        func_str = String::New(function_name);
+        if (function_name[0] == '.') {
+          func_str = String::Concat(class_str, func_str);
+        }
+        func = cls.LookupFunctionAllowPrivate(func_str);
+      }
+    }
+    if (!func.IsNull()) {
+      return func.raw();
+    }
+  }
+  return Function::null();
+}
+
+
 void Library::CheckFunctionFingerprints() {
   GrowableArray<FpDiff> collected_fp_diffs;
-  Library& lib = Library::Handle();
-  Class& cls = Class::Handle();
+  GrowableArray<Library*> all_libs;
   Function& func = Function::Handle();
-  String& str = String::Handle();
   bool has_errors = false;
 
 #define CHECK_FINGERPRINTS(class_name, function_name, dest, fp)                \
-  func = Function::null();                                                     \
-  if (strcmp(#class_name, "::") == 0) {                                        \
-    str = Symbols::New(#function_name);                                        \
-    func = lib.LookupFunctionAllowPrivate(str, NULL);                          \
-  } else {                                                                     \
-    str = String::New(#class_name);                                            \
-    cls = lib.LookupClassAllowPrivate(str, NULL);                              \
-    if (!cls.IsNull()) {                                                       \
-      if (#function_name[0] == '.') {                                          \
-        str = String::New(#class_name#function_name);                          \
-      } else {                                                                 \
-        str = String::New(#function_name);                                     \
-      }                                                                        \
-      func = cls.LookupFunctionAllowPrivate(str);                              \
-    }                                                                          \
-  }                                                                            \
-  if (!func.IsNull() && (func.SourceFingerprint() != fp)) {                    \
+  func = GetFunction(all_libs, #class_name, #function_name);                   \
+  if (func.IsNull()) {                                                         \
+    has_errors = true;                                                         \
+    OS::Print("Function not found %s.%s\n", #class_name, #function_name);      \
+  } else if (func.SourceFingerprint() != fp) {                                 \
     has_errors = true;                                                         \
     OS::Print("Wrong fingerprint for '%s': expecting %d found %d\n",           \
         func.ToFullyQualifiedCString(), fp, func.SourceFingerprint());         \
     collected_fp_diffs.Add(FpDiff(fp, func.SourceFingerprint()));              \
   }                                                                            \
 
-  lib = Library::CoreLibrary();
+  all_libs.Add(&Library::ZoneHandle(Library::CoreLibrary()));
   CORE_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
   CORE_INTEGER_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
 
+  all_libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
+  all_libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
   RECOGNIZED_LIST(CHECK_FINGERPRINTS);
 
-  lib = Library::MathLibrary();
+  all_libs.Clear();
+  all_libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
   MATH_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
 
-  lib = Library::TypedDataLibrary();
+  all_libs.Clear();
+  all_libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
   TYPED_DATA_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
 
 #undef CHECK_FINGERPRINTS
 
+Class& cls = Class::Handle();
+
 #define CHECK_FACTORY_FINGERPRINTS(factory_symbol, cid, fp)                    \
   cls = Isolate::Current()->class_table()->At(cid);                            \
   func = cls.LookupFunctionAllowPrivate(Symbols::factory_symbol());            \
-  ASSERT(!func.IsNull());                                                      \
-  if (func.SourceFingerprint() != fp) {                                        \
+  if (func.IsNull()) {                                                         \
+    has_errors = true;                                                         \
+    OS::Print("Function not found %s.%s\n", cls.ToCString(),                   \
+        Symbols::factory_symbol().ToCString());                                \
+  } else if (func.SourceFingerprint() != fp) {                                 \
     has_errors = true;                                                         \
     OS::Print("Wrong fingerprint for '%s': expecting %d found %d\n",           \
         func.ToFullyQualifiedCString(), fp, func.SourceFingerprint());         \
@@ -7701,6 +7778,7 @@
   RECOGNIZED_LIST_FACTORY_LIST(CHECK_FACTORY_FINGERPRINTS);
 
 #undef CHECK_FACTORY_FINGERPRINTS
+
   if (has_errors) {
     for (intptr_t i = 0; i < collected_fp_diffs.length(); i++) {
       OS::Print("s/%d/%d/\n",
@@ -7716,7 +7794,7 @@
   ASSERT(Object::instructions_class() != Class::null());
   if (size < 0 || size > kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in Instructions::New: invalid size %"Pd"\n", size);
+    FATAL1("Fatal error in Instructions::New: invalid size %" Pd "\n", size);
   }
   Instructions& result = Instructions::Handle();
   {
@@ -7810,7 +7888,7 @@
   if (num_descriptors < 0 || num_descriptors > kMaxElements) {
     // This should be caught before we reach here.
     FATAL1("Fatal error in PcDescriptors::New: "
-           "invalid num_descriptors %"Pd"\n", num_descriptors);
+           "invalid num_descriptors %" Pd "\n", num_descriptors);
   }
   PcDescriptors& result = PcDescriptors::Handle();
   {
@@ -7865,7 +7943,7 @@
   // "*" in a printf format specifier tells it to read the field width from
   // the printf argument list.
   const char* kFormat =
-      "%#-*"Px"\t%s\t%"Pd"\t\t%"Pd"\t%"Pd"\n";
+      "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n";
   // First compute the buffer size required.
   intptr_t len = 1;  // Trailing '\0'.
   for (intptr_t i = 0; i < Length(); i++) {
@@ -7909,7 +7987,7 @@
   // the check for too large number of descriptors.
   if (Length() > 3000) {
     if (FLAG_trace_compiler) {
-      OS::Print("Not checking pc decriptors, length %"Pd"\n", Length());
+      OS::Print("Not checking pc decriptors, length %" Pd "\n", Length());
     }
     return;
   }
@@ -7997,7 +8075,7 @@
       (payload_size >
            (kSmiMax - static_cast<intptr_t>(sizeof(RawStackmap))))) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in Stackmap::New: invalid length %"Pd"\n",
+    FATAL1("Fatal error in Stackmap::New: invalid length %" Pd "\n",
            length);
   }
   {
@@ -8027,7 +8105,7 @@
   if (IsNull()) {
     return "{null}";
   } else {
-    const char* kFormat = "%#"Px": ";
+    const char* kFormat = "%#" Px ": ";
     intptr_t fixed_length = OS::SNPrint(NULL, 0, kFormat, PC()) + 1;
     Isolate* isolate = Isolate::Current();
     // Guard against integer overflow in the computation of alloc_size.
@@ -8035,7 +8113,7 @@
     // TODO(kmillikin): We could just truncate the string if someone
     // tries to print a 2 billion plus entry stackmap.
     if (Length() > (kIntptrMax - fixed_length)) {
-      FATAL1("Length() is unexpectedly large (%"Pd")", Length());
+      FATAL1("Length() is unexpectedly large (%" Pd ")", Length());
     }
     intptr_t alloc_size = fixed_length + Length();
     char* chars = isolate->current_zone()->Alloc<char>(alloc_size);
@@ -8086,7 +8164,7 @@
 const char* LocalVarDescriptors::ToCString() const {
   intptr_t len = 1;  // Trailing '\0'.
   const char* kFormat =
-      "%2"Pd" kind=%d scope=0x%04x begin=%"Pd" end=%"Pd" name=%s\n";
+      "%2" Pd " kind=%d scope=0x%04x begin=%" Pd " end=%" Pd " name=%s\n";
   for (intptr_t i = 0; i < Length(); i++) {
     String& var_name = String::Handle(GetName(i));
     RawLocalVarDescriptors::VarInfo info;
@@ -8131,7 +8209,7 @@
   if (num_variables < 0 || num_variables > kMaxElements) {
     // This should be caught before we reach here.
     FATAL1("Fatal error in LocalVarDescriptors::New: "
-           "invalid num_variables %"Pd"\n", num_variables);
+           "invalid num_variables %" Pd "\n", num_variables);
   }
   LocalVarDescriptors& result = LocalVarDescriptors::Handle();
   {
@@ -8217,7 +8295,7 @@
   ASSERT(Object::exception_handlers_class() != Class::null());
   if (num_handlers < 0 || num_handlers >= kMaxHandlers) {
     FATAL1("Fatal error in ExceptionHandlers::New(): "
-           "invalid num_handlers %"Pd"\n",
+           "invalid num_handlers %" Pd "\n",
            num_handlers);
   }
   ExceptionHandlers& result = ExceptionHandlers::Handle();
@@ -8244,7 +8322,8 @@
   Type& type = Type::Handle();
   RawExceptionHandlers::HandlerInfo info;
   // First compute the buffer size required.
-  const char* kFormat = "%"Pd" => %#"Px"  (%"Pd" types) (outer %"Pd")\n";
+  const char* kFormat = "%" Pd " => %#" Px "  (%" Pd
+                        " types) (outer %" Pd ")\n";
   const char* kFormat2 = "  %d. %s\n";
   intptr_t len = 1;  // Trailing '\0'.
   for (intptr_t i = 0; i < Length(); i++) {
@@ -8430,7 +8509,8 @@
   Comments* comments;
   if (count < 0 || count > (kIntptrMax / kNumberOfEntries)) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in Code::Comments::New: invalid count %"Pd"\n", count);
+    FATAL1("Fatal error in Code::Comments::New: invalid count %" Pd "\n",
+           count);
   }
   if (count == 0) {
     comments = new Comments(Object::empty_array());
@@ -8604,7 +8684,7 @@
 RawCode* Code::New(intptr_t pointer_offsets_length) {
   if (pointer_offsets_length < 0 || pointer_offsets_length > kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %"Pd"\n",
+    FATAL1("Fatal error in Code::New: invalid pointer_offsets_length %" Pd "\n",
            pointer_offsets_length);
   }
   ASSERT(Object::code_class() != Class::null());
@@ -8894,7 +8974,7 @@
 
   if (num_variables < 0 || num_variables > kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in Context::New: invalid num_variables %"Pd"\n",
+    FATAL1("Fatal error in Context::New: invalid num_variables %" Pd "\n",
            num_variables);
   }
   Context& result = Context::Handle();
@@ -8926,7 +9006,7 @@
   ASSERT(Object::context_scope_class() != Class::null());
   if (num_variables < 0 || num_variables > kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in ContextScope::New: invalid num_variables %"Pd"\n",
+    FATAL1("Fatal error in ContextScope::New: invalid num_variables %" Pd "\n",
            num_variables);
   }
   intptr_t size = ContextScope::InstanceSize(num_variables);
@@ -9043,7 +9123,8 @@
 
 
 const char* ICData::ToCString() const {
-  const char* kFormat = "ICData target:'%s' num-args: %"Pd" num-checks: %"Pd"";
+  const char* kFormat = "ICData target:'%s' num-args: %" Pd
+                        " num-checks: %" Pd "";
   const String& name = String::Handle(target_name());
   const intptr_t num_args = num_args_tested();
   const intptr_t num_checks = NumberOfChecks();
@@ -9931,6 +10012,58 @@
 }
 
 
+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 =
+      PatchClass::Handle(MakeTempPatchClass(cls, expr));
+  const String& eval_func_name = String::Handle(Symbols::New(":eval"));
+  const Function& eval_func =
+      Function::Handle(Function::New(eval_func_name,
+                                     RawFunction::kRegularFunction,
+                                     false,  // Not 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(1);
+  eval_func.SetNumOptionalParameters(0, true);
+  eval_func.set_is_optimizable(false);
+
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, *this);
+  const Object& result =
+      Object::Handle(DartEntry::InvokeFunction(eval_func, args));
+  return result.raw();
+}
+
+
+
 bool Instance::Equals(const Instance& other) const {
   if (this->raw() == other.raw()) {
     return true;  // "===".
@@ -12227,7 +12360,7 @@
 RawBigint* Bigint::Allocate(intptr_t length, Heap::Space space) {
   if (length < 0 || length > kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in Bigint::Allocate: invalid length %"Pd"\n", length);
+    FATAL1("Fatal error in Bigint::Allocate: invalid length %" Pd "\n", length);
   }
   ASSERT(Isolate::Current()->object_store()->bigint_class() != Class::null());
   Bigint& result = Bigint::Handle();
@@ -13150,7 +13283,7 @@
          Class::null());
   if (len < 0 || len > kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in OneByteString::New: invalid len %"Pd"\n", len);
+    FATAL1("Fatal error in OneByteString::New: invalid len %" Pd "\n", len);
   }
   {
     RawObject* raw = Object::Allocate(OneByteString::kClassId,
@@ -13327,7 +13460,7 @@
   ASSERT(Isolate::Current()->object_store()->two_byte_string_class());
   if (len < 0 || len > kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in TwoByteString::New: invalid len %"Pd"\n", len);
+    FATAL1("Fatal error in TwoByteString::New: invalid len %" Pd "\n", len);
   }
   String& result = String::Handle();
   {
@@ -13456,7 +13589,7 @@
          external_one_byte_string_class() != Class::null());
   if (len < 0 || len > kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in ExternalOneByteString::New: invalid len %"Pd"\n",
+    FATAL1("Fatal error in ExternalOneByteString::New: invalid len %" Pd "\n",
            len);
   }
   String& result = String::Handle();
@@ -13494,7 +13627,7 @@
          Class::null());
   if (len < 0 || len > kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in ExternalTwoByteString::New: invalid len %"Pd"\n",
+    FATAL1("Fatal error in ExternalTwoByteString::New: invalid len %" Pd "\n",
            len);
   }
   String& result = String::Handle();
@@ -13593,7 +13726,7 @@
 RawArray* Array::New(intptr_t class_id, intptr_t len, Heap::Space space) {
   if (len < 0 || len > Array::kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in Array::New: invalid len %"Pd"\n", len);
+    FATAL1("Fatal error in Array::New: invalid len %" Pd "\n", len);
   }
   Array& result = Array::Handle();
   {
@@ -13620,8 +13753,8 @@
   if (IsNull()) {
     return IsImmutable() ? "ImmutableArray NULL" : "Array NULL";
   }
-  const char* format = !IsImmutable() ? "Array len:%"Pd"" :
-      "Immutable Array len:%"Pd"";
+  const char* format = !IsImmutable() ? "Array len:%" Pd "" :
+      "Immutable Array len:%" Pd "";
   intptr_t len = OS::SNPrint(NULL, 0, format, Length()) + 1;
   char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
   OS::SNPrint(chars, len, format, Length());
@@ -13700,7 +13833,7 @@
         this->SetAt(i, obj);
       } else {
         ASSERT(error_str != NULL);
-        const char* kFormat = "element at index %"Pd": %s\n";
+        const char* kFormat = "element at index %" Pd ": %s\n";
         const intptr_t len =
             OS::SNPrint(NULL, 0, kFormat, i, obj.ToCString()) + 1;
         char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
@@ -13832,7 +13965,7 @@
   if (IsNull()) {
     return "GrowableObjectArray NULL";
   }
-  const char* format = "GrowableObjectArray len:%"Pd"";
+  const char* format = "GrowableObjectArray len:%" Pd "";
   intptr_t len = OS::SNPrint(NULL, 0, format, Length()) + 1;
   char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
   OS::SNPrint(chars, len, format, Length());
@@ -14438,7 +14571,7 @@
          Class::null());
   if (len < 0 || len > kMaxElements) {
     // This should be caught before we reach here.
-    FATAL1("Fatal error in JSRegexp::New: invalid len %"Pd"\n", len);
+    FATAL1("Fatal error in JSRegexp::New: invalid len %" Pd "\n", len);
   }
   JSRegExp& result = JSRegExp::Handle();
   {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index a27fae7..20c508b 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1715,6 +1715,11 @@
     return kind() == RawFunction::kSetterFunction;
   }
 
+  // Returns true if this function represents an implicit setter function.
+  bool IsImplicitSetterFunction() const {
+    return kind() == RawFunction::kImplicitSetter;
+  }
+
   // Returns true if this function represents a (possibly implicit) closure
   // function.
   bool IsClosureFunction() const {
@@ -1982,11 +1987,33 @@
   static intptr_t guarded_cid_offset() {
     return OFFSET_OF(RawField, guarded_cid_);
   }
+  // Return the list length that any list stored in this field is guaranteed
+  // to have. If length is kUnknownFixedLength the length has not
+  // been determined. If length is kNoFixedLength this field has multiple
+  // list lengths associated with it and cannot be predicted.
+  intptr_t guarded_list_length() const {
+    return raw_ptr()->guarded_list_length_;
+  }
+  void set_guarded_list_length(intptr_t list_length) const {
+    raw_ptr()->guarded_list_length_ = list_length;
+  }
+  static intptr_t guarded_list_length_offset() {
+    return OFFSET_OF(RawField, guarded_list_length_);
+  }
+  bool needs_length_check() const {
+    const bool r = guarded_list_length() >= Field::kUnknownFixedLength;
+    ASSERT(!r || is_final());
+    return r;
+  }
 
   static bool IsExternalizableCid(intptr_t cid) {
     return (cid == kOneByteStringCid) || (cid == kTwoByteStringCid);
   }
 
+  enum {
+    kUnknownFixedLength = -1,
+    kNoFixedLength = -2,
+  };
   // Returns false if any value read from this field is guaranteed to be
   // not null.
   // Internally we is_nullable_ field contains either kNullCid (nullable) or
@@ -2003,8 +2030,12 @@
   }
 
   // Update guarded class id and nullability of the field to reflect assignment
-  // of the value with the given class id to this field.
+  // of the value with the given class id to this field. May trigger
+  // deoptimization of dependent code.
   void UpdateCid(intptr_t cid) const;
+  // Update guarded class length of the field to reflect assignment of the
+  // value with the given length. May trigger deoptimization of dependent code.
+  void UpdateLength(intptr_t length) const;
 
   // Return the list of optimized code objects that were optimized under
   // assumptions about guarded class id and nullability of this field.
@@ -3688,6 +3719,11 @@
   // function.
   bool IsCallable(Function* function, Context* context) const;
 
+  // Evaluate the given expression as if it appeared in an instance
+  // method of this instance and return the resulting value, or an
+  // error object if evaluating the expression fails.
+  RawObject* Evaluate(const String& expr) const;
+
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawInstance));
   }
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index e53b5d9..a4b7ec6 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -63,6 +63,7 @@
     utf_library_(Library::null()),
     libraries_(GrowableObjectArray::null()),
     pending_classes_(GrowableObjectArray::null()),
+    pending_functions_(GrowableObjectArray::null()),
     sticky_error_(Error::null()),
     unhandled_exception_handler_(String::null()),
     empty_context_(Context::null()),
@@ -105,6 +106,9 @@
   ASSERT(this->out_of_memory() == Instance::null());
   ASSERT(this->preallocated_stack_trace() == Stacktrace::null());
 
+  ASSERT(this->pending_functions() == GrowableObjectArray::null());
+  this->pending_functions_ = GrowableObjectArray::New();
+
   Object& result = Object::Handle();
   const Library& library = Library::Handle(Library::CoreLibrary());
 
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 48e711a..6ccdff9 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -349,6 +349,10 @@
     pending_classes_ = value.raw();
   }
 
+  RawGrowableObjectArray* pending_functions() const {
+    return pending_functions_;
+  }
+
   RawError* sticky_error() const { return sticky_error_; }
   void set_sticky_error(const Error& value) {
     ASSERT(!value.IsNull());
@@ -485,6 +489,7 @@
   RawLibrary* utf_library_;
   RawGrowableObjectArray* libraries_;
   RawGrowableObjectArray* pending_classes_;
+  RawGrowableObjectArray* pending_functions_;
   RawError* sticky_error_;
   RawString* unhandled_exception_handler_;
   RawContext* empty_context_;
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index e4145c6..61d9cbd 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -3263,7 +3263,7 @@
   }
   EXPECT(data.IsArray());
   const Array& metadata = Array::Cast(data);
-  OS::Print("Metadata for %s has %"Pd" values:\n", name, metadata.Length());
+  OS::Print("Metadata for %s has %" Pd " values:\n", name, metadata.Length());
   Object& elem = Object::Handle();
   for (int i = 0; i < metadata.Length(); i++) {
     elem = metadata.At(i);
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 17a378a..1c625e4 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -73,7 +73,7 @@
                       bool optimized) {
     Dart_FileWriteCallback file_write = Isolate::file_write_callback();
     ASSERT(file_write != NULL);
-    const char* format = "%"Px" %"Px" %s%s\n";
+    const char* format = "%" Px " %" Px " %s%s\n";
     const char* marker = optimized ? "*" : "";
     intptr_t len = OS::SNPrint(NULL, 0, format, base, size, marker, name);
     char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 2b869d4..5a14414 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -157,7 +157,7 @@
                       bool optimized) {
     Dart_FileWriteCallback file_write = Isolate::file_write_callback();
     ASSERT(file_write != NULL);
-    const char* format = "%"Px" %"Px" %s%s\n";
+    const char* format = "%" Px " %" Px " %s%s\n";
     const char* marker = optimized ? "*" : "";
     intptr_t len = OS::SNPrint(NULL, 0, format, base, size, marker, name);
     char* buffer = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index a63642d..1e96917 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -58,7 +58,7 @@
         intptr_t line, column;
         script.GetTokenLocation(token_pos, &line, &column);
         PrintIndent();
-        OS::Print("%s (line %"Pd", col %"Pd", token %"Pd")\n",
+        OS::Print("%s (line %" Pd ", col %" Pd ", token %" Pd ")\n",
                   msg, line, column, token_pos);
       }
       indent_++;
@@ -255,7 +255,8 @@
       current_class_(Class::Handle(isolate_)),
       library_(Library::Handle(isolate_, library.raw())),
       try_blocks_list_(NULL),
-      last_used_try_index_(CatchClauseNode::kInvalidTryIndex) {
+      last_used_try_index_(CatchClauseNode::kInvalidTryIndex),
+      unregister_pending_function_(false) {
   ASSERT(tokens_iterator_.IsValid());
   ASSERT(!library.IsNull());
 }
@@ -284,7 +285,8 @@
           isolate_,
           parsed_function->function().origin()).library())),
       try_blocks_list_(NULL),
-      last_used_try_index_(CatchClauseNode::kInvalidTryIndex) {
+      last_used_try_index_(CatchClauseNode::kInvalidTryIndex),
+      unregister_pending_function_(false) {
   ASSERT(tokens_iterator_.IsValid());
   ASSERT(!current_function().IsNull());
   if (FLAG_enable_type_checks) {
@@ -293,6 +295,19 @@
 }
 
 
+Parser::~Parser() {
+  if (unregister_pending_function_) {
+    const GrowableObjectArray& pending_functions =
+        GrowableObjectArray::Handle(
+            isolate()->object_store()->pending_functions());
+    ASSERT(pending_functions.Length() > 0);
+    ASSERT(pending_functions.At(pending_functions.Length()-1) ==
+        current_function().raw());
+    pending_functions.RemoveLast();
+  }
+}
+
+
 void Parser::SetScript(const Script & script, intptr_t token_pos) {
   script_ = script.raw();
   tokens_iterator_.SetStream(TokenStream::Handle(script.tokens()), token_pos);
@@ -1133,7 +1148,7 @@
   for (; i < desc.PositionalCount(); ++i) {
     ParamDesc p;
     char name[64];
-    OS::SNPrint(name, 64, ":p%"Pd, i);
+    OS::SNPrint(name, 64, ":p%" Pd, i);
     p.name = &String::ZoneHandle(Symbols::New(name));
     p.type = &Type::ZoneHandle(Type::DynamicType());
     params.parameters->Add(p);
@@ -2087,6 +2102,7 @@
                String::Handle(field.name()).ToCString());
     } else {
       field.UpdateCid(kNullCid);
+      field.UpdateLength(Field::kNoFixedLength);
     }
   }
 }
@@ -2359,6 +2375,23 @@
 }
 
 
+void Parser::CheckRecursiveInvocation() {
+  const GrowableObjectArray& pending_functions =
+      GrowableObjectArray::Handle(
+          isolate()->object_store()->pending_functions());
+  for (int i = 0; i < pending_functions.Length(); i++) {
+    if (pending_functions.At(i) == current_function().raw()) {
+      const String& fname =
+          String::Handle(current_function().UserVisibleName());
+      ErrorMsg("circular dependency for function %s", fname.ToCString());
+    }
+  }
+  ASSERT(!unregister_pending_function_);
+  pending_functions.Add(current_function());
+  unregister_pending_function_ = true;
+}
+
+
 // Parser is at the opening parenthesis of the formal parameter declaration
 // of function. Parse the formal parameters, initializers and code.
 SequenceNode* Parser::ParseConstructor(const Function& func,
@@ -2371,6 +2404,8 @@
   const Class& cls = Class::Handle(func.Owner());
   ASSERT(!cls.IsNull());
 
+  CheckRecursiveInvocation();
+
   if (func.IsImplicitConstructor()) {
     // Special case: implicit constructor.
     // The parser adds an implicit default constructor when a class
@@ -3122,7 +3157,7 @@
   }
   if (members->FieldNameExists(*field->name, !field->has_final)) {
     ErrorMsg(field->name_pos,
-             "'%s' field/method already defined\n", field->name->ToCString());
+             "field or method '%s' already defined", field->name->ToCString());
   }
   Function& getter = Function::Handle();
   Function& setter = Function::Handle();
@@ -3260,7 +3295,7 @@
       member.params.has_optional_named_parameters ||
       (member.params.num_fixed_parameters != expected_num_parameters)) {
     // Subtract receiver when reporting number of expected arguments.
-    ErrorMsg(member.name_pos, "operator %s expects %"Pd" argument(s)",
+    ErrorMsg(member.name_pos, "operator %s expects %" Pd " argument(s)",
         member.name->ToCString(), (expected_num_parameters - 1));
   }
 }
@@ -5018,6 +5053,7 @@
                                         Function::ZoneHandle(func.raw()),
                                         native_name,
                                         native_function,
+                                        current_block_->scope,
                                         is_bootstrap_native)));
 }
 
@@ -6852,7 +6888,7 @@
     if (token_pos >= 0) {
       intptr_t line, column;
       script.GetTokenLocation(token_pos, &line, &column);
-      result = String::NewFormatted("'%s': %s: line %"Pd" pos %"Pd": ",
+      result = String::NewFormatted("'%s': %s: line %" Pd " pos %" Pd ": ",
                                     script_url.ToCString(),
                                     message_header,
                                     line,
@@ -7241,7 +7277,7 @@
 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos,
                                                const char* s) {
   char name[64];
-  OS::SNPrint(name, 64, ":%s%"Pd, s, token_pos);
+  OS::SNPrint(name, 64, ":%s%" Pd, s, token_pos);
   LocalVariable* temp =
       new LocalVariable(token_pos,
                         String::ZoneHandle(Symbols::New(name)),
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 2af08c2..b2fbf97 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -182,6 +182,7 @@
 
   Parser(const Script& script, const Library& library, intptr_t token_pos);
   Parser(const Script& script, ParsedFunction* function, intptr_t token_pos);
+  ~Parser();
 
   // The function for which we will generate code.
   const Function& current_function() const;
@@ -320,6 +321,8 @@
       const Error& prev_error, intptr_t token_pos, const char* format, ...)
       PRINTF_ATTRIBUTE(4, 5);
 
+  void CheckRecursiveInvocation();
+
   const Instance& EvaluateConstExpr(AstNode* expr);
   AstNode* RunStaticFieldInitializer(const Field& field);
   RawObject* EvaluateConstConstructorCall(
@@ -693,6 +696,8 @@
   intptr_t AllocateTryIndex() { return ++last_used_try_index_; }
   intptr_t last_used_try_index_;
 
+  bool unregister_pending_function_;
+
   DISALLOW_COPY_AND_ASSIGN(Parser);
 };
 
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 7483d21..2ec7137 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -37,15 +37,15 @@
   uword tags = ptr()->tags_;
   intptr_t reserved = ReservedBits::decode(tags);
   if (reserved != 0) {
-    FATAL1("Invalid tags field encountered %#"Px"\n", tags);
+    FATAL1("Invalid tags field encountered %#" Px "\n", tags);
   }
   intptr_t class_id = ClassIdTag::decode(tags);
   if (!isolate->class_table()->IsValidIndex(class_id)) {
-    FATAL1("Invalid class id encountered %"Pd"\n", class_id);
+    FATAL1("Invalid class id encountered %" Pd "\n", class_id);
   }
   intptr_t size = SizeTag::decode(tags);
   if (size != 0 && size != SizeFromClass()) {
-    FATAL1("Inconsistent class size encountered %"Pd"\n", size);
+    FATAL1("Inconsistent class size encountered %" Pd "\n", size);
   }
 }
 
@@ -252,7 +252,7 @@
         break;
       }
       default:
-        OS::Print("Class Id: %"Pd"\n", class_id);
+        OS::Print("Class Id: %" Pd "\n", class_id);
         UNREACHABLE();
         break;
     }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 6d5892d..1be013c 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -688,6 +688,7 @@
   intptr_t guarded_cid_;
   intptr_t is_nullable_;  // kNullCid if field can contain null value and
                           // any other value otherwise.
+  intptr_t guarded_list_length_;
   uint8_t kind_bits_;  // static, final, const, has initializer.
 };
 
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 3e48cdb..ab17198 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -257,7 +257,7 @@
         reinterpret_cast<uword>(ptr()->type_class_) - kHeapObjectTag +
             Object::tags_offset()));
     if (cid == kUnresolvedClassCid) {
-      OS::Print("Snapshotting unresolved type '%s' at token pos %"Pd"\n",
+      OS::Print("Snapshotting unresolved type '%s' at token pos %" Pd "\n",
                 RawOneByteStringToCString(
                     reinterpret_cast<RawOneByteString*>(
                         reinterpret_cast<RawUnresolvedClass*>(
@@ -265,7 +265,7 @@
                 ptr()->token_pos_);
     } else {
       // Assume cid == kClassId, but it can also be kIllegalCid.
-      OS::Print("Snapshotting unfinalized type '%s' at token pos %"Pd"\n",
+      OS::Print("Snapshotting unfinalized type '%s' at token pos %" Pd "\n",
                 RawOneByteStringToCString(
                     reinterpret_cast<RawOneByteString*>(
                         reinterpret_cast<RawClass*>(
@@ -342,7 +342,7 @@
     // to, making sure not to allocate any handles. Unfortunately, we cannot
     // print the script name.
     OS::Print("Snapshotting unfinalized type parameter '%s' of class '%s' at "
-              "token pos %"Pd"\n",
+              "token pos %" Pd "\n",
               RawOneByteStringToCString(
                   reinterpret_cast<RawOneByteString*>(ptr()->name_)),
               RawOneByteStringToCString(
@@ -821,6 +821,7 @@
   field.set_token_pos(reader->ReadIntptrValue());
   field.set_guarded_cid(reader->ReadIntptrValue());
   field.set_is_nullable(reader->ReadIntptrValue());
+  field.set_guarded_list_length(reader->ReadIntptrValue());
   field.set_kind_bits(reader->Read<uint8_t>());
 
   // Set all the object fields.
@@ -854,6 +855,7 @@
   writer->WriteIntptrValue(ptr()->token_pos_);
   writer->WriteIntptrValue(ptr()->guarded_cid_);
   writer->WriteIntptrValue(ptr()->is_nullable_);
+  writer->WriteIntptrValue(ptr()->guarded_list_length_);
   writer->Write<uint8_t>(ptr()->kind_bits_);
 
   // Write out all the object pointer fields.
diff --git a/runtime/vm/scanner.cc b/runtime/vm/scanner.cc
index 8bf4926..0d6e5d0 100644
--- a/runtime/vm/scanner.cc
+++ b/runtime/vm/scanner.cc
@@ -947,7 +947,7 @@
   }
   char private_key[32];
   OS::SNPrint(private_key, sizeof(private_key),
-              "%c%#"Px"", kPrivateKeySeparator, key_value);
+              "%c%#" Px "", kPrivateKeySeparator, key_value);
   const String& result = String::Handle(String::New(private_key, Heap::kOld));
   return result.raw();
 }
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index d19dbe1..687f2e5 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -167,7 +167,7 @@
   String& url = String::Handle();
   String& function = String::Handle();
   for (int i = 0; i < n_frames; i++) {
-    ActivationFrame* frame = stack->ActivationFrameAt(i);
+    ActivationFrame* frame = stack->FrameAt(i);
     url ^= frame->SourceUrl();
     function ^= frame->function().UserVisibleName();
     js->OpenObject();
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 7826a37..9135e2c 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -294,7 +294,8 @@
   if (token_pos >= 0) {
     script.GetTokenLocation(token_pos, &line, &column);
   }
-  OS::Print("pc=0x%"Px" fp=0x%"Px" sp=0x%"Px" %s%s (%s:%"Pd":%"Pd")\n",
+  OS::Print("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd
+            ":%" Pd ")\n",
             pc, fp, sp,
             is_optimized ? (is_inlined ? "inlined " : "optimized ") : "",
             func_name.ToCString(),
@@ -344,7 +345,7 @@
                      GetApproximateTokenIndex(code, frame->pc()),
                      code.is_optimized(), false);
     } else {
-      OS::Print("pc=0x%"Px" fp=0x%"Px" sp=0x%"Px" %s frame\n",
+      OS::Print("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s frame\n",
                 frame->pc(), frame->fp(), frame->sp(),
                 frame->IsEntryFrame() ? "entry" :
                     frame->IsExitFrame() ? "exit" :
@@ -422,7 +423,7 @@
     if (last_pc != sim_->get_pc()) {
       last_pc = sim_->get_pc();
       if (Simulator::IsIllegalAddress(last_pc)) {
-        OS::Print("pc is out of bounds: 0x%"Px"\n", last_pc);
+        OS::Print("pc is out of bounds: 0x%" Px "\n", last_pc);
       } else {
         Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
       }
@@ -976,7 +977,7 @@
   // it will be possible to disassemble the code and inspect registers.
   char buffer[128];
   snprintf(buffer, sizeof(buffer),
-           "illegal memory access at 0x%"Px", pc=0x%"Px"\n",
+           "illegal memory access at 0x%" Px ", pc=0x%" Px "\n",
            addr, fault_pc);
   SimulatorDebugger dbg(this);
   dbg.Stop(instr, buffer);
@@ -998,7 +999,7 @@
   // it will be possible to disassemble the code and inspect registers.
   char buffer[64];
   snprintf(buffer, sizeof(buffer),
-           "unaligned %s at 0x%"Px", pc=%p\n", msg, addr, instr);
+           "unaligned %s at 0x%" Px ", pc=%p\n", msg, addr, instr);
   SimulatorDebugger dbg(this);
   dbg.Stop(instr, buffer);
   // The debugger will return control in non-interactive mode.
@@ -1506,7 +1507,7 @@
         Redirection* redirection = Redirection::FromSvcInstruction(instr);
         uword external = redirection->external_function();
         if (FLAG_trace_sim) {
-          OS::Print("Call to host function at 0x%"Pd"\n", external);
+          OS::Print("Call to host function at 0x%" Pd "\n", external);
         }
 
         if ((redirection->call_kind() == kRuntimeCall) ||
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index fa8dbb8..7efabfa 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -314,7 +314,7 @@
     if (last_pc != sim_->get_pc()) {
       last_pc = sim_->get_pc();
       if (Simulator::IsIllegalAddress(last_pc)) {
-        OS::Print("pc is out of bounds: 0x%"Px"\n", last_pc);
+        OS::Print("pc is out of bounds: 0x%" Px "\n", last_pc);
       } else {
         Disassembler::Disassemble(last_pc, last_pc + Instr::kInstrSize);
       }
@@ -818,7 +818,7 @@
   // it will be possible to disassemble the code and inspect registers.
   char buffer[128];
   snprintf(buffer, sizeof(buffer),
-           "illegal memory access at 0x%"Px", pc=0x%"Px"\n",
+           "illegal memory access at 0x%" Px ", pc=0x%" Px "\n",
            addr, fault_pc);
   SimulatorDebugger dbg(this);
   dbg.Stop(instr, buffer);
@@ -832,7 +832,7 @@
   // it will be possible to disassemble the code and inspect registers.
   char buffer[128];
   snprintf(buffer, sizeof(buffer),
-           "pc=%p, unaligned %s at 0x%"Px"\n",  instr, msg, addr);
+           "pc=%p, unaligned %s at 0x%" Px "\n",  instr, msg, addr);
   SimulatorDebugger dbg(this);
   dbg.Stop(instr, buffer);
   // The debugger will return control in non-interactive mode.
@@ -1005,7 +1005,7 @@
       Redirection* redirection = Redirection::FromBreakInstruction(instr);
       uword external = redirection->external_function();
       if (FLAG_trace_sim) {
-        OS::Print("Call to host function at 0x%"Pd"\n", external);
+        OS::Print("Call to host function at 0x%" Pd "\n", external);
       }
 
       if ((redirection->call_kind() == kRuntimeCall) ||
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 0758462..0aac461 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -950,7 +950,7 @@
     TestCase::LoadTestScript(kScriptChars, NULL);
     EXPECT_VALID(Api::CheckIsolateState(isolate));
     timer1.Stop();
-    OS::PrintErr("Without Snapshot: %"Pd64"us\n", timer1.TotalElapsedTime());
+    OS::PrintErr("Without Snapshot: %" Pd64 "us\n", timer1.TotalElapsedTime());
 
     // Write snapshot with object content.
     FullSnapshotWriter writer(&buffer, &malloc_allocator);
@@ -965,7 +965,7 @@
   {
     Dart_EnterScope();  // Start a Dart API scope for invoking API functions.
     timer2.Stop();
-    OS::PrintErr("From Snapshot: %"Pd64"us\n", timer2.TotalElapsedTime());
+    OS::PrintErr("From Snapshot: %" Pd64 "us\n", timer2.TotalElapsedTime());
 
     // Invoke a function which returns an object.
     Dart_Handle cls =
@@ -1004,7 +1004,7 @@
     Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
     EXPECT_VALID(Api::CheckIsolateState(isolate));
     timer1.Stop();
-    OS::PrintErr("Without Snapshot: %"Pd64"us\n", timer1.TotalElapsedTime());
+    OS::PrintErr("Without Snapshot: %" Pd64 "us\n", timer1.TotalElapsedTime());
 
     // Write snapshot with object content.
     FullSnapshotWriter writer(&buffer, &malloc_allocator);
@@ -1024,7 +1024,7 @@
   {
     Dart_EnterScope();  // Start a Dart API scope for invoking API functions.
     timer2.Stop();
-    OS::PrintErr("From Snapshot: %"Pd64"us\n", timer2.TotalElapsedTime());
+    OS::PrintErr("From Snapshot: %" Pd64 "us\n", timer2.TotalElapsedTime());
 
     // Invoke a function which returns an object.
     Dart_Handle cls = Dart_GetClass(TestCase::lib(),
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 163e653..0a97d0b 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -27,7 +27,7 @@
 
 
 void StackFrame::Print() const {
-  OS::Print("[%-8s : sp(%#"Px") ]\n", GetName(), sp());
+  OS::Print("[%-8s : sp(%#" Px ") ]\n", GetName(), sp());
 }
 
 
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index d35b1c1..22b970a 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -286,24 +286,24 @@
     symbol_table = Dart::vm_isolate()->object_store()->symbol_table();
     table_size = symbol_table.Length() - 1;
     used ^= symbol_table.At(table_size);
-    OS::Print("VM Isolate: Number of symbols : %"Pd"\n", used.Value());
-    OS::Print("VM Isolate: Symbol table capacity : %"Pd"\n", table_size);
+    OS::Print("VM Isolate: Number of symbols : %" Pd "\n", used.Value());
+    OS::Print("VM Isolate: Symbol table capacity : %" Pd "\n", table_size);
 
     // Now dump regular isolate symbol table stats.
     symbol_table = Isolate::Current()->object_store()->symbol_table();
     table_size = symbol_table.Length() - 1;
     used ^= symbol_table.At(table_size);
-    OS::Print("Isolate: Number of symbols : %"Pd"\n", used.Value());
-    OS::Print("Isolate: Symbol table capacity : %"Pd"\n", table_size);
+    OS::Print("Isolate: Number of symbols : %" Pd "\n", used.Value());
+    OS::Print("Isolate: Symbol table capacity : %" Pd "\n", table_size);
 
     // Dump overall collision and growth counts.
-    OS::Print("Number of symbol table grows = %"Pd"\n", num_of_grows_);
+    OS::Print("Number of symbol table grows = %" Pd "\n", num_of_grows_);
     OS::Print("Collision counts on add and lookup :\n");
     intptr_t i = 0;
     for (i = 0; i < (kMaxCollisionBuckets - 1); i++) {
-      OS::Print("  %"Pd" collisions => %"Pd"\n", i, collision_count_[i]);
+      OS::Print("  %" Pd " collisions => %" Pd "\n", i, collision_count_[i]);
     }
-    OS::Print("  > %"Pd" collisions => %"Pd"\n", i, collision_count_[i]);
+    OS::Print("  > %" Pd " collisions => %" Pd "\n", i, collision_count_[i]);
   }
 }
 
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index c39133e..c892cbe 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -375,6 +375,9 @@
   static const String& At() {
     return *(symbol_handles_[kNullCharId + '@']);
   }
+  static const String& Semicolon() {
+    return *(symbol_handles_[kNullCharId + ';']);
+  }
 
   // Access methods for symbol handles stored in the vm isolate.
 #define DEFINE_SYMBOL_HANDLE_ACCESSOR(symbol, literal)                         \
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index db850f4..ff8b563 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -53,7 +53,7 @@
 
     // Check whether this attempt falls within the exptected time limits.
     int64_t wakeup_time = stop - start;
-    OS::Print("wakeup_time: %"Pd64"\n", wakeup_time);
+    OS::Print("wakeup_time: %" Pd64 "\n", wakeup_time);
     const int kAcceptableTimeJitter = 20;  // Measured in milliseconds.
     const int kAcceptableWakeupDelay = 150;  // Measured in milliseconds.
     if (((wait_time - kAcceptableTimeJitter) <= wakeup_time) &&
diff --git a/runtime/vm/timer.cc b/runtime/vm/timer.cc
index 96c3224..d428af7 100644
--- a/runtime/vm/timer.cc
+++ b/runtime/vm/timer.cc
@@ -26,7 +26,7 @@
 
 #define TIMER_FIELD_REPORT(name, msg)                                          \
   if (name().enabled() && name().message() != NULL) {                          \
-    OS::Print("%s %"Pd64" micros.\n",                                          \
+    OS::Print("%s %" Pd64 " micros.\n",                                        \
               name().message(),                                                \
               name().TotalElapsedTime());                                      \
   }
diff --git a/runtime/vm/verifier.cc b/runtime/vm/verifier.cc
index ee6ac19..4270af2 100644
--- a/runtime/vm/verifier.cc
+++ b/runtime/vm/verifier.cc
@@ -32,7 +32,7 @@
     if (raw_obj->IsHeapObject()) {
       if (!allocated_set_->Contains(raw_obj)) {
         uword raw_addr = RawObject::ToAddr(raw_obj);
-        FATAL1("Invalid object pointer encountered %#"Px"\n", raw_addr);
+        FATAL1("Invalid object pointer encountered %#" Px "\n", raw_addr);
       }
     }
   }
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index 5b43216..f0c7c5d 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -114,7 +114,7 @@
 #if defined(DEBUG)
   ASSERT(size >= 0);
   if (FLAG_trace_zones) {
-    OS::PrintErr("*** Expanding zone 0x%"Px"\n",
+    OS::PrintErr("*** Expanding zone 0x%" Px "\n",
                  reinterpret_cast<intptr_t>(this));
     DumpZoneSizes();
   }
@@ -179,8 +179,8 @@
   for (Segment* s = large_segments_; s != NULL; s = s->next()) {
     size += s->size();
   }
-  OS::PrintErr("***   Zone(0x%"Px") size in bytes,"
-               " Total = %"Pd" Large Segments = %"Pd"\n",
+  OS::PrintErr("***   Zone(0x%" Px ") size in bytes,"
+               " Total = %" Pd " Large Segments = %" Pd "\n",
                reinterpret_cast<intptr_t>(this), SizeInBytes(), size);
 }
 #endif
diff --git a/runtime/vm/zone.h b/runtime/vm/zone.h
index f932db9..ff53c21 100644
--- a/runtime/vm/zone.h
+++ b/runtime/vm/zone.h
@@ -162,7 +162,7 @@
       zone_() {
 #ifdef DEBUG
     if (FLAG_trace_zones) {
-      OS::PrintErr("*** Starting a new Stack zone 0x%"Px"(0x%"Px")\n",
+      OS::PrintErr("*** Starting a new Stack zone 0x%" Px "(0x%" Px ")\n",
                    reinterpret_cast<intptr_t>(this),
                    reinterpret_cast<intptr_t>(&zone_));
     }
@@ -177,7 +177,7 @@
     isolate()->set_current_zone(zone_.previous_);
 #ifdef DEBUG
     if (FLAG_trace_zones) {
-      OS::PrintErr("*** Deleting Stack zone 0x%"Px"(0x%"Px")\n",
+      OS::PrintErr("*** Deleting Stack zone 0x%" Px "(0x%" Px ")\n",
                    reinterpret_cast<intptr_t>(this),
                    reinterpret_cast<intptr_t>(&zone_));
     }
@@ -204,7 +204,7 @@
 
   // Round up the requested size to fit the alignment.
   if (size > (kIntptrMax - kAlignment)) {
-    FATAL1("Zone::Alloc: 'size' is too large: size=%"Pd"", size);
+    FATAL1("Zone::Alloc: 'size' is too large: size=%" Pd "", size);
   }
   size = Utils::RoundUp(size, kAlignment);
 
@@ -227,7 +227,7 @@
 inline ElementType* Zone::Alloc(intptr_t len) {
   const intptr_t element_size = sizeof(ElementType);
   if (len > (kIntptrMax / element_size)) {
-    FATAL2("Zone::Alloc: 'len' is too large: len=%"Pd", element_size=%"Pd,
+    FATAL2("Zone::Alloc: 'len' is too large: len=%" Pd ", element_size=%" Pd,
            len, element_size);
   }
   return reinterpret_cast<ElementType*>(AllocUnsafe(len * element_size));
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index 7923de79..b15631a 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -170,14 +170,10 @@
         // directly. In effect, we don't support truly asynchronous API.
         text = deprecatedFutureValue(provider(resourceUri));
       } catch (exception) {
-        if (node != null) {
-          cancel("$exception", node: node);
-        } else {
-          reportError(
-              null,
-              leg.MessageKind.GENERIC, {'text': 'Error: $exception'});
-          throw new leg.CompilerCancelledException("$exception");
-        }
+        reportError(node,
+                    leg.MessageKind.READ_SCRIPT_ERROR,
+                    {'uri': readableUri, 'exception': exception});
+        return null;
       }
       SourceFile sourceFile = new SourceFile(resourceUri.toString(), text);
       // We use [readableUri] as the URI for the script since need to preserve
@@ -216,34 +212,23 @@
         }
       }
       if (!allowInternalLibraryAccess) {
-        if (node != null && importingLibrary != null) {
+        if (importingLibrary != null) {
           reportError(
               node,
-              leg.MessageKind.GENERIC,
-              {'text':
-                  'Error: Internal library $resolvedUri is not accessible from '
-                  '${importingLibrary.canonicalUri}.'});
+              leg.MessageKind.INTERNAL_LIBRARY_FROM,
+              {'resolvedUri': resolvedUri,
+               'importingUri': importingLibrary.canonicalUri});
         } else {
           reportError(
-              null,
-              leg.MessageKind.GENERIC,
-              {'text':
-                  'Error: Internal library $resolvedUri is not accessible.'});
+              node,
+              leg.MessageKind.INTERNAL_LIBRARY,
+              {'resolvedUri': resolvedUri});
         }
       }
     }
     if (path == null) {
-      if (node != null) {
-        reportFatalError(
-            node,
-            leg.MessageKind.GENERIC,
-            {'text': 'Error: Library not found ${resolvedUri}.'});
-      } else {
-        reportFatalError(
-            null,
-            leg.MessageKind.GENERIC,
-            {'text': 'Error: Library not found ${resolvedUri}.'});
-      }
+      reportError(node, leg.MessageKind.LIBRARY_NOT_FOUND,
+                  {'resolvedUri': resolvedUri});
       return null;
     }
     if (resolvedUri.path == 'html' ||
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index b0061d9..432292e 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -264,7 +264,7 @@
   bool isClosure() => closureElement != null;
 
   bool isVariableCaptured(Element element) {
-    freeVariableMapping.containsKey(element);
+    return freeVariableMapping.containsKey(element);
   }
 
   bool isVariableBoxed(Element element) {
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index c5d9bb0..91ee72a 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -245,7 +245,7 @@
 
   void registerStaticUse(Element element, Enqueuer enqueuer) {}
 
-  void onLibraryScanned(LibraryElement library, Uri uri) {}
+  void onLibraryLoaded(LibraryElement library, Uri uri) {}
 
   void registerMetadataInstantiatedType(DartType type, TreeElements elements) {}
   void registerMetadataStaticUse(Element element) {}
@@ -754,7 +754,7 @@
    * This method is called before [library] import and export scopes have been
    * set up.
    */
-  void onLibraryScanned(LibraryElement library, Uri uri) {
+  void onLibraryLoaded(LibraryElement library, Uri uri) {
     if (dynamicClass != null) {
       // When loading the built-in libraries, dynamicClass is null. We
       // take advantage of this as core imports js_helper and sees [dynamic]
@@ -775,8 +775,14 @@
     } else if (uri == new Uri(scheme: 'dart', path: 'async')) {
       deferredLibraryClass =
           findRequiredElement(library, const SourceString('DeferredLibrary'));
+    } else if (isolateHelperLibrary == null
+	       && (uri == new Uri(scheme: 'dart', path: '_isolate_helper'))) {
+      isolateHelperLibrary = scanBuiltinLibrary('_isolate_helper');
+    } else if (foreignLibrary == null
+	       && (uri == new Uri(scheme: 'dart', path: '_foreign_helper'))) {
+      foreignLibrary = scanBuiltinLibrary('_foreign_helper');
     }
-    backend.onLibraryScanned(library, uri);
+    backend.onLibraryLoaded(library, uri);
   }
 
   Element findRequiredElement(LibraryElement library, SourceString name) {
@@ -885,9 +891,6 @@
   void scanBuiltinLibraries() {
     jsHelperLibrary = scanBuiltinLibrary('_js_helper');
     interceptorsLibrary = scanBuiltinLibrary('_interceptors');
-    foreignLibrary = scanBuiltinLibrary('_foreign_helper');
-    isolateHelperLibrary = scanBuiltinLibrary('_isolate_helper');
-
     assertMethod = jsHelperLibrary.find(const SourceString('assertHelper'));
     identicalFunction = coreLibrary.find(const SourceString('identical'));
 
diff --git a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
index 1af5315..b8a13a7 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
@@ -29,6 +29,7 @@
 import 'patch_parser.dart';
 import 'types/types.dart' as ti;
 import 'resolution/resolution.dart';
+import 'source_file.dart' show SourceFile;
 import 'js/js.dart' as js;
 import 'deferred_load.dart' show DeferredLoadTask;
 import 'types/container_tracer.dart' show ContainerTracer;
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
index 9f4c816..d9a6f1b 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -409,7 +409,8 @@
             && isSafeToRemoveTypeDeclarations(classMembers));
     renamePlaceholders(
         compiler, collector, renames, imports,
-        fixedMemberNames, shouldCutDeclarationTypes);
+        fixedMemberNames, shouldCutDeclarationTypes,
+        uniqueGlobalNaming: useMirrorHelperLibrary);
 
     // Sort elements.
     final sortedTopLevels = sortElements(topLevelElements);
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
index 6dc9ad8..73480bf 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
@@ -67,7 +67,8 @@
     Map<Node, String> renames,
     Map<LibraryElement, String> imports,
     Set<String> fixedMemberNames,
-    bool cutDeclarationTypes) {
+    bool cutDeclarationTypes,
+    {uniqueGlobalNaming: false}) {
   final Map<LibraryElement, Map<String, String>> renamed
       = new Map<LibraryElement, Map<String, String>>();
 
@@ -178,24 +179,34 @@
     rename = makeRenamer(generateUniqueName);
     renameElement = makeElementRenamer(rename, generateUniqueName);
 
-    // 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.
-    List<Set<Node>> allSortedLocals = new List<Set<Node>>();
-    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 > allSortedLocals.length) {
-        allSortedLocals.add(new Set<Node>());
+    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()));
       }
-      for (int i = 0; i < currentSortedNodes.length; i++) {
-        allSortedLocals[i].addAll(currentSortedNodes[i]);
+    } 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]);
+        }
       }
     }
 
@@ -217,7 +228,7 @@
       renamables.add(
           new MemberRenamable(memberName, identifiers, memberRenamer));
     });
-    for (Set<Node> localIdentifiers in allSortedLocals) {
+    for (Set<Node> localIdentifiers in allLocals) {
       renamables.add(new LocalRenamable(localIdentifiers, localRenamer));
     }
     renamables.sort((Renamable renamable1, Renamable renamable2) =>
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index ee46294..7a809b7 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -366,7 +366,9 @@
   }
 
   bool canBeUsedForGlobalOptimizations(Element element) {
-    if (element.isParameter() || element.isFieldParameter()) {
+    if (element.isParameter()
+        || element.isFieldParameter()
+        || element.isField()) {
       element = element.enclosingElement;
     }
     return !helpersUsed.contains(element.declaration);
@@ -638,7 +640,7 @@
         },
         includeSuperAndInjectedMembers: true);
     }
-    enqueuer.registerInstantiatedClass(cls, elements);
+    enqueueClass(enqueuer, cls, elements);
   }
 
   void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
@@ -660,11 +662,10 @@
       if (enqueuer.isResolutionQueue) {
         // TODO(9577): Make it so that these are not needed when there are no
         // native classes.
-        enqueuer.registerStaticUse(getNativeInterceptorMethod);
-        enqueuer.registerStaticUse(defineNativeMethodsFinishMethod);
-        enqueuer.registerStaticUse(initializeDispatchPropertyMethod);
-        enqueuer.registerInstantiatedClass(jsInterceptorClass,
-                                           compiler.globalDependencies);
+        enqueue(enqueuer, getNativeInterceptorMethod, elements);
+        enqueue(enqueuer, defineNativeMethodsFinishMethod, elements);
+        enqueue(enqueuer, initializeDispatchPropertyMethod, elements);
+        enqueueClass(enqueuer, jsInterceptorClass, compiler.globalDependencies);
       }
     }
 
@@ -675,24 +676,31 @@
           || cls == compiler.numClass) {
         // The backend will try to optimize number operations and use the
         // `iae` helper directly.
-        enqueuer.registerStaticUse(
-            compiler.findHelper(const SourceString('iae')));
+        enqueue(enqueuer,
+                compiler.findHelper(const SourceString('iae')),
+                elements);
       } else if (cls == compiler.listClass
                  || cls == compiler.stringClass) {
         // The backend will try to optimize array and string access and use the
         // `ioore` and `iae` helpers directly.
-        enqueuer.registerStaticUse(
-            compiler.findHelper(const SourceString('ioore')));
-        enqueuer.registerStaticUse(
-            compiler.findHelper(const SourceString('iae')));
+        enqueue(enqueuer,
+                compiler.findHelper(const SourceString('ioore')),
+                elements);
+        enqueue(enqueuer,
+                compiler.findHelper(const SourceString('iae')),
+                elements);
       } else if (cls == compiler.functionClass) {
-        enqueuer.registerInstantiatedClass(compiler.closureClass, elements);
+        enqueueClass(enqueuer, compiler.closureClass, elements);
       } else if (cls == compiler.mapClass) {
         // The backend will use a literal list to initialize the entries
         // of the map.
-        enqueuer.registerInstantiatedClass(compiler.listClass, elements);
-        enqueuer.registerInstantiatedClass(mapLiteralClass, elements);
+        enqueueClass(enqueuer, compiler.listClass, elements);
+        enqueueClass(enqueuer, mapLiteralClass, elements);
         enqueueInResolution(getMapMaker(), elements);
+      } else if (cls == compiler.boundClosureClass) {
+        // TODO(ngeoffray): Move the bound closure class in the
+        // backend.
+        enqueueClass(enqueuer, compiler.boundClosureClass, elements);
       }
     }
     ClassElement result = null;
@@ -703,8 +711,8 @@
                || cls == jsFixedArrayClass
                || cls == jsExtendableArrayClass) {
       addInterceptors(jsArrayClass, enqueuer, elements);
-      enqueuer.registerInstantiatedClass(jsFixedArrayClass, elements);
-      enqueuer.registerInstantiatedClass(jsExtendableArrayClass, elements);
+      enqueueClass(enqueuer, jsFixedArrayClass, elements);
+      enqueueClass(enqueuer, jsExtendableArrayClass, elements);
     } else if (cls == compiler.intClass || cls == jsIntClass) {
       addInterceptors(jsIntClass, enqueuer, elements);
       addInterceptors(jsNumberClass, enqueuer, elements);
@@ -731,11 +739,11 @@
   void registerUseInterceptor(Enqueuer enqueuer) {
     assert(!enqueuer.isResolutionQueue);
     if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return;
-    enqueuer.registerStaticUse(getNativeInterceptorMethod);
-    enqueuer.registerStaticUse(defineNativeMethodsFinishMethod);
-    enqueuer.registerStaticUse(initializeDispatchPropertyMethod);
     TreeElements elements = compiler.globalDependencies;
-    enqueuer.registerInstantiatedClass(jsPlainJavaScriptObjectClass, elements);
+    enqueue(enqueuer, getNativeInterceptorMethod, elements);
+    enqueue(enqueuer, defineNativeMethodsFinishMethod, elements);
+    enqueue(enqueuer, initializeDispatchPropertyMethod, elements);
+    enqueueClass(enqueuer, jsPlainJavaScriptObjectClass, elements);
     needToInitializeDispatchProperty = true;
   }
 
@@ -749,10 +757,14 @@
     if (jsIndexingBehaviorInterface != null) {
       world.registerIsCheck(jsIndexingBehaviorInterface.computeType(compiler),
                             elements);
-      world.registerStaticUse(
-          compiler.findHelper(const SourceString('isJsIndexable')));
-      world.registerStaticUse(
-          compiler.findInterceptor(const SourceString('dispatchPropertyName')));
+      enqueue(
+          world,
+          compiler.findHelper(const SourceString('isJsIndexable')),
+          elements);
+      enqueue(
+          world,
+          compiler.findInterceptor(const SourceString('dispatchPropertyName')),
+          elements);
     }
 
     if (compiler.enableTypeAssertions) {
@@ -774,7 +786,7 @@
   void registerCatchStatement(Enqueuer enqueuer, TreeElements elements) {
     void ensure(ClassElement classElement) {
       if (classElement != null) {
-        enqueuer.registerInstantiatedClass(classElement, elements);
+        enqueueClass(enqueuer, classElement, elements);
       }
     }
     enqueueInResolution(getExceptionUnwrapper(), elements);
@@ -835,7 +847,7 @@
     enqueue(enqueuer, getGetRuntimeTypeInfo(), elements);
     enqueue(enqueuer, getComputeSignature(), elements);
     enqueue(enqueuer, getGetRuntimeTypeArguments(), elements);
-    enqueuer.registerInstantiatedClass(compiler.listClass, elements);
+    enqueueClass(enqueuer, compiler.listClass, elements);
   }
 
   void registerRuntimeType(Enqueuer enqueuer, TreeElements elements) {
@@ -843,23 +855,21 @@
     enqueueInResolution(getSetRuntimeTypeInfo(), elements);
     enqueueInResolution(getGetRuntimeTypeInfo(), elements);
     registerGetRuntimeTypeArgument(elements);
-    compiler.enqueuer.resolution.registerInstantiatedClass(
-        compiler.listClass, elements);
+    enqueueClass(enqueuer, compiler.listClass, elements);
   }
 
   void registerTypeVariableExpression(TreeElements elements) {
     enqueueInResolution(getSetRuntimeTypeInfo(), elements);
     enqueueInResolution(getGetRuntimeTypeInfo(), elements);
     registerGetRuntimeTypeArgument(elements);
-    compiler.enqueuer.resolution.registerInstantiatedClass(
-        compiler.listClass, elements);
+    enqueueClass(compiler.enqueuer.resolution, compiler.listClass, elements);
     enqueueInResolution(getRuntimeTypeToString(), elements);
     enqueueInResolution(getCreateRuntimeType(), elements);
   }
 
   void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) {
     type = type.unalias(compiler);
-    world.registerInstantiatedClass(compiler.boolClass, elements);
+    enqueueClass(world, compiler.boolClass, elements);
     bool inCheckedMode = compiler.enableTypeAssertions;
     // [registerIsCheck] is also called for checked mode checks, so we
     // need to register checked mode helpers.
@@ -885,7 +895,7 @@
           enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements);
         }
       }
-      world.registerInstantiatedClass(compiler.listClass, elements);
+      enqueueClass(world, compiler.listClass, elements);
     }
     if (type is FunctionType) {
       enqueueInResolution(getCheckFunctionSubtype(), elements);
@@ -914,24 +924,20 @@
   void registerThrowNoSuchMethod(TreeElements elements) {
     enqueueInResolution(getThrowNoSuchMethod(), elements);
     // Also register the types of the arguments passed to this method.
-    compiler.enqueuer.resolution.registerInstantiatedClass(
-        compiler.listClass, elements);
-    compiler.enqueuer.resolution.registerInstantiatedClass(
-        compiler.stringClass, elements);
+    enqueueClass(compiler.enqueuer.resolution, compiler.listClass, elements);
+    enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, elements);
   }
 
   void registerThrowRuntimeError(TreeElements elements) {
     enqueueInResolution(getThrowRuntimeError(), elements);
     // Also register the types of the arguments passed to this method.
-    compiler.enqueuer.resolution.registerInstantiatedClass(
-        compiler.stringClass, elements);
+    enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, elements);
   }
 
   void registerAbstractClassInstantiation(TreeElements elements) {
     enqueueInResolution(getThrowAbstractClassInstantiationError(), elements);
     // Also register the types of the arguments passed to this method.
-    compiler.enqueuer.resolution.registerInstantiatedClass(
-        compiler.stringClass, elements);
+    enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, elements);
   }
 
   void registerFallThroughError(TreeElements elements) {
@@ -943,8 +949,7 @@
     enqueueInResolution(
         compiler.objectClass.lookupLocalMember(Compiler.NO_SUCH_METHOD),
         elements);
-    compiler.enqueuer.resolution.registerInstantiatedClass(
-        compiler.listClass, elements);
+    enqueueClass(compiler.enqueuer.resolution, compiler.listClass, elements);
   }
 
   void registerRequiredType(DartType type, Element enclosingElement) {
@@ -1016,6 +1021,7 @@
   // Therefore we need to collect the list of helpers the backend may
   // use.
   void enqueue(Enqueuer enqueuer, Element e, TreeElements elements) {
+    if (e == null) return;
     helpersUsed.add(e.declaration);
     enqueuer.addToWorkList(e);
     elements.registerDependency(e);
@@ -1027,14 +1033,25 @@
     enqueue(enqueuer, e, elements);
   }
 
+  void enqueueClass(Enqueuer enqueuer, Element cls, TreeElements elements) {
+    if (cls == null) return;
+    helpersUsed.add(cls.declaration);
+    // Both declaration and implementation may declare fields, so we
+    // add both to the list of helpers.
+    if (cls.declaration != cls.implementation) {
+      helpersUsed.add(cls.implementation);
+    }
+    enqueuer.registerInstantiatedClass(cls, elements);
+  }
+
   void registerConstantMap(TreeElements elements) {
     Element e = compiler.findHelper(const SourceString('ConstantMap'));
     if (e != null) {
-      compiler.enqueuer.resolution.registerInstantiatedClass(e, elements);
+      enqueueClass(compiler.enqueuer.resolution, e, elements);
     }
     e = compiler.findHelper(const SourceString('ConstantProtoMap'));
     if (e != null) {
-      compiler.enqueuer.resolution.registerInstantiatedClass(e, elements);
+      enqueueClass(compiler.enqueuer.resolution, e, elements);
     }
   }
 
@@ -1457,7 +1474,7 @@
     return false;
   }
 
-  void onLibraryScanned(LibraryElement library, Uri uri) {
+  void onLibraryLoaded(LibraryElement library, Uri uri) {
     if (uri == Uri.parse('dart:_js_mirrors')) {
       disableTreeShakingMarker =
           library.find(const SourceString('disableTreeShaking'));
diff --git a/sdk/lib/_internal/compiler/implementation/library_loader.dart b/sdk/lib/_internal/compiler/implementation/library_loader.dart
index 8f4f224..55031d2 100644
--- a/sdk/lib/_internal/compiler/implementation/library_loader.dart
+++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart
@@ -220,6 +220,7 @@
 class LibraryLoaderTask extends LibraryLoader {
   LibraryLoaderTask(Compiler compiler) : super(compiler);
   String get name => 'LibraryLoader';
+  List onLibraryLoadedCallbacks = [];
 
   final Map<String, LibraryElement> libraryNames =
       new LinkedHashMap<String, LibraryElement>();
@@ -234,6 +235,9 @@
           createLibrary(currentHandler, null, resolvedUri, node, canonicalUri);
       currentHandler.computeExports();
       currentHandler = null;
+      var workList = onLibraryLoadedCallbacks;
+      onLibraryLoadedCallbacks = [];
+      workList.forEach((f) => f());
       return library;
     });
   }
@@ -362,7 +366,9 @@
   void scanPart(Part part, Uri resolvedUri, LibraryElement library) {
     if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri);
     Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part);
+    if (readableUri == null) return;
     Script sourceScript = compiler.readScript(readableUri, part);
+    if (sourceScript == null) return;
     CompilationUnitElement unit =
         new CompilationUnitElementX(sourceScript, library);
     compiler.withCurrentElement(unit, () {
@@ -385,6 +391,7 @@
     Uri resolvedUri = base.resolve(tag.uri.dartString.slowToString());
     LibraryElement loadedLibrary =
         createLibrary(handler, library, resolvedUri, tag.uri, resolvedUri);
+    if (loadedLibrary == null) return;
     handler.registerDependency(library, tag, loadedLibrary);
 
     if (!loadedLibrary.hasLibraryName()) {
@@ -409,31 +416,32 @@
   LibraryElement createLibrary(LibraryDependencyHandler handler,
                                LibraryElement importingLibrary,
                                Uri resolvedUri, Node node, Uri canonicalUri) {
-    bool newLibrary = false;
+    // TODO(johnniwinther): Create erroneous library elements for missing
+    // libraries.
     Uri readableUri =
         compiler.translateResolvedUri(importingLibrary, resolvedUri, node);
     if (readableUri == null) return null;
-    LibraryElement createLibrary() {
-      newLibrary = true;
-      Script script = compiler.readScript(readableUri, node);
-      LibraryElement element = new LibraryElementX(script, canonicalUri);
-      handler.registerNewLibrary(element);
-      native.maybeEnableNative(compiler, element);
-      return element;
-    }
     LibraryElement library;
-    if (canonicalUri == null) {
-      library = createLibrary();
-    } else {
-      library = compiler.libraries.putIfAbsent(canonicalUri.toString(),
-                                               createLibrary);
+    if (canonicalUri != null) {
+      library = compiler.libraries[canonicalUri.toString()];
     }
-    if (newLibrary) {
+    if (library == null) {
+      Script script = compiler.readScript(readableUri, node);
+      if (script == null) return null;
+
+      library = new LibraryElementX(script, canonicalUri);
+      handler.registerNewLibrary(library);
+      native.maybeEnableNative(compiler, library);
+      if (canonicalUri != null) {
+        compiler.libraries[canonicalUri.toString()] = library;
+      }
+      
       compiler.withCurrentElement(library, () {
         compiler.scanner.scanLibrary(library);
         processLibraryTags(handler, library);
         handler.registerLibraryExports(library);
-        compiler.onLibraryScanned(library, resolvedUri);
+        onLibraryLoadedCallbacks.add(
+            () => compiler.onLibraryLoaded(library, resolvedUri));
       });
     }
     return library;
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index 724383c..5fc7944 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -119,10 +119,10 @@
 
   void processNativeClasses(Iterable<LibraryElement> libraries) {
     libraries.forEach(processNativeClassesInLibrary);
-    processNativeClassesInLibrary(compiler.isolateHelperLibrary);
-
+    if (compiler.isolateHelperLibrary != null) {
+      processNativeClassesInLibrary(compiler.isolateHelperLibrary);
+    }
     processSubclassesOfNativeClasses(libraries);
-
     if (!enableLiveTypeAnalysis) {
       nativeClasses.forEach((c) => enqueueClass(c, 'forced'));
       flushQueue();
diff --git a/sdk/lib/_internal/compiler/implementation/script.dart b/sdk/lib/_internal/compiler/implementation/script.dart
index b130616..f6cda01 100644
--- a/sdk/lib/_internal/compiler/implementation/script.dart
+++ b/sdk/lib/_internal/compiler/implementation/script.dart
@@ -5,10 +5,7 @@
 part of dart2js;
 
 class Script {
-  // TODO(kasperl): Once MockFile in tests/compiler/dart2js/parser_helper.dart
-  // implements SourceFile, we should be able to type the [file] field as
-  // such.
-  final file;
+  final SourceFile file;
 
   /**
    * The readable URI from which this script was loaded.
diff --git a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
index 4cbd641..3188a3e 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
@@ -38,8 +38,8 @@
     try {
       source = readAll(uriPathToNative(resourceUri.path));
     } on FileException catch (ex) {
-      throw 'Error: Cannot read "${relativize(cwd, resourceUri, isWindows)}" '
-            '(${ex.osError}).';
+      throw "Error reading '${relativize(cwd, resourceUri, isWindows)}' "
+            "(${ex.osError})";
     }
     dartCharactersRead += source.length;
     sourceFiles[resourceUri.toString()] = new SourceFile(
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 b9a50a2..449ae88 100644
--- a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
@@ -21,8 +21,6 @@
   FlatTypeMask(DartType base, int kind, bool isNullable)
       : this.internal(base, (kind << 1) | (isNullable ? 1 : 0));
 
-  FlatTypeMask.empty()
-      : this.internal(null, (EMPTY << 1) | 1);
   FlatTypeMask.exact(DartType base)
       : this.internal(base, (EXACT << 1) | 1);
   FlatTypeMask.subclass(DartType base)
@@ -30,8 +28,9 @@
   FlatTypeMask.subtype(DartType base)
       : this.internal(base, (SUBTYPE << 1) | 1);
 
-  FlatTypeMask.nonNullEmpty()
-      : this.internal(null, EMPTY << 1);
+  const FlatTypeMask.nonNullEmpty(): base = null, flags = 0;
+  const FlatTypeMask.empty() : base = null, flags = 1;
+
   FlatTypeMask.nonNullExact(DartType base)
       : this.internal(base, EXACT << 1);
   FlatTypeMask.nonNullSubclass(DartType base)
diff --git a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart b/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
index 00c9295..e835be0 100644
--- a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
@@ -79,6 +79,12 @@
    * Adds [newType] as an input of [phiType].
    */
   T addPhiInput(Element element, T phiType, T newType);
+
+  /**
+   * Returns a new receiver type for this [selector] applied to
+   * [receiverType].
+   */
+  T refineReceiver(Selector selector, T receiverType);
 }
 
 /**
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 6fe350d..519d1fd 100644
--- a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
@@ -122,6 +122,15 @@
   TypeMask simplifyPhi(Node node, Element element, TypeMask phiType) {
     return phiType;
   }
+
+  TypeMask refineReceiver(Selector selector, TypeMask receiverType) {
+    // If the receiver is based on an element, we let the type
+    // inferrer handle it. Otherwise, we might prevent it from finding
+    // one-level cycles in the inference graph.
+    if (receiverType.isElement) return receiverType;
+    TypeMask newType = compiler.world.allFunctions.receiverType(selector);
+    return receiverType.intersection(newType, compiler);
+  }
 }
 
 /**
@@ -1582,6 +1591,7 @@
   SideEffects sideEffects = new SideEffects.empty();
   final Element outermostElement;
   final InferrerEngine<T> inferrer;
+  final Set<Element> capturedVariables = new Set<Element>();
 
   SimpleTypeInferrerVisitor.internal(analyzedElement,
                                      this.outermostElement,
@@ -1735,11 +1745,14 @@
     // same as [newType].
     ClosureClassMap nestedClosureData =
         compiler.closureToClassMapper.getMappingForNestedFunction(node);
-    nestedClosureData.forEachNonBoxedCapturedVariable((variable, field) {
-      // The type may be null for instance contexts: the 'this'
-      // variable and type parameters.
-      if (locals.locals[variable] == null) return;
-      inferrer.recordType(field, locals.locals[variable]);
+    nestedClosureData.forEachCapturedVariable((variable, field) {
+      if (!nestedClosureData.isVariableBoxed(variable)) {
+        // The type may be null for instance contexts: the 'this'
+        // variable and type parameters.
+        if (locals.locals[variable] == null) return;
+        inferrer.recordType(field, locals.locals[variable]);
+      }
+      capturedVariables.add(variable);
     });
 
     return types.functionType;
@@ -2164,17 +2177,32 @@
 
   T handleDynamicSend(Node node,
                       Selector selector,
-                      T receiver,
+                      T receiverType,
                       ArgumentsTypes arguments,
                       [CallSite constraint]) {
-    if (selector.mask != receiver) {
-      selector = (receiver == types.dynamicType)
+    if (selector.mask != receiverType) {
+      selector = (receiverType == types.dynamicType)
           ? selector.asUntyped
-          : types.newTypedSelector(receiver, selector);
+          : types.newTypedSelector(receiverType, selector);
       updateSelectorInTree(node, selector);
     }
+
+    // If the receiver of the call is a local, we may know more about
+    // its type by refining it with the potential targets of the
+    // calls. 
+    if (node.asSend() != null) {
+      Node receiver = node.asSend().receiver;
+      if (receiver != null) {
+        Element element = elements[receiver];
+        if (Elements.isLocal(element) && !capturedVariables.contains(element)) {
+          T refinedType = types.refineReceiver(selector, receiverType);
+          locals.update(element, refinedType, node);
+        }
+      }
+    }
+
     return inferrer.registerCalledSelector(
-        node, selector, receiver, outermostElement, arguments,
+        node, selector, receiverType, outermostElement, arguments,
         constraint, sideEffects, inLoop);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index 334b520..47bd8bf 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -13,14 +13,13 @@
   factory TypeMask(DartType base, int kind, bool isNullable)
       => new FlatTypeMask(base, kind, isNullable);
 
-  factory TypeMask.empty() => new FlatTypeMask.empty();
+  const factory TypeMask.empty() = FlatTypeMask.empty;
 
   factory TypeMask.exact(DartType base) => new FlatTypeMask.exact(base);
   factory TypeMask.subclass(DartType base) => new FlatTypeMask.subclass(base);
   factory TypeMask.subtype(DartType base) => new FlatTypeMask.subtype(base);
 
-  factory TypeMask.nonNullEmpty()
-      => new FlatTypeMask.nonNullEmpty();
+  const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty;
   factory TypeMask.nonNullExact(DartType base)
       => new FlatTypeMask.nonNullExact(base);
   factory TypeMask.nonNullSubclass(DartType base)
diff --git a/sdk/lib/_internal/compiler/implementation/universe/function_set.dart b/sdk/lib/_internal/compiler/implementation/universe/function_set.dart
index 6d3f4b7..a228736 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/function_set.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/function_set.dart
@@ -49,20 +49,28 @@
    * that may be invoked with the given [selector].
    */
   Iterable<Element> filter(Selector selector) {
+    return query(selector).functions;
+  }
+
+  TypeMask receiverType(Selector selector) {
+    return query(selector).computeMask(compiler);
+  }
+
+  FunctionSetQuery query(Selector selector) {
     SourceString name = selector.name;
     FunctionSetNode node = nodes[name];
     FunctionSetNode noSuchMethods = nodes[Compiler.NO_SUCH_METHOD];
     if (node != null) {
-      return node.query(selector, compiler, noSuchMethods).functions;
+      return node.query(selector, compiler, noSuchMethods);
     }
     // If there is no method that matches [selector] we know we can
     // only hit [:noSuchMethod:].
-    if (noSuchMethods == null) return const <Element>[];
+    if (noSuchMethods == null) return const FunctionSetQuery(const <Element>[]);
     selector = (selector.mask == null)
         ? compiler.noSuchMethodSelector
         : new TypedSelector(selector.mask, compiler.noSuchMethodSelector);
 
-    return noSuchMethods.query(selector, compiler, null).functions;
+    return noSuchMethods.query(selector, compiler, null);
   }
 
   void forEach(Function action) {
@@ -186,11 +194,41 @@
   FunctionSetQuery newQuery(Iterable<Element> functions,
                             Selector selector,
                             Compiler compiler) {
-    return new FunctionSetQuery(functions);
+    return new FullFunctionSetQuery(functions);
   }
 }
 
 class FunctionSetQuery {
   final Iterable<Element> functions;
+  TypeMask computeMask(Compiler compiler) => const TypeMask.nonNullEmpty();
   const FunctionSetQuery(this.functions);
 }
+
+class FullFunctionSetQuery extends FunctionSetQuery {
+  TypeMask _mask;
+
+  /**
+   * Compute the type of all potential receivers of this function set.
+   */
+  TypeMask computeMask(Compiler compiler) {
+    if (_mask != null) return _mask;
+    return _mask = new TypeMask.unionOf(functions
+        .expand((element) {
+          ClassElement cls = element.getEnclosingClass();
+          return compiler.world.isUsedAsMixin(cls)
+              ? ([cls]..addAll(compiler.world.mixinUses[cls]))
+              : [cls];
+        })
+        .map((cls) {
+          if (compiler.backend.isNullImplementation(cls)) {
+            return const TypeMask.empty();
+          }
+          return compiler.world.hasSubclasses(cls)
+              ? new TypeMask.nonNullSubclass(cls.rawType)
+              : new TypeMask.nonNullExact(cls.rawType);
+        }),
+        compiler);
+  }
+
+  FullFunctionSetQuery(functions) : super(functions);
+}
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 803d5a9..7edacfa 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -631,6 +631,16 @@
   static const MessageKind PACKAGE_ROOT_NOT_SET = const MessageKind(
       'Error: Cannot resolve "#{uri}". Package root has not been set.');
 
+  static const MessageKind INTERNAL_LIBRARY_FROM = const MessageKind(
+      'Error: Internal library "#{resolvedUri}" is not accessible from '
+      '"#{importingUri}".');
+
+  static const MessageKind INTERNAL_LIBRARY = const MessageKind(
+      'Error: Internal library "#{resolvedUri}" is not accessible.');
+
+  static const MessageKind LIBRARY_NOT_FOUND = const MessageKind(
+      'Error: Library not found "#{resolvedUri}".');
+
   static const MessageKind UNSUPPORTED_EQ_EQ_EQ = const MessageKind(
       'Error: "===" is not an operator. '
       'Did you mean "#{lhs} == #{rhs}" or "identical(#{lhs}, #{rhs})"?');
@@ -742,6 +752,16 @@
 main() {}
 """]);
 
+  static const MessageKind READ_SCRIPT_ERROR = const MessageKind(
+      "Error: Can't read '#{uri}' (#{exception}).",
+      examples: const [
+          """
+// 'foo.dart' does not exist.
+import 'foo.dart';
+
+main() {}
+"""]);
+
   static const MessageKind COMPILER_CRASHED = const MessageKind(
       'Error: The compiler crashed when compiling this element.');
 
diff --git a/sdk/lib/_internal/compiler/implementation/world.dart b/sdk/lib/_internal/compiler/implementation/world.dart
index 9bcc17f..2382113 100644
--- a/sdk/lib/_internal/compiler/implementation/world.dart
+++ b/sdk/lib/_internal/compiler/implementation/world.dart
@@ -47,6 +47,11 @@
     return _typesImplementedBySubclasses[cls.declaration];
   }
 
+  bool hasSubclasses(ClassElement cls) {
+    Set<ClassElement> subclasses = compiler.world.subclassesOf(cls);
+    return subclasses != null && !subclasses.isEmpty;
+  }
+
   World(Compiler compiler)
       : allFunctions = new FunctionSet(compiler),
         this.compiler = compiler;
diff --git a/sdk/lib/_internal/lib/interceptors.dart b/sdk/lib/_internal/lib/interceptors.dart
index fedc0f6..c40b797 100644
--- a/sdk/lib/_internal/lib/interceptors.dart
+++ b/sdk/lib/_internal/lib/interceptors.dart
@@ -365,7 +365,7 @@
 /**
  * The interceptor class for [Null].
  *
- * This class defines implementations for *all* methods on [Object] since the
+ * This class defines implementations for *all* methods on [Object] since
  * the methods on Object assume the receiver is non-null.  This means that
  * JSNull will always be in the interceptor set for methods defined on Object.
  */
diff --git a/sdk/lib/_internal/lib/io_patch.dart b/sdk/lib/_internal/lib/io_patch.dart
index e41a2ce..4216317 100644
--- a/sdk/lib/_internal/lib/io_patch.dart
+++ b/sdk/lib/_internal/lib/io_patch.dart
@@ -163,7 +163,13 @@
     throw new UnsupportedError("Platform._localHostname");
   }
   patch static _executable() {
-    throw new UnsupportedError("Platform_Executable");
+    throw new UnsupportedError("Platform._executable");
+  }
+  patch static List<String> _executableArguments() {
+    throw new UnsupportedError("Platform._executableArguments");
+  }
+  patch static String _packageRoot() {
+    throw new UnsupportedError("Platform._packageRoot");
   }
   patch static _environment() {
     throw new UnsupportedError("Platform._environment");
diff --git a/sdk/lib/_internal/pub/lib/src/command/list_package_dirs.dart b/sdk/lib/_internal/pub/lib/src/command/list_package_dirs.dart
index ea5b140..fc05630 100644
--- a/sdk/lib/_internal/pub/lib/src/command/list_package_dirs.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/list_package_dirs.dart
@@ -8,6 +8,8 @@
 import 'dart:io';
 import 'dart:json' as json;
 
+import 'package:path/path.dart' as path;
+
 import '../command.dart';
 import '../exit_codes.dart' as exit_codes;
 import '../log.dart' as log;
@@ -32,14 +34,26 @@
     }
 
     var output = {};
+
+    // Include the local paths to all locked packages.
+    var packages = {};
     var futures = [];
     entrypoint.loadLockFile().packages.forEach((name, package) {
       var source = entrypoint.cache.sources[package.source];
       futures.add(source.getDirectory(package).then((packageDir) {
-        output[name] = packageDir;
+        packages[name] = path.join(packageDir, "lib");
       }));
     });
 
+    output["packages"] = packages;
+
+    // Include the self link.
+    packages[entrypoint.root.name] = path.join(entrypoint.root.dir, "lib");
+
+    // Include the file(s) which when modified will affect the results. For pub,
+    // that's just the lockfile.
+    output["input_files"] = [entrypoint.lockFilePath];
+
     return Future.wait(futures).then((_) {
       log.message(json.stringify(output));
     });
diff --git a/sdk/lib/_internal/pub/lib/src/entrypoint.dart b/sdk/lib/_internal/pub/lib/src/entrypoint.dart
index 9ec81ec..aec7cf9 100644
--- a/sdk/lib/_internal/pub/lib/src/entrypoint.dart
+++ b/sdk/lib/_internal/pub/lib/src/entrypoint.dart
@@ -54,7 +54,10 @@
   String get packagesDir => path.join(root.dir, 'packages');
 
   /// `true` if the entrypoint package currently has a lock file.
-  bool get lockFileExists => entryExists(_lockFilePath);
+  bool get lockFileExists => entryExists(lockFilePath);
+
+  /// The path to the entrypoint package's lockfile.
+  String get lockFilePath => path.join(root.dir, 'pubspec.lock');
 
   /// Ensures that the package identified by [id] is installed to the directory.
   /// Returns the resolved [PackageId].
@@ -150,7 +153,7 @@
   /// exists. If it doesn't, this completes to an empty [LockFile].
   LockFile loadLockFile() {
     if (!lockFileExists) return new LockFile.empty();
-    return new LockFile.load(_lockFilePath, cache.sources);
+    return new LockFile.load(lockFilePath, cache.sources);
   }
 
   /// Determines whether or not the lockfile is out of date with respect to the
@@ -183,9 +186,6 @@
     return true;
   }
 
-  /// The path to the entrypoint package's lockfile.
-  String get _lockFilePath => path.join(root.dir, 'pubspec.lock');
-
   /// Saves a list of concrete package versions to the `pubspec.lock` file.
   void _saveLockFile(List<PackageId> packageIds) {
     var lockFile = new LockFile.empty();
diff --git a/sdk/lib/_internal/pub/lib/src/pub_package_provider.dart b/sdk/lib/_internal/pub/lib/src/pub_package_provider.dart
index 0c43571..0e2c51b 100644
--- a/sdk/lib/_internal/pub/lib/src/pub_package_provider.dart
+++ b/sdk/lib/_internal/pub/lib/src/pub_package_provider.dart
@@ -46,9 +46,6 @@
   /// Gets the root directory of [package].
   String getPackageDir(String package) => _packageDirs[package];
 
-  // TODO(rnystrom): Actually support transformers.
-  Iterable<Iterable<Transformer>> getTransformers(String package) => [];
-
   Future<Asset> getAsset(AssetId id) {
     var file = path.join(_packageDirs[id.package], id.path);
     return new Future.value(new Asset.fromPath(id, file));
diff --git a/sdk/lib/_internal/pub/pub.status b/sdk/lib/_internal/pub/pub.status
index 7d8c4fb..951e99a 100644
--- a/sdk/lib/_internal/pub/pub.status
+++ b/sdk/lib/_internal/pub/pub.status
@@ -2,6 +2,11 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+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
+
 # Pub only runs on the VM, so just rule out all compilers.
 [ $compiler == dart2js || $compiler == dart2dart ]
 *: Skip
diff --git a/sdk/lib/_internal/pub/test/list_package_dirs/ignores_updated_pubspec_test.dart b/sdk/lib/_internal/pub/test/list_package_dirs/ignores_updated_pubspec_test.dart
index bc13c27..6d539a6 100644
--- a/sdk/lib/_internal/pub/test/list_package_dirs/ignores_updated_pubspec_test.dart
+++ b/sdk/lib/_internal/pub/test/list_package_dirs/ignores_updated_pubspec_test.dart
@@ -4,8 +4,7 @@
 
 import 'package:path/path.dart' as path;
 
-import '../../lib/src/exit_codes.dart' as exit_codes;
-
+import '../../lib/src/io.dart';
 import '../descriptor.dart' as d;
 import '../test_pub.dart';
 
@@ -32,9 +31,19 @@
       })
     ]).create();
 
+    // Note: Using canonicalize here because pub gets the path to the
+    // entrypoint package from the working directory, which has had symlinks
+    // resolve. On Mac, "/tmp" is actually a symlink to "/private/tmp", so we
+    // need to accomodate that.
     schedulePub(args: ["list-package-dirs", "--format=json"],
         outputJson: {
-          "foo": path.join(sandboxDir, "foo")
+          "packages": {
+            "foo": path.join(sandboxDir, "foo", "lib"),
+            "myapp": canonicalize(path.join(sandboxDir, appPath, "lib"))
+          },
+          "input_files": [
+            canonicalize(path.join(sandboxDir, appPath, "pubspec.lock"))
+          ]
         });
   });
 }
\ No newline at end of file
diff --git a/sdk/lib/_internal/pub/test/list_package_dirs/includes_dev_dependencies_test.dart b/sdk/lib/_internal/pub/test/list_package_dirs/includes_dev_dependencies_test.dart
index 60c7786..a5761d2 100644
--- a/sdk/lib/_internal/pub/test/list_package_dirs/includes_dev_dependencies_test.dart
+++ b/sdk/lib/_internal/pub/test/list_package_dirs/includes_dev_dependencies_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:path/path.dart' as path;
 
+import '../../lib/src/io.dart';
 import '../descriptor.dart' as d;
 import '../test_pub.dart';
 
@@ -26,9 +27,19 @@
 
     pubInstall();
 
+    // Note: Using canonicalize here because pub gets the path to the
+    // entrypoint package from the working directory, which has had symlinks
+    // resolve. On Mac, "/tmp" is actually a symlink to "/private/tmp", so we
+    // need to accomodate that.
     schedulePub(args: ["list-package-dirs", "--format=json"],
         outputJson: {
-          "foo": path.join(sandboxDir, "foo")
+          "packages": {
+            "foo": path.join(sandboxDir, "foo", "lib"),
+            "myapp": canonicalize(path.join(sandboxDir, appPath, "lib"))
+          },
+          "input_files": [
+            canonicalize(path.join(sandboxDir, appPath, "pubspec.lock"))
+          ]
         });
   });
 }
\ No newline at end of file
diff --git a/sdk/lib/_internal/pub/test/list_package_dirs/lists_dependency_directories_test.dart b/sdk/lib/_internal/pub/test/list_package_dirs/lists_dependency_directories_test.dart
index b3ac39b..0e8f9f3 100644
--- a/sdk/lib/_internal/pub/test/list_package_dirs/lists_dependency_directories_test.dart
+++ b/sdk/lib/_internal/pub/test/list_package_dirs/lists_dependency_directories_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:path/path.dart' as path;
 
+import '../../lib/src/io.dart';
 import '../descriptor.dart' as d;
 import '../test_pub.dart';
 
@@ -26,11 +27,21 @@
 
     pubInstall();
 
+    // Note: Using canonicalize here because pub gets the path to the
+    // entrypoint package from the working directory, which has had symlinks
+    // resolve. On Mac, "/tmp" is actually a symlink to "/private/tmp", so we
+    // need to accomodate that.
     schedulePub(args: ["list-package-dirs", "--format=json"],
         outputJson: {
-          "foo": path.join(sandboxDir, "foo"),
-          "bar": port.then((p) => path.join(sandboxDir, cachePath, "hosted",
-              "localhost%58$p", "bar-1.0.0"))
+          "packages": {
+            "foo": path.join(sandboxDir, "foo", "lib"),
+            "bar": port.then((p) => path.join(sandboxDir, cachePath, "hosted",
+                "localhost%58$p", "bar-1.0.0", "lib")),
+            "myapp": canonicalize(path.join(sandboxDir, appPath, "lib"))
+          },
+          "input_files": [
+            canonicalize(path.join(sandboxDir, appPath, "pubspec.lock"))
+          ]
         });
   });
 }
\ No newline at end of file
diff --git a/sdk/lib/async/timer.dart b/sdk/lib/async/timer.dart
index ff7b07e..ed8103f 100644
--- a/sdk/lib/async/timer.dart
+++ b/sdk/lib/async/timer.dart
@@ -4,30 +4,43 @@
 
 part of dart.async;
 
+/**
+ * A count-down timer that can be configured to fire once or repeatedly.
+ *
+ * The timer counts down from the specified duration to 0.
+ * When the timer reaches 0, the timer invokes the specified callback function.
+ * Use a periodic timer to repeatedly count down the same interval.
+ *
+ * A negative duration is treated the same as a duration of 0.
+ * If the duration is statically known to be 0, consider using [run].
+ *
+ * Frequently the duration is either a constant or computed as in the
+ * following example (taking advantage of the multiplication operator of
+ * the [Duration] class):
+ *
+ *     const TIMEOUT = const Duration(seconds: 3);
+ *     const ms = const Duration(milliseconds: 1);
+ *
+ *     startTimeout([int milliseconds]) {
+ *       var duration = milliseconds == null ? TIMEOUT : ms * milliseconds;
+ *       return new Timer(duration, handleTimeout);
+ *     }
+ *     void handleTimeout(Timer _) {  // callback function
+ *       ...
+ *     }
+ *
+ * Note: If Dart code using Timer is compiled to JavaScript, the finest
+ * granularity available in the browser is 4 milliseconds.
+ * 
+ * See [Stopwatch] for measuring elapsed time.
+ */
 abstract class Timer {
 
   /**
    * Creates a new timer.
    *
-   * The [callback] callback is invoked after the given [duration].
-   * A negative duration is treated similar to a duration of 0.
+   * The [callback] function is invoked after the given [duration].
    *
-   * If the [duration] is statically known to be 0, consider using [run].
-   *
-   * Frequently the [duration] is either a constant or computed as in the
-   * following example (taking advantage of the multiplication operator of
-   * the Duration class):
-   *
-   *     const TIMEOUT = const Duration(seconds: 3);
-   *     const ms = const Duration(milliseconds: 1);
-   *
-   *     startTimeout([int milliseconds]) {
-   *       var duration = milliseconds == null ? TIMEOUT : ms * milliseconds;
-   *       return new Timer(duration, handleTimeout);
-   *     }
-   *
-   * Note: If Dart code using Timer is compiled to JavaScript, the finest
-   * granularity available in the browser is 4 milliseconds.
    */
   factory Timer(Duration duration, void callback()) {
     return _Zone.current.createTimer(duration, callback);
@@ -37,7 +50,7 @@
    * Creates a new repeating timer.
    *
    * The [callback] is invoked repeatedly with [duration] intervals until
-   * canceled. A negative duration is treated similar to a duration of 0.
+   * canceled with the [cancel] function.
    */
   factory Timer.periodic(Duration duration,
                                   void callback(Timer timer)) {
diff --git a/sdk/lib/convert/encoding.dart b/sdk/lib/convert/encoding.dart
index 19989fb..0f6126c 100644
--- a/sdk/lib/convert/encoding.dart
+++ b/sdk/lib/convert/encoding.dart
@@ -9,8 +9,8 @@
  */
 // TODO(floitsch): dart:io already has an Encoding class. If we can't
 // consolitate them, we need to remove `Encoding` here.
-abstract class Encoding extends Codec<String, List<int>> {
-  const Encoding();
+abstract class _Encoding extends Codec<String, List<int>> {
+  const _Encoding();
 
   // TODO(floitsch): should we introduce a StringToByteEncoder and
   // a ByteToStringDecoder so that we have better typing?
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index 2f92ef4..80f7a78 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -22,7 +22,7 @@
  * A [Utf8Codec] encodes strings to utf-8 code units (bytes) and decodes
  * UTF-8 code units to strings.
  */
-class Utf8Codec extends Encoding {
+class Utf8Codec extends _Encoding {
   final bool _allowMalformed;
 
   /**
@@ -177,7 +177,7 @@
     for (stringIndex = start; stringIndex < end; stringIndex++) {
       int codeUnit = str.codeUnitAt(stringIndex);
       // ASCII has the same representation in UTF-8 and UTF-16.
-      if (codeUnit < _ONE_BYTE_LIMIT) {
+      if (codeUnit <= _ONE_BYTE_LIMIT) {
         if (_bufferIndex >= _buffer.length) break;
         _buffer[_bufferIndex++] = codeUnit;
       } else if (_isLeadSurrogate(codeUnit)) {
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index 89208f8..6cfe998 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -2,12 +2,121 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+/**
+ *
+ * Built-in types, collections,
+ * and other core functionality for every Dart program.
+ *
+ * Some classes in this library,
+ * such as [String] and [num],
+ * support Dart's built-in data types.
+ * Other classes provide data structures
+ * for managing collections of objects.
+ * And still other classes represent commonly used types of data
+ * such as URIs, dates, and times.
+ *
+ *
+ * ## Built-in types
+ *
+ * [String], [int], [double], [bool], [List], and [Map]
+ * provide support for Dart's built-in data types.
+ * To declare and initialize variables of these types, write:
+ *     String myString   = 'A sequence of characters.';
+ *     int meaningOfLife = 42;
+ *     double valueOfPi  = 3.141592;
+ *     bool visible      = true;
+ *     List superHeros   = [ 'Batman', 'Superman', 'Harry Potter' ];
+ *     Map sidekicks     = { 'Batman': 'Robin',
+ *                           'Superman': 'Lois Lane',
+ *                           'Harry Potter': 'Ron and Hermione' };
+ *
+ * ## Strings
+ *
+ * A [String] is immutable and represents a sequence of characters.
+ * [StringBuffer] provides a way to construct strings efficiently.
+ * 
+ * The Dart language uses the [String] and [StringBuffer]
+ * behind the scenes to implement string concatenation, interpolation,
+ * and other features.
+ *     String myString = 'Live on ';
+ *     String get palindrome => myString + myString.split('').reversed.join();
+ *
+ *
+ * ## Collections
+ *
+ * The dart:core library provides basic collections,
+ * such as [List], [Map], and [Set].
+ *
+ * * A [List] is an ordered collection of objects, with a length.
+ * Lists are sometimes called arrays.
+ * Use a List when you need to access objects by index.
+ *
+ * * A [Set] is an unordered collection of unique objects.
+ * You cannot get an item by index (position).
+ * Adding a duplicate item has no effect.
+ * Use a [Set] when you need to guarantee object uniqueness.
+ *
+ * * A [Map] is an unordered collection of key-value pairs.
+ * Maps are sometimes called associative arrays because
+ * maps associate a key to some value for easy retrieval.
+ * Keys are unique.
+ * Use a [Map] when you need to access objects
+ * by a unique identifier.
+ *
+ * In addition to these classes,
+ * dart:core contains [Iterable],
+ * an interface that defines functionality
+ * common in collections of objects.
+ * Examples include the ability
+ * to run a function on each element in the collection,
+ * to apply a test to each element, 
+ * to retrieve an object, and to determine length.
+ *
+ * Iterable is implemented by [List] and [Set],
+ * and used by [Map] for its lists of keys and values.
+ * 
+ * For other kinds of collections, check out the dart:collection library.
+ * 
+ * ## Date and time
+ *
+ * Use [DateTime] to represent a point in time
+ * and [Duration] to represent a span of time.
+ *
+ * You can create [DateTime] objects with constructors
+ * or by parsing a correctly formatted string.
+ *     DateTime now = new DateTime.now();
+ *     DateTime berlinWallFell = new DateTime(1989, 11, 9);
+ *     DateTime moonLanding = DateTime.parse("1969-07-20");
+ *
+ * Create a [Duration] object specifying the individual time units.
+ *     Duration timeRemaining = new Duration(hours:56, minutes:14);
+ *     
+ * ## Uri
+ *
+ * A [Uri] object represents a uniform resource identifier,
+ * which identifies a resource on the web.
+ *     Uri dartlang = Uri.parse('http://dartlang.org/');
+ *
+ * ## Other documentation
+ *
+ * For more information about how to use the built-in types, refer to
+ * [Built-in Types](http://www.dartlang.org/docs/dart-up-and-running/contents/ch02.html#built-in-types)
+ * in Chapter 2 of
+ * [Dart: Up and Running](http://www.dartlang.org/docs/dart-up-and-running/).
+ *
+ * Also, see
+ * [dart:core - Numbers, Collections, Strings, and More](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dartcore---strings-collections-and-more)
+ * for more coverage of classes in this package.
+ *
+ */
+
+
 library dart.core;
 
 import "dart:collection";
 import "dart:_collection-dev" hide Symbol;
 import "dart:_collection-dev" as _collection_dev;
-import "dart:utf" show codepointsToUtf8, decodeUtf8;
+import "dart:convert" show UTF8;
 
 part "bool.dart";
 part "comparable.dart";
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index e0509d6..39a5f2f 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -5,13 +5,92 @@
 part of dart.core;
 
 /**
- * A DateTime object represents a point in time.
+ * An instant in time, such as July 20, 1969, 8:18pm PST.
  *
- * It can represent time values that are at a distance of at most
- * 8,640,000,000,000,000ms (100,000,000 days) from epoch (1970-01-01 UTC). In
- * other words: [:millisecondsSinceEpoch.abs() <= 8640000000000000:].
+ * Create a DateTime object by using one of the constructors
+ * or by parsing a correctly formatted string,
+ * which complies with a subset of ISO 8601.
+ * Note that hours are specified between 0 and 23,
+ * as in a 24-hour clock.
+ * For example:
  *
- * Also see [Stopwatch] for means to measure time-spans.
+ *     DateTime now = new DateTime.now();
+ *     DateTime berlinWallFell = new DateTime(1989, 11, 9);
+ *     DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");  // 8:18pm
+ *
+ * A DateTime object is anchored either in the UTC time zone
+ * or in the local time zone of the current computer
+ * when the object is created.
+ *
+ * Once created, neither the value nor the time zone
+ * of a DateTime object may be changed.
+ *
+ * You can use properties to get
+ * the individual units of a DateTime object.
+ *
+ *     assert(berlinWallFell.month == 11);
+ *     assert(moonLanding.hour == 20);
+ *
+ * For convenience and readability,
+ * the DateTime class provides a constant for each day and month
+ * name&mdash;for example, [AUGUST] and [FRIDAY].
+ * You can use these constants to improve code readibility:
+ *
+ *     DateTime berlinWallFell = new DateTime(1989, DateTime.NOVEMBER, 9);
+ *     assert(berlinWallFell.month == DateTime.SATURDAY);
+ *
+ * Day and month values begin at 1, and the week starts on Monday.
+ * That is, the constants [JANUARY] and [MONDAY] are both 1.
+ *
+ * ## Working with UTC and local time
+ *
+ * A DateTime object is in the local time zone
+ * unless explicitly created in the UTC time zone.
+ *
+ *     DateTime dDay = new DateTime.utc(1944, 6, 6);
+ *    
+ * Use [isUtc] to determine whether a DateTime object is based in UTC.
+ * Use the methods [toLocal] and [toUtc]
+ * to get the equivalent date/time value specified in the other time zone.
+ * Use [timeZoneName] to get an abbreviated name of the time zone
+ * for the DateTime object.
+ * To find the difference
+ * between UTC and the time zone of a DateTime object
+ * call [timeZoneOffset].
+ *
+ * ## Comparing DateTime objects
+ *
+ * The DateTime class contains several handy methods,
+ * such as [isAfter], [isBefore], and [isAtSameMomentAs],
+ * for comparing DateTime objects.
+ *
+ *     assert(berlinWallFell.isAfter(moonLanding) == true);
+ *     assert(berlinWallFell.isBefore(moonLanding) == false);
+ *
+ * ## Using DateTime with Duration
+ *
+ * Use the [add] and [subtract] methods with a [Duration] object
+ * to create a new DateTime object based on another.
+ * For example, to find the date that is sixty days after today, write:
+ *
+ *     DateTime today = new DateTime.now();
+ *     DateTime sixtyDaysFromNow = today.add(new Duration(days: 60));
+ *
+ * To find out how much time is between two DateTime objects use
+ * [difference], which returns a [Duration] object:
+ *
+ *     Duration difference = berlinWallFell.difference(dDay);
+ *     assert(difference.inDays == 16592);
+ *
+ * ## Other resources
+ *
+ * See [Duration] to represent a span of time.
+ * See [Stopwatch] to measure timespans.
+ *
+ * The DateTime class does not provide internationalization.
+ * To internationalize your code, use
+ * the [intl](http://pub.dartlang.org/packages/intl) package.
+ *
  */
 class DateTime implements Comparable {
   // Weekday constants that are returned by [weekday] method:
@@ -40,24 +119,34 @@
   static const int MONTHS_PER_YEAR = 12;
 
   /**
-   * The milliseconds since 1970-01-01T00:00:00Z (UTC). This value is
-   * independent of the time zone.
+   * The number of milliseconds since
+   * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
    *
-   * See [Stopwatch] for means to measure time-spans.
+   * This value is independent of the time zone.
+   *
+   * This value is at most
+   * 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch.
+   * In other words: [:millisecondsSinceEpoch.abs() <= 8640000000000000:].
+   *
    */
   final int millisecondsSinceEpoch;
 
   /**
    * True if this [DateTime] is set to UTC time.
+   *
+   *     DateTime dDay = new DateTime.utc(1944, 6, 6);
+   *     assert(dDay.isUtc);
+   *
    */
   final bool isUtc;
 
   /**
-   * Constructs a [DateTime] instance based on the individual parts. The date is
-   * in the local time zone.
+   * Constructs a [DateTime] instance specified in the local time zone.
    *
-   * [month] and [day] are one-based. For example
-   * [:new DateTime(1938, 1, 10):] represents the 10th of January 1938.
+   * For example,
+   * to create a new DateTime object representing April 29, 2014, 6:04am:
+   *
+   *     DateTime annularEclipse = new DateTime(2014, DateTime.APRIL, 29, 6, 4);
    */
   // TODO(8042): This should be a redirecting constructor and not a factory.
   factory DateTime(int year,
@@ -72,12 +161,9 @@
   }
 
   /**
-   * Constructs a [DateTime] instance based on the individual parts. The date is
-   * in the UTC time zone.
+   * Constructs a [DateTime] instance specified in the UTC time zone.
    *
-   * [month] and [day] are one-based. For example
-   * [:new DateTime.utc(1938, 1, 10):] represents the 10th of January 1938 in
-   * Coordinated Universal Time.
+   *     DateTime dDay = new DateTime.utc(1944, DateTime.JUNE, 6);
    */
   // TODO(8042): This should be a redirecting constructor and not a factory.
   factory DateTime.utc(int year,
@@ -92,8 +178,11 @@
   }
 
   /**
-   * Constructs a new [DateTime] instance with current date time value in the
+   * Constructs a [DateTime] instance with current date and time in the
    * local time zone.
+   *
+   *     DateTime thisInstant = new DateTime.now();
+   *
    */
   // TODO(8042): This should be a redirecting constructor and not a factory.
   factory DateTime.now() { return new DateTime._now(); }
@@ -159,11 +248,13 @@
   static const int _MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;
 
   /**
-   * Constructs a new [DateTime] instance with the given [millisecondsSinceEpoch].
+   * Constructs a new [DateTime] instance
+   * with the given [millisecondsSinceEpoch].
+   *
    * If [isUtc] is false then the date is in the local time zone.
    *
    * The constructed [DateTime] represents
-   * 1970-01-01T00:00:00Z + [millisecondsSinceEpoch]ms in the given
+   * 1970-01-01T00:00:00Z + [millisecondsSinceEpoch] ms in the given
    * time zone (local or UTC).
    */
   // TODO(lrn): Have two constructors instead of taking an optional bool.
@@ -179,9 +270,14 @@
 
   /**
    * Returns true if [other] is a [DateTime] at the same moment and in the
-   * same timezone (UTC or local).
+   * same time zone (UTC or local).
    *
-   * See [isAtSameMomentAs] for a comparison that ignores the timezone.
+   *     DateTime dDayUtc   = new DateTime.utc(1944, DateTime.JUNE, 6);
+   *     DateTime dDayLocal = new DateTime(1944, DateTime.JUNE, 6);
+   *
+   *     assert(dDayUtc.isAtSameMomentAs(dDayLocal) == false);
+   *
+   * See [isAtSameMomentAs] for a comparison that adjusts for time zone.
    */
   bool operator ==(other) {
     if (!(other is DateTime)) return false;
@@ -190,38 +286,70 @@
   }
 
   /**
-   * Returns true if [this] occurs before [other]. The comparison is independent
+   * Returns true if [this] occurs before [other].
+   *
+   * The comparison is independent
    * of whether the time is in UTC or in the local time zone.
+   *
+   *     DateTime berlinWallFell = new DateTime(1989, 11, 9);
+   *     DateTime moonLanding    = DateTime.parse("1969-07-20 20:18:00");
+   *
+   *     assert(berlinWallFell.isBefore(moonLanding) == false);
+   *
    */
   bool isBefore(DateTime other) {
     return millisecondsSinceEpoch < other.millisecondsSinceEpoch;
   }
 
   /**
-   * Returns true if [this] occurs after [other]. The comparison is independent
+   * Returns true if [this] occurs after [other].
+   *
+   * The comparison is independent
    * of whether the time is in UTC or in the local time zone.
+   *
+   *     DateTime berlinWallFell = new DateTime(1989, 11, 9);
+   *     DateTime moonLanding    = DateTime.parse("1969-07-20 20:18:00");
+   *
+   *     assert(berlinWallFell.isAfter(moonLanding) == true);
+   *
    */
   bool isAfter(DateTime other) {
     return millisecondsSinceEpoch > other.millisecondsSinceEpoch;
   }
 
   /**
-   * Returns true if [this] occurs at the same moment as [other]. The
-   * comparison is independent of whether the time is in UTC or in the local
+   * Returns true if [this] occurs at the same moment as [other].
+   *
+   * The comparison is independent of whether the time is in UTC or in the local
    * time zone.
+   *
+   *     DateTime berlinWallFell = new DateTime(1989, 11, 9);
+   *     DateTime moonLanding    = DateTime.parse("1969-07-20 20:18:00");
+   *
+   *     assert(berlinWallFell.isAtSameMomentAs(moonLanding) == false);
    */
   bool isAtSameMomentAs(DateTime other) {
     return millisecondsSinceEpoch == other.millisecondsSinceEpoch;
   }
 
+  /**
+   * Compares this DateTime object to [other],
+   * returning zero if the values are equal.
+   *
+   * This function returns a negative integer
+   * if this DateTime is smaller (earlier) than [other],
+   * or a positive integer if it is greater (later).
+   */
   int compareTo(DateTime other)
       => millisecondsSinceEpoch.compareTo(other.millisecondsSinceEpoch);
 
   int get hashCode => millisecondsSinceEpoch;
 
   /**
-   * Returns [this] in the local time zone. Returns itself if it is already in
-   * the local time zone. Otherwise, this method is equivalent to
+   * Returns this DateTime value in the local time zone.
+   *
+   * Returns [this] if it is already in the local time zone.
+   * Otherwise this method is equivalent to:
    *
    *     new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
    *                                             isUtc: false)
@@ -235,8 +363,10 @@
   }
 
   /**
-   * Returns [this] in UTC. Returns itself if it is already in UTC. Otherwise,
-   * this method is equivalent to
+   * Returns this DateTime value in the UTC time zone.
+   *
+   * Returns [this] if it is already in UTC.
+   * Otherwise this method is equivalent to:
    *
    *     new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
    *                                             isUtc: true)
@@ -248,8 +378,13 @@
   }
 
   /**
-   * Returns a human readable string for this instance.
+   * Returns a human-readable string for this instance.
+   *
    * The returned string is constructed for the time zone of this instance.
+   * The `toString()` method provides a simply formatted string.
+   * It does not support internationalized strings.
+   * Use the [intl](http://pub.dartlang.org/packages/intl) package
+   * at the pub shared packages repo.
    */
   String toString() {
     String fourDigits(int n) {
@@ -286,21 +421,41 @@
     }
   }
 
-  /** Returns a new [DateTime] with the [duration] added to [this]. */
+  /**
+   * Returns a new [DateTime] instance with [duration] added to [this].
+   *
+   *     DateTime today = new DateTime.now();
+   *     DateTime sixtyDaysFromNow = today.add(new Duration(days: 60));
+   */
+
   DateTime add(Duration duration) {
     int ms = millisecondsSinceEpoch;
     return new DateTime.fromMillisecondsSinceEpoch(
         ms + duration.inMilliseconds, isUtc: isUtc);
   }
 
-  /** Returns a new [DateTime] with the [duration] subtracted from [this]. */
+  /**
+   * Returns a new [DateTime] instance with [duration] subtracted from [this].
+   *
+   *     DateTime today = new DateTime.now();
+   *     DateTime sixtyDaysAgo = today.subtract(new Duration(days: 60));
+   */
   DateTime subtract(Duration duration) {
     int ms = millisecondsSinceEpoch;
     return new DateTime.fromMillisecondsSinceEpoch(
         ms - duration.inMilliseconds, isUtc: isUtc);
   }
 
-  /** Returns a [Duration] with the difference of [this] and [other]. */
+  /**
+   * Returns a [Duration] with the difference between [this] and [other].
+   *
+   *     DateTime berlinWallFell = new DateTime(1989, DateTime.NOVEMBER, 9);
+   *     DateTime dDay = new DateTime(1944, DateTime.JUNE, 6);
+   *
+   *     Duration difference = berlinWallFell.difference(dDay);
+   *     assert(difference.inDays == 16592);
+   */
+
   Duration difference(DateTime other) {
     int ms = millisecondsSinceEpoch;
     int otherMs = other.millisecondsSinceEpoch;
@@ -321,15 +476,16 @@
       int millisecond, bool isUtc);
 
   /**
-   * Returns the abbreviated time-zone name.
-   *
-   * Examples: [:"CET":] or [:"CEST":].
+   * The abbreviated time zone name&mdash;for example,
+   * [:"CET":] or [:"CEST":].
    */
   external String get timeZoneName;
 
   /**
-   * The time-zone offset is the difference between local time and UTC. That is,
-   * the offset is positive for time zones west of UTC.
+   * The time zone offset, which
+   * is the difference between local time and UTC.
+   *
+   * The offset is positive for time zones west of UTC.
    *
    * Note, that JavaScript, Python and C return the difference between UTC and
    * local time. Java, C# and Ruby return the difference between local time and
@@ -338,43 +494,72 @@
   external Duration get timeZoneOffset;
 
   /**
-   * Returns the year.
+   * The year.
+   *
+   *     DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
+   *     assert(moonLanding.year == 1969);
    */
   external int get year;
 
   /**
-   * Returns the month into the year [1..12].
+   * The month [1..12].
+   *
+   *     DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
+   *     assert(moonLanding.month == 7);
+   *     assert(moonLanding.month == JULY);
    */
   external int get month;
 
   /**
-   * Returns the day into the month [1..31].
+   * The day of the month [1..31].
+   *
+   *     DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
+   *     assert(moonLanding.day == 20);
    */
   external int get day;
 
   /**
-   * Returns the hour into the day [0..23].
+   * The hour of the day, expressed as in a 24-hour clock [0..23].
+   *
+   *     DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
+   *     assert(moonLanding.hour == 20);
    */
   external int get hour;
 
   /**
-   * Returns the minute into the hour [0...59].
+   * The minute [0...59].
+   *
+   *     DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
+   *     assert(moonLanding.minute == 18);
    */
   external int get minute;
 
   /**
-   * Returns the second into the minute [0...59].
+   * The second [0...59].
+   *
+   *     DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
+   *     assert(moonLanding.second == 0);
    */
   external int get second;
 
   /**
-   * Returns the millisecond into the second [0...999].
+   * The millisecond [0...999].
+   *
+   *     DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
+   *     assert(moonLanding.millisecond == 0);
    */
   external int get millisecond;
 
   /**
-   * Returns the week day [MON..SUN]. In accordance with ISO 8601
-   * a week starts with Monday which has the value 1.
+   * The day of the week [MONDAY]..[SUNDAY].
+   *
+   * In accordance with ISO 8601
+   * a week starts with Monday, which has the value 1.
+   *
+   *     DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
+   *     assert(moonLanding.weekday == 7);
+   *     assert(moonLanding.weekday == DateTime.SUNDAY);
+   *
    */
   external int get weekday;
 }
diff --git a/sdk/lib/core/duration.dart b/sdk/lib/core/duration.dart
index a19c651..77633a6 100644
--- a/sdk/lib/core/duration.dart
+++ b/sdk/lib/core/duration.dart
@@ -5,7 +5,36 @@
 part of dart.core;
 
 /**
- * A [Duration] represents a time span. A duration can be negative.
+ * A span of time, such as 27 days, 4 hours, 12 minutes, and 3 seconds.
+ *
+ * To create a new Duration object, use this class's single constructor
+ * giving the appropriate arguments:
+ *
+ *     Duration fastestMarathon = new Duration(hours:2, minutes:3, seconds:2);
+ *
+ * The Duration is the sum of all individual parts.
+ * This means that individual parts can be larger than the next-bigger unit.
+ * For example, [minutes] can be greater than 59.
+ *
+ *     assert(fastestMarathon.inMinutes == 123);
+ *
+ * All individual parts are allowed to be negative.
+ *
+ * Use one of the properties, such as [inDays],
+ * to retrieve the integer value of the Duration in the specified time unit.
+ * Note that the returned value is rounded down.
+ * For example, 
+ *
+ *     Duration aLongWeekend = new Duration(hours:88);
+ *     assert(aLongWeekend.inDays == 3);
+ *
+ * This class provides a collection of arithmetic
+ * and comparison operators,
+ * plus a set of constants useful for converting time units.
+ *
+ * See [DateTime] to represent a point in time.
+ * See [Stopwatch] to measure time-spans.
+ *
  */
 class Duration implements Comparable<Duration> {
   static const int MICROSECONDS_PER_MILLISECOND = 1000;
@@ -38,18 +67,20 @@
 
   static const Duration ZERO = const Duration(seconds: 0);
 
-  /**
-   * This [Duration] in microseconds.
+  /*
+   * The value of this Duration object in microseconds.
    */
   final int _duration;
 
   /**
-   * The duration is the sum of all individual parts. This means that individual
-   * parts don't need to be less than the next-bigger unit. For example [hours]
-   * is allowed to have a value greater than 23.
+   * Creates a new Duration object whose value
+   * is the sum of all individual parts.
+   *
+   * Individual parts can be larger than the next-bigger unit.
+   * For example, [hours] can be greater than 23.
    *
    * All individual parts are allowed to be negative.
-   * All arguments are by default 0.
+   * All arguments are 0 by default.
    */
   const Duration({int days: 0,
                   int hours: 0,
@@ -65,23 +96,24 @@
                     microseconds;
 
   /**
-   * Returns the sum of this [Duration] and [other]  as a new [Duration].
+   * Adds this Duration and [other] and
+   * returns the sum as a new Duration object.
    */
   Duration operator +(Duration other) {
     return new Duration(microseconds: _duration + other._duration);
   }
 
   /**
-   * Returns the difference of this [Duration] and [other] as a new
-   * [Duration].
+   * Subtracts [other] from this Duration and
+   * returns the difference as a new Duration object.
    */
   Duration operator -(Duration other) {
     return new Duration(microseconds: _duration - other._duration);
   }
 
   /**
-   * Multiplies this [Duration] by the given [factor] and returns the result
-   * as a new [Duration].
+   * Multiplies this Duration by the given [factor] and returns the result
+   * as a new Duration object.
    *
    * Note that when [factor] is a double, and the duration is greater than
    * 53 bits, precision is lost because of double-precision arithmetic.
@@ -91,8 +123,8 @@
   }
 
   /**
-   * Divides this [Duration] by the given [quotient] and returns the truncated
-   * result as a new [Duration].
+   * Divides this Duration by the given [quotient] and returns the truncated
+   * result as a new Duration object.
    *
    * Throws an [IntegerDivisionByZeroException] if [quotient] is `0`.
    */
@@ -103,52 +135,71 @@
     return new Duration(microseconds: _duration ~/ quotient);
   }
 
+  /**
+   * Returns `true` if the value of this Duration
+   * is less than the value of [other].
+   */
   bool operator <(Duration other) => this._duration < other._duration;
 
+  /**
+   * Returns `true` if the value of this Duration
+   * is greater than the value of [other].
+   */
   bool operator >(Duration other) => this._duration > other._duration;
 
+  /**
+   * Returns `true` if the value of this Duration
+   * is less than or equal to the value of [other].
+   */
   bool operator <=(Duration other) => this._duration <= other._duration;
 
+  /**
+   * Returns `true` if the value of this Duration
+   * is greater than or equal to the value of [other].
+   */
   bool operator >=(Duration other) => this._duration >= other._duration;
 
   /**
-   * This [Duration] in days. Incomplete days are discarded
+   * Returns the number of whole days spanned by this Duration.
    */
   int get inDays => _duration ~/ Duration.MICROSECONDS_PER_DAY;
 
   /**
-   * This [Duration] in hours. Incomplete hours are discarded.
+   * Returns the number of whole hours spanned by this Duration.
    *
    * The returned value can be greater than 23.
    */
   int get inHours => _duration ~/ Duration.MICROSECONDS_PER_HOUR;
 
   /**
-   * This [Duration] in minutes. Incomplete minutes are discarded.
+   * Returns the number of whole minutes spanned by this Duration.
    *
    * The returned value can be greater than 59.
    */
   int get inMinutes => _duration ~/ Duration.MICROSECONDS_PER_MINUTE;
 
   /**
-   * This [Duration] in seconds. Incomplete seconds are discarded.
+   * Returns the number of whole seconds spanned by this Duration.
    *
    * The returned value can be greater than 59.
    */
   int get inSeconds => _duration ~/ Duration.MICROSECONDS_PER_SECOND;
 
   /**
-   * This [Duration] in milliseconds. Incomplete milliseconds are discarded.
+   * Returns number of whole milliseconds spanned by this Duration.
    *
    * The returned value can be greater than 999.
    */
   int get inMilliseconds => _duration ~/ Duration.MICROSECONDS_PER_MILLISECOND;
 
   /**
-   * This [Duration] in microseconds.
+   * Returns number of whole microseconds spanned by this Duration.
    */
   int get inMicroseconds => _duration;
 
+  /**
+   * Returns `true` if this Duration is the same object as [other].
+   */
   bool operator ==(other) {
     if (other is !Duration) return false;
     return _duration == other._duration;
@@ -156,6 +207,14 @@
 
   int get hashCode => _duration.hashCode;
 
+  /**
+   * Compares this Duration to [other],
+   * returning zero if the values are equal.
+   *
+   * This function returns a negative integer
+   * if this Duration is smaller than [other],
+   * or a positive integer if it is greater.
+   */
   int compareTo(Duration other) => _duration.compareTo(other._duration);
 
   String toString() {
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index dc0ccfa..af9f895 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -5,72 +5,66 @@
 part of dart.core;
 
 /**
- * A [List] is an indexable collection with a length.
+ * An indexable collection of objects with a length.
  *
- * A `List` implementation can choose not to support all methods
- * of the `List` interface.
+ * Subclasses of this class implement different kinds of lists.
+ * The most common kinds of lists are:
  *
- * The most common list types are:
- * * Fixed length list. It is an error to use operations that can change
- *   the list's length.
- * * Growable list. Full implementation of the interface.
- * * Unmodifiable list. It is an error to use operations that can change
- *   the list's length, or that can change the values of the list.
- *   If an unmodifable list is backed by another modifiable data structure,
- *   the values read from it may still change over time.
+ * * Fixed-length list.
+ *   An error occurs when attempting to use operations
+ *   that can change the length of the list.
  *
- * Example:
+ * * Growable list. Full implementation of the API defined in this class.
+ *
+ * The following code illustrates that some List implementations support
+ * only a subset of the API.
  *
  *     var fixedLengthList = new List(5);
- *     fixedLengthList.length = 0;  // throws.
- *     fixedLengthList.add(499);  // throws
+ *     fixedLengthList.length = 0;  // Error.
+ *     fixedLengthList.add(499);    // Error.
  *     fixedLengthList[0] = 87;
+ *
  *     var growableList = [1, 2];
  *     growableList.length = 0;
  *     growableList.add(499);
  *     growableList[0] = 87;
- *     var unmodifiableList = const [1, 2];
- *     unmodifiableList.length = 0;  // throws.
- *     unmodifiableList.add(499);  // throws
- *     unmodifiableList[0] = 87;  // throws.
  *
  * Lists are [Iterable].
- * List iteration iterates over values in index order.
- * Changing the values will not affect iteration,
- * but changing the valid indices -
- * that is, changing the list's length -
- * between iteration steps
- * will cause a [ConcurrentModificationError].
- * This means that only growable lists can throw [ConcurrentModificationError].
+ * Iteration occurs over values in index order.
+ * Changing the values does not affect iteration,
+ * but changing the valid indices&mdash;that is,
+ * changing the list's length&mdash;between
+ * iteration steps
+ * causes a [ConcurrentModificationError].
+ * This means that only growable lists can throw ConcurrentModificationError.
  * If the length changes temporarily
  * and is restored before continuing the iteration,
- * the iterator will not detect it.
+ * the iterator does not detect it.
  */
 abstract class List<E> implements Iterable<E> {
   /**
-   * Creates a list of the given [length].
+   * Creates a list of the given _length_.
    *
-   * The list is a fixed-length list if [length] is provided, and an empty
-   * growable list if [length] is omitted.
+   * The created list is fixed-length if _length_ is provided.
+   * The list has length 0 and is growable if _length_ is omitted.
    *
-   * It is an error if [length] is not a non-negative integer.
+   * An error occurs if _length_ is negative.
    */
   external factory List([int length]);
 
   /**
-   * Creates a fixed-length list of the given [length] where each entry
-   * contains [fill].
+   * Creates a fixed-length list of the given _length_
+   * and initializes the value at each position with [fill].
    */
   external factory List.filled(int length, E fill);
 
   /**
-   * Creates an list with the elements of [other].
+   * Creates a list and initializes it using the contents of [other].
    *
-   * The order in the list will be
-   * the order provided by the iterator of [other].
+   * The [Iterator] of [other] provides the order of the objects.
    *
-   * The returned list is growable if [growable] is true, otherwise it's
-   * a fixed length list.
+   * This constructor returns a growable list if [growable] is true;
+   * otherwise, it returns a fixed-length list.
    */
   factory List.from(Iterable other, { bool growable: true }) {
     List<E> list = new List<E>();
@@ -87,14 +81,14 @@
   }
 
   /**
-   * Generate a `List` of values.
+   * Generates a list of values.
    *
-   * Creates a list with [length] positions
-   * and fills them by values created by calling [generator]
-   * for each index in the range `0` .. `[length] - 1`
+   * Creates a list with _length_ positions
+   * and fills it with values created by calling [generator]
+   * for each index in the range `0` .. `length - 1`
    * in increasing order.
    *
-   * The created list's length is fixed unless [growable] is true.
+   * The created list is fixed-length unless [growable] is true.
    */
   factory List.generate(int length, E generator(int index),
                        { bool growable: true }) {
@@ -111,202 +105,202 @@
   }
 
   /**
-   * Returns the element at the given [index] in the list or throws
-   * an [RangeError] if [index] is out of bounds.
+   * Returns the object at the given [index] in the list
+   * or throws a [RangeError] if [index] is out of bounds.
    */
   E operator [](int index);
 
   /**
-   * Sets the entry at the given [index] in the list to [value].
-   *
-   * Throws an [RangeError] if [index] is out of bounds.
+   * Sets the value at the given [index] in the list to [value]
+   * or throws a [RangeError] if [index] is out of bounds.
    */
   void operator []=(int index, E value);
 
   /**
-   * Returns the number of elements in the list.
+   * Returns the number of objects in this list.
    *
-   * The valid indices for a list are 0 through `length - 1`.
+   * The valid indices for a list are `0` through `length - 1`.
    */
   int get length;
 
   /**
-   * Changes the length of the list. If [newLength] is greater than
+   * Changes the length of this list.
+   *
+   * If [newLength] is greater than
    * the current [length], entries are initialized to [:null:].
    *
-   * Throws an [UnsupportedError] if the list is not extendable.
+   * Throws an [UnsupportedError] if the list is fixed-length.
    */
   void set length(int newLength);
 
   /**
-   * Adds [value] at the end of the list, extending the length by
-   * one.
+   * Adds [value] to the end of this list,
+   * extending the length by one.
    *
-   * Throws an [UnsupportedError] if the list is not extendable.
+   * Throws an [UnsupportedError] if the list is fixed-length.
    */
   void add(E value);
 
   /**
-   * Appends all elements of the [iterable] to the end of this list.
+   * Appends all objects of [iterable] to the end of this list.
    *
-   * Extends the length of the list by the number of elements in [iterable].
-   * Throws an [UnsupportedError] if this list is not extensible.
+   * Extends the length of the list by the number of objects in [iterable].
+   * Throws an [UnsupportedError] if this list is fixed-length.
    */
   void addAll(Iterable<E> iterable);
 
   /**
-   * Returns an [Iterable] of the elements of this [List] in reverse order.
+   * Returns an [Iterable] of the objects in this list in reverse order.
    */
   Iterable<E> get reversed;
 
   /**
-   * Sorts the list according to the order specified by the [compare] function.
+   * Sorts this list according to the order specified by the [compare] function.
    *
    * The [compare] function must act as a [Comparator].
    *
-   * The default [List] implementations use [Comparable.compare] if
+   * The default List implementations use [Comparable.compare] if
    * [compare] is omitted.
    */
   void sort([int compare(E a, E b)]);
 
   /**
-   * Returns the first index of [element] in the list.
+   * Returns the first index of [element] in this list.
    *
    * Searches the list from index [start] to the length of the list.
-   * The first time an element [:e:] is encountered so that [:e == element:],
-   * the index of [:e:] is returned.
+   * The first time an object [:o:] is encountered so that [:o == element:],
+   * the index of [:o:] is returned.
    * Returns -1 if [element] is not found.
    */
   int indexOf(E element, [int start = 0]);
 
   /**
-   * Returns the last index of [element] in the list.
+   * Returns the last index of [element] in this list.
    *
-   * Searches the list backwards from index [start] (inclusive) to 0.
+   * Searches the list backwards from index [start] to 0.
    *
-   * The first time an element [:e:] is encountered so that [:e == element:],
-   * the index of [:e:] is returned.
+   * The first time an object [:o:] is encountered so that [:o == element:],
+   * the index of [:o:] is returned.
    *
-   * If start is not provided, it defaults to [:this.length - 1:].
+   * If [start] is not provided, it defaults to [:this.length - 1:].
    *
    * Returns -1 if [element] is not found.
    */
   int lastIndexOf(E element, [int start]);
 
   /**
-   * Removes all elements in the list.
+   * Removes all objects from this list;
+   * the length of the list becomes zero.
    *
-   * The length of the list becomes zero.
-   *
-   * Throws an [UnsupportedError], and retains all elements, if the
-   * length of the list cannot be changed.
+   * Throws an [UnsupportedError], and retains all objects, if this 
+   * is a fixed-length list.
    */
   void clear();
 
   /**
-   * Inserts the element at position [index] in the list.
+   * Inserts the object at position [index] in this list.
    *
-   * This increases the length of the list by one and shifts all elements
+   * This increases the length of the list by one and shifts all objects
    * at or after the index towards the end of the list.
    *
-   * It is an error if the [index] does not point inside the list or at the
-   * position after the last element.
+   * An error occurs if the [index] is less than 0 or greater than length.
+   * An [UnsupportedError] occurs if the list is fixed-length.
    */
   void insert(int index, E element);
 
   /**
-   * Inserts all elements of [iterable] at position [index] in the list.
+   * Inserts all objects of [iterable] at position [index] in this list.
    *
    * This increases the length of the list by the length of [iterable] and
-   * shifts all later elements towards the end of the list.
+   * shifts all later objects towards the end of the list.
    *
-   * It is an error if the [index] does not point inside the list or at the
-   * position after the last element.
+   * An error occurs if the [index] is less than 0 or greater than length.
+   * An [UnsupportedError] occurs if the list is fixed-length.
    */
   void insertAll(int index, Iterable<E> iterable);
 
   /**
-   * Overwrites elements of `this` with the elemenst of [iterable] starting
-   * at position [index] in the list.
+   * Overwrites objects of `this` with the objects of [iterable], starting
+   * at position [index] in this list.
    *
    * This operation does not increase the length of `this`.
    *
-   * It is an error if the [index] does not point inside the list or at the
-   * position after the last element.
-   *
-   * It is an error if the [iterable] is longer than [length] - [index].
+   * An error occurs if the [index] is less than 0 or greater than length.
+   * An error occurs if the [iterable] is longer than [length] - [index].
    */
   void setAll(int index, Iterable<E> iterable);
 
   /**
-   * Removes [value] from the list. Returns true if [value] was
-   * in the list. Returns false otherwise. The method has no effect
-   * if [value] value was not in the list.
+   * Removes [value] from this list.
+   *
+   * Returns true if [value] was in the list.
+   * Returns false otherwise.
+   * The method has no effect if [value] was not in the list.
+   *
+   * An [UnsupportedError] occurs if the list is fixed-length.
    */
   bool remove(Object value);
 
   /**
-   * Removes the element at position [index] from the list.
+   * Removes the object at position [index] from this list.
    *
-   * This reduces the length of `this` by one and moves all later elements
+   * This method reduces the length of `this` by one and moves all later objects
    * down by one position.
    *
-   * Returns the removed element.
+   * Returns the removed object.
    *
-   * Throws an [ArgumentError] if [index] is not an [int].
-   *
-   * Throws an [RangeError] if the [index] does not point inside
-   * the list.
-   *
-   * Throws an [UnsupportedError], and doesn't remove the element,
-   * if the length of `this` cannot be changed.
+   * * Throws an [ArgumentError] if [index] is not an [int].
+   * * Throws a [RangeError] if the [index] is out of range for this list.
+   * * Throws an [UnsupportedError], and doesn't remove the object,
+   * if this is a fixed-length list.
    */
   E removeAt(int index);
 
   /**
-   * Pops and returns the last element of the list.
-   * Throws a [UnsupportedError] if the length of the
-   * list cannot be changed.
+   * Pops and returns the last object in this list.
+   *
+   * Throws an [UnsupportedError] if this is a fixed-length list.
    */
   E removeLast();
 
   /**
-   * Removes all elements of this list that satisfy [test].
+   * Removes all objects from this list that satisfy [test].
    *
-   * An elements [:e:] satisfies [test] if [:test(e):] is true.
+   * An object [:o:] satisfies [test] if [:test(o):] is true.
+   *
+   * Throws an [UnsupportedError] if this is a fixed-length list.
    */
   void removeWhere(bool test(E element));
 
   /**
-   * Removes all elements of this list that fail to satisfy [test].
+   * Removes all objects from this list that fail to satisfy [test].
    *
-   * An elements [:e:] satisfies [test] if [:test(e):] is true.
+   * An object [:o:] satisfies [test] if [:test(o):] is true.
+   *
+   * Throws an [UnsupportedError] if this is a fixed-length list.
    */
   void retainWhere(bool test(E element));
 
   /**
-   * Returns a new list containing the elements from [start] to [end].
-   *
-   * The result contains elements of this list with indices greater than or
-   * equal to [start] and less than [end].
+   * Returns a new list containing the objects
+   * from [start] inclusive to [end] exclusive.
    *
    * If [end] is omitted, the [length] of `this` is used.
    *
-   * It is an error if [start] is outside the range `0` .. `[length]` or if
-   * [end] is outside the range `[start]` .. `[length]`.
+   * An error occurs if [start] is outside the range `0` .. `length` or if
+   * [end] is outside the range `start` .. `length`.
    */
   List<E> sublist(int start, [int end]);
 
   /**
-   * Returns an [Iterable] that iterates over the elements in the range
-   * [start] to [end] exclusive. The result of this function
-   * is backed by `this`.
+   * Returns an [Iterable] that iterates over the objects in the range
+   * [start] inclusive to [end] exclusive.
    *
-   * It is an error if [end] is before [start].
+   * An error occurs if [end] is before [start].
    *
-   * It is an error if the [start] and [end] are not valid ranges at the time
-   * of the call to this method. The returned [Iterable] behaves similar to
-   * `skip(start).take(end - start)`. That is, it will not throw exceptions
+   * An error occurs if the [start] and [end] are not valid ranges at the time
+   * of the call to this method. The returned [Iterable] behaves like
+   * `skip(start).take(end - start)`. That is, it does not throw exceptions
    * if `this` changes size.
    *
    * Example:
@@ -320,17 +314,15 @@
   Iterable<E> getRange(int start, int end);
 
   /**
-   * Copies the elements of [iterable], skipping the [skipCount] first elements,
-   * into the range [start] to [end] exclusive of `this`.
+   * Copies the objects of [iterable], skipping [skipCount] objects first,
+   * into the range [start] inclusive to [end] exclusive of `this`.
    *
    * If [start] equals [end] and [start]..[end] represents a legal range, this
    * method has no effect.
    *
-   * It is an error if [start]..[end] is not a valid range pointing into the
-   * `this`.
-   *
-   * It is an error if the [iterable] does not have enough elements after
-   * skipping [skipCount] elements.
+   * An error occurs if [start]..[end] is not a valid range for `this`.
+   * An error occurs if the [iterable] does not have enough objects after
+   * skipping [skipCount] objects.
    *
    * Example:
    *
@@ -342,28 +334,26 @@
   void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]);
 
   /**
-   * Removes the elements in the range [start] to [end] exclusive.
+   * Removes the objects in the range [start] inclusive to [end] exclusive.
    *
-   * It is an error if [start]..[end] is not a valid range pointing into the
-   * `this`.
+   * An error occurs if [start]..[end] is not a valid range for `this`.
+   * Throws an [UnsupportedError] if this is a fixed-length list.
    */
   void removeRange(int start, int end);
 
   /**
-   * Sets the elements in the range [start] to [end] exclusive to the given
-   * [fillValue].
+   * Sets the objects in the range [start] inclusive to [end] exclusive
+   * to the given [fillValue].
    *
-   * It is an error if [start]..[end] is not a valid range pointing into the
-   * `this`.
+   * An error occurs if [start]..[end] is not a valid range for `this`.
    */
   void fillRange(int start, int end, [E fillValue]);
 
   /**
-   * Removes the elements in the range [start] to [end] exclusive and replaces
-   * them with the contents of the [iterable].
+   * Removes the objects in the range [start] inclusive to [end] exclusive
+   * and replaces them with the contents of the [iterable].
    *
-   * It is an error if [start]..[end] is not a valid range pointing into the
-   * `this`.
+   * An error occurs if [start]..[end] is not a valid range for `this`.
    *
    * Example:
    *
@@ -376,8 +366,8 @@
   /**
    * Returns an unmodifiable [Map] view of `this`.
    *
-   * It has the indices of this list as keys, and the corresponding elements
-   * as values. The [Map.keys] [Iterable] will iterate the indices of this list
+   * The map uses the indices of this list as keys and the corresponding objects
+   * as values. The `Map.keys` [Iterable] iterates the indices of this list
    * in numerical order.
    */
   Map<int, E> asMap();
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 3f1a7cc..b2ca3f2 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -5,11 +5,11 @@
 part of dart.core;
 
 /**
- * The String class represents sequences of characters. Strings are
- * immutable. A string is represented by a sequence of Unicode UTF-16
- * code units accessible through the [codeUnitAt] or the
- * [codeUnits] members. Their string representation is accessible through
- * the index-operator.
+ * A class for working with a sequence of characters.
+ *
+ * A string is represented by a sequence of Unicode UTF-16 code units
+ * accessible through the [codeUnitAt] or the [codeUnits] members. Their
+ * string representation is accessible through the index-operator.
  *
  * The characters of a string are encoded in UTF-16. Decoding UTF-16, which
  * combines surrogate pairs, yields Unicode code points. Following a similar
@@ -17,8 +17,13 @@
  * Unicode code point. The runes of a string are accessible through the [runes]
  * getter.
  *
+ * Strings are immutable.
+ *
  * It is a compile-time error for a class to attempt to extend or implement
  * String.
+ *
+ * For concatenating strings efficiently, use the [StringBuffer] class. For
+ * working with regular expressions, use the [RegExp] class.
  */
 abstract class String implements Comparable<String>, Pattern {
   /**
diff --git a/sdk/lib/core/string_buffer.dart b/sdk/lib/core/string_buffer.dart
index 59d1aa9..e8bc72d 100644
--- a/sdk/lib/core/string_buffer.dart
+++ b/sdk/lib/core/string_buffer.dart
@@ -5,9 +5,11 @@
 part of dart.core;
 
 /**
- * The StringBuffer class is useful for concatenating strings
- * efficiently. Only on a call to [toString] are the strings
- * concatenated to a single String.
+ * A class for concatenating strings efficiently.
+ *
+ * Allows for the incremental building of a string using write*() methods.
+ * The strings are concatenated to a single string only when [toString] is
+ * called.
  */
 class StringBuffer implements StringSink {
 
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 47d6327..85e76ba 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -1083,11 +1083,11 @@
    * pluses to spaces.
    *
    * It will create a byte-list of the decoded characters, and then use
-   * [decode] to decode the byte-list to a String. Default is a UTF_8 decoder.
+   * [decode] to decode the byte-list to a String. Default is a UTF-8 decoder.
    */
   static String decodeQueryComponent(
       String encodedComponent,
-      {String decode(List<int> bytes): decodeUtf8}) {
+      {String decode(List<int> bytes): null}) {
     return _uriDecode(encodedComponent, plusToSpace: true, decode: decode);
   }
 
@@ -1128,12 +1128,12 @@
    * Keys in the query string that have no value are mapped to the
    * empty string.
    *
-   * Each query component will be decoded using [decode]. Default is a UTF_8
+   * Each query component will be decoded using [decode]. Default is a UTF-8
    * decoder.
    */
   static Map<String, String> splitQueryString(
       String query,
-      {String decode(List<int> bytes): decodeUtf8}) {
+      {String decode(List<int> bytes): null}) {
     return query.split("&").fold({}, (map, element) {
       int index = element.indexOf("=");
       if (index == -1) {
@@ -1202,7 +1202,8 @@
             throw new ArgumentError('Malformed URI');
           }
         }
-        for (int codepoint in codepointsToUtf8([ch])) {
+        // TODO(floitsch): don't allocate a new string.
+        for (int codepoint in UTF8.encode(new String.fromCharCode(ch))) {
           result.write(byteToHex(codepoint));
         }
       }
@@ -1243,11 +1244,11 @@
    * If [plusToSpace] is `true`, plus characters will be converted to spaces.
    *
    * The decoder will create a byte-list of the percent-encoded parts, and then
-   * decode the byte-list using [decode]. Default is a UTF_8 decoder.
+   * decode the byte-list using [decode]. Default is a UTF-8 decoder.
    */
   static String _uriDecode(String text,
                            {bool plusToSpace: false,
-                            String decode(List<int> bytes): decodeUtf8}) {
+                            String decode(List<int> bytes): null}) {
     StringBuffer result = new StringBuffer();
     List<int> codepoints = new List<int>();
     for (int i = 0; i < text.length;) {
@@ -1270,7 +1271,8 @@
           if (i == text.length) break;
           ch = text.codeUnitAt(i);
         }
-        result.write(decode(codepoints));
+        result.write(
+            decode == null ? UTF8.decode(codepoints) : decode(codepoints));
       }
     }
     return result.toString();
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 15b960c..b584d35 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -1122,6 +1122,11 @@
   @DocsEditable()
   String globalCompositeOperation;
 
+  @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
+  @DocsEditable()
+  @Experimental() // untriaged
+  bool imageSmoothingEnabled;
+
   @DomName('CanvasRenderingContext2D.lineCap')
   @DocsEditable()
   String lineCap;
@@ -1176,14 +1181,6 @@
   @Experimental()
   final num backingStorePixelRatio;
 
-  @JSName('webkitImageSmoothingEnabled')
-  @DomName('CanvasRenderingContext2D.webkitImageSmoothingEnabled')
-  @DocsEditable()
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental()
-  bool imageSmoothingEnabled;
-
   @JSName('arc')
   @DomName('CanvasRenderingContext2D.arc')
   @DocsEditable()
@@ -1255,6 +1252,16 @@
   @DocsEditable()
   CanvasGradient createRadialGradient(num x0, num y0, num r0, num x1, num y1, num r1) native;
 
+  @DomName('CanvasRenderingContext2D.drawCustomFocusRing')
+  @DocsEditable()
+  @Experimental() // untriaged
+  bool drawCustomFocusRing(Element element) native;
+
+  @DomName('CanvasRenderingContext2D.drawSystemFocusRing')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void drawSystemFocusRing(Element element) native;
+
   @DomName('CanvasRenderingContext2D.fill')
   @DocsEditable()
   void fill([String winding]) native;
@@ -6422,7 +6429,7 @@
   @JSName('getAsString')
   @DomName('DataTransferItem.getAsString')
   @DocsEditable()
-  void _getAsString([_StringCallback callback]) native;
+  void _getAsString(_StringCallback callback) native;
 
   @JSName('getAsString')
   @DomName('DataTransferItem.getAsString')
@@ -7176,12 +7183,6 @@
   @DocsEditable()
   Event $dom_createEvent(String eventType) native;
 
-  @JSName('createNodeIterator')
-  @DomName('Document.createNodeIterator')
-  @DocsEditable()
-  @Unstable()
-  NodeIterator $dom_createNodeIterator(Node root, [int whatToShow, NodeFilter filter, bool expandEntityReferences]) native;
-
   @JSName('createRange')
   @DomName('Document.createRange')
   @DocsEditable()
@@ -7215,11 +7216,6 @@
   @Experimental()
   TouchList $dom_createTouchList() native;
 
-  @JSName('createTreeWalker')
-  @DomName('Document.createTreeWalker')
-  @DocsEditable()
-  TreeWalker $dom_createTreeWalker(Node root, [int whatToShow, NodeFilter filter, bool expandEntityReferences]) native;
-
   @JSName('elementFromPoint')
   @DomName('Document.elementFromPoint')
   @DocsEditable()
@@ -7621,6 +7617,11 @@
   ElementList queryAll(String selectors) {
     return new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
   }
+
+  /// Checks if [register] is supported on the current platform.
+  bool get supportsRegister {
+    return JS('bool', '("register" in #)', this);
+  }
 }
 // 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
@@ -8478,7 +8479,7 @@
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
   @Experimental()
   ElementStream<Event> get onFullscreenError;
- 
+
 }
 
 // TODO(jacobr): this is an inefficient implementation but it is hard to see
@@ -9619,6 +9620,18 @@
     Point p = Element._offsetToHelper(parentOffset, parent);
     return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
   }
+
+  @JSName('innerHTML')
+  @DomName('HTMLElement.innerHTML')
+  String get innerHtml => JS('String', '#.innerHTML', this);
+
+  void set innerHtml(String value) {
+    JS('', '#.innerHTML = #', this, value);
+    // Polyfill relies on mutation observers for upgrading, but we want it
+    // immediate.
+    Platform.upgradeCustomElements(this);
+  }
+
   // To suppress missing implicit constructor warnings.
   factory Element._() { throw new UnsupportedError("Not supported"); }
 
@@ -9855,14 +9868,10 @@
   @DocsEditable()
   bool hidden;
 
-  @DomName('Element.id')
+  @DomName('Element.inputMethodContext')
   @DocsEditable()
-  String id;
-
-  @JSName('innerHTML')
-  @DomName('Element.innerHTML')
-  @DocsEditable()
-  String innerHtml;
+  @Experimental() // untriaged
+  final InputMethodContext inputMethodContext;
 
   @DomName('Element.isContentEditable')
   @DocsEditable()
@@ -9910,12 +9919,6 @@
   @DocsEditable()
   void click() native;
 
-  @DomName('Element.getInputContext')
-  @DocsEditable()
-  // http://www.w3.org/TR/ime-api/#the-getinputcontext-method
-  @Experimental()
-  InputMethodContext getInputContext() native;
-
   @DomName('Element.ALLOW_KEYBOARD_INPUT')
   @DocsEditable()
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#dom-element-requestfullscreen
@@ -9947,6 +9950,10 @@
   @DocsEditable()
   final int clientWidth;
 
+  @DomName('Element.id')
+  @DocsEditable()
+  String id;
+
   @DomName('Element.offsetHeight')
   @DocsEditable()
   final int offsetHeight;
@@ -10039,6 +10046,13 @@
   @Creates('_ClientRectList')
   List<Rect> getClientRects() native;
 
+  @DomName('Element.getDestinationInsertionPoints')
+  @DocsEditable()
+  @Experimental() // untriaged
+  @Returns('NodeList')
+  @Creates('NodeList')
+  List<Node> getDestinationInsertionPoints() native;
+
   @DomName('Element.getElementsByClassName')
   @DocsEditable()
   @Returns('NodeList')
@@ -10784,6 +10798,17 @@
   // To suppress missing implicit constructor warnings.
   factory ErrorEvent._() { throw new UnsupportedError("Not supported"); }
 
+  @DomName('ErrorEvent.colno')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final int colno;
+
+  @DomName('ErrorEvent.error')
+  @DocsEditable()
+  @Experimental() // untriaged
+  @Creates('Null')
+  final Object error;
+
   @DomName('ErrorEvent.filename')
   @DocsEditable()
   final String filename;
@@ -12485,6 +12510,18 @@
   @DocsEditable()
   final Element activeElement;
 
+  @DomName('HTMLDocument.captureEvents')
+  @DocsEditable()
+  // http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture
+  @deprecated // deprecated
+  void captureEvents() native;
+
+  @DomName('HTMLDocument.releaseEvents')
+  @DocsEditable()
+  // http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture
+  @deprecated // deprecated
+  void releaseEvents() native;
+
 
   @DomName('Document.body')
   BodyElement body;
@@ -13392,16 +13429,6 @@
   @Experimental() // untriaged
   final int width;
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DomName('ImageBitmapCallback')
-@Experimental() // untriaged
-typedef void ImageBitmapCallback(ImageBitmap bitmap);
 // Copyright (c) 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.
@@ -13758,8 +13785,6 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#concept-input-type-file-selected
-  @Returns('_EntryArray')
-  @Creates('_EntryArray')
   final List<Entry> entries;
 
   @JSName('webkitGrammar')
@@ -14485,6 +14510,26 @@
   // To suppress missing implicit constructor warnings.
   factory KeyboardEvent._() { throw new UnsupportedError("Not supported"); }
 
+  @DomName('KeyboardEvent.DOM_KEY_LOCATION_LEFT')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const int DOM_KEY_LOCATION_LEFT = 0x01;
+
+  @DomName('KeyboardEvent.DOM_KEY_LOCATION_NUMPAD')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const int DOM_KEY_LOCATION_NUMPAD = 0x03;
+
+  @DomName('KeyboardEvent.DOM_KEY_LOCATION_RIGHT')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const int DOM_KEY_LOCATION_RIGHT = 0x02;
+
+  @DomName('KeyboardEvent.DOM_KEY_LOCATION_STANDARD')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const int DOM_KEY_LOCATION_STANDARD = 0x00;
+
   @DomName('KeyboardEvent.altGraphKey')
   @DocsEditable()
   @Experimental() // nonstandard
@@ -14509,6 +14554,11 @@
   @Experimental() // nonstandard
   final int keyLocation;
 
+  @DomName('KeyboardEvent.location')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final int location;
+
   @DomName('KeyboardEvent.metaKey')
   @DocsEditable()
   final bool metaKey;
@@ -14517,6 +14567,11 @@
   @DocsEditable()
   final bool shiftKey;
 
+  @DomName('KeyboardEvent.getModifierState')
+  @DocsEditable()
+  @Experimental() // untriaged
+  bool getModifierState(String keyArgument) native;
+
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -17849,47 +17904,6 @@
   @DocsEditable()
   static const int SHOW_TEXT = 0x00000004;
 }
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DomName('NodeIterator')
-@Unstable()
-class NodeIterator extends Interceptor native "NodeIterator" {
-  factory NodeIterator(Node root, int whatToShow) {
-    return document.$dom_createNodeIterator(root, whatToShow, null, false);
-  }
-
-  @DomName('NodeIterator.pointerBeforeReferenceNode')
-  @DocsEditable()
-  final bool pointerBeforeReferenceNode;
-
-  @DomName('NodeIterator.referenceNode')
-  @DocsEditable()
-  final Node referenceNode;
-
-  @DomName('NodeIterator.root')
-  @DocsEditable()
-  final Node root;
-
-  @DomName('NodeIterator.whatToShow')
-  @DocsEditable()
-  final int whatToShow;
-
-  @DomName('NodeIterator.detach')
-  @DocsEditable()
-  void detach() native;
-
-  @DomName('NodeIterator.nextNode')
-  @DocsEditable()
-  Node nextNode() native;
-
-  @DomName('NodeIterator.previousNode')
-  @DocsEditable()
-  Node previousNode() native;
-
-}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -18121,11 +18135,6 @@
   @DocsEditable()
   int checkPermission() native;
 
-  @JSName('createHTMLNotification')
-  @DomName('NotificationCenter.createHTMLNotification')
-  @DocsEditable()
-  Notification createHtmlNotification(String url) native;
-
   @DomName('NotificationCenter.createNotification')
   @DocsEditable()
   Notification createNotification(String iconUrl, String title, String body) native;
@@ -18605,7 +18614,9 @@
 @SupportedBrowser(SupportedBrowser.CHROME)
 @SupportedBrowser(SupportedBrowser.FIREFOX)
 @SupportedBrowser(SupportedBrowser.IE)
-class Performance extends Interceptor native "Performance" {
+class Performance extends EventTarget native "Performance" {
+  // To suppress missing implicit constructor warnings.
+  factory Performance._() { throw new UnsupportedError("Not supported"); }
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => JS('bool', '!!(window.performance)');
@@ -19567,6 +19578,45 @@
 
 
 @DocsEditable()
+@DomName('RsaKeyGenParams')
+@Experimental() // untriaged
+class RsaKeyGenParams extends Algorithm native "RsaKeyGenParams" {
+  // To suppress missing implicit constructor warnings.
+  factory RsaKeyGenParams._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('RsaKeyGenParams.modulusLength')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final int modulusLength;
+
+  @DomName('RsaKeyGenParams.publicExponent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final Uint8List publicExponent;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable()
+@DomName('RsaSsaParams')
+@Experimental() // untriaged
+class RsaSsaParams extends Algorithm native "RsaSsaParams" {
+  // To suppress missing implicit constructor warnings.
+  factory RsaSsaParams._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('RsaSsaParams.hash')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final Algorithm hash;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable()
 @DomName('RTCDataChannel')
 // http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDataChannel
 @Experimental()
@@ -19598,10 +19648,40 @@
   @DocsEditable()
   final int bufferedAmount;
 
+  @DomName('RTCDataChannel.id')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final int id;
+
   @DomName('RTCDataChannel.label')
   @DocsEditable()
   final String label;
 
+  @DomName('RTCDataChannel.maxRetransmitTime')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final int maxRetransmitTime;
+
+  @DomName('RTCDataChannel.maxRetransmits')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final int maxRetransmits;
+
+  @DomName('RTCDataChannel.negotiated')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final bool negotiated;
+
+  @DomName('RTCDataChannel.ordered')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final bool ordered;
+
+  @DomName('RTCDataChannel.protocol')
+  @DocsEditable()
+  @Experimental() // untriaged
+  final String protocol;
+
   @DomName('RTCDataChannel.readyState')
   @DocsEditable()
   final String readyState;
@@ -20798,6 +20878,16 @@
   // To suppress missing implicit constructor warnings.
   factory SourceBuffer._() { throw new UnsupportedError("Not supported"); }
 
+  @DomName('SourceBuffer.appendWindowEnd')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num appendWindowEnd;
+
+  @DomName('SourceBuffer.appendWindowStart')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num appendWindowStart;
+
   @DomName('SourceBuffer.buffered')
   @DocsEditable()
   final TimeRanges buffered;
@@ -20825,6 +20915,11 @@
   @DocsEditable()
   @Experimental() // untriaged
   void appendBufferView(TypedData data) native;
+
+  @DomName('SourceBuffer.remove')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void remove(num start, num end) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -21951,15 +22046,15 @@
   @DomName('SubtleCrypto.decrypt')
   @DocsEditable()
   @Experimental() // untriaged
-  CryptoOperation decrypt(Map algorithm) {
+  CryptoOperation decrypt(Map algorithm, CryptoKey key) {
     var algorithm_1 = convertDartToNative_Dictionary(algorithm);
-    return _decrypt_1(algorithm_1);
+    return _decrypt_1(algorithm_1, key);
   }
   @JSName('decrypt')
   @DomName('SubtleCrypto.decrypt')
   @DocsEditable()
   @Experimental() // untriaged
-  CryptoOperation _decrypt_1(algorithm) native;
+  CryptoOperation _decrypt_1(algorithm, CryptoKey key) native;
 
   @DomName('SubtleCrypto.digest')
   @DocsEditable()
@@ -21977,15 +22072,28 @@
   @DomName('SubtleCrypto.encrypt')
   @DocsEditable()
   @Experimental() // untriaged
-  CryptoOperation encrypt(Map algorithm) {
+  CryptoOperation encrypt(Map algorithm, CryptoKey key) {
     var algorithm_1 = convertDartToNative_Dictionary(algorithm);
-    return _encrypt_1(algorithm_1);
+    return _encrypt_1(algorithm_1, key);
   }
   @JSName('encrypt')
   @DomName('SubtleCrypto.encrypt')
   @DocsEditable()
   @Experimental() // untriaged
-  CryptoOperation _encrypt_1(algorithm) native;
+  CryptoOperation _encrypt_1(algorithm, CryptoKey key) native;
+
+  @DomName('SubtleCrypto.generateKey')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Object generateKey(Map algorithm, bool extractable, List<String> keyUsages) {
+    var algorithm_1 = convertDartToNative_Dictionary(algorithm);
+    return _generateKey_1(algorithm_1, extractable, keyUsages);
+  }
+  @JSName('generateKey')
+  @DomName('SubtleCrypto.generateKey')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Object _generateKey_1(algorithm, extractable, List<String> keyUsages) native;
 
   @DomName('SubtleCrypto.importKey')
   @DocsEditable()
@@ -22003,28 +22111,28 @@
   @DomName('SubtleCrypto.sign')
   @DocsEditable()
   @Experimental() // untriaged
-  CryptoOperation sign(Map algorithm) {
+  CryptoOperation sign(Map algorithm, CryptoKey key) {
     var algorithm_1 = convertDartToNative_Dictionary(algorithm);
-    return _sign_1(algorithm_1);
+    return _sign_1(algorithm_1, key);
   }
   @JSName('sign')
   @DomName('SubtleCrypto.sign')
   @DocsEditable()
   @Experimental() // untriaged
-  CryptoOperation _sign_1(algorithm) native;
+  CryptoOperation _sign_1(algorithm, CryptoKey key) native;
 
   @DomName('SubtleCrypto.verify')
   @DocsEditable()
   @Experimental() // untriaged
-  CryptoOperation verify(Map algorithm) {
+  CryptoOperation verify(Map algorithm, CryptoKey key, TypedData signature) {
     var algorithm_1 = convertDartToNative_Dictionary(algorithm);
-    return _verify_1(algorithm_1);
+    return _verify_1(algorithm_1, key, signature);
   }
   @JSName('verify')
   @DomName('SubtleCrypto.verify')
   @DocsEditable()
   @Experimental() // untriaged
-  CryptoOperation _verify_1(algorithm) native;
+  CryptoOperation _verify_1(algorithm, CryptoKey key, TypedData signature) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -22611,6 +22719,13 @@
   @DocsEditable()
   final String wholeText;
 
+  @DomName('Text.getDestinationInsertionPoints')
+  @DocsEditable()
+  @Experimental() // untriaged
+  @Returns('NodeList')
+  @Creates('NodeList')
+  List<Node> getDestinationInsertionPoints() native;
+
   @DomName('Text.replaceWholeText')
   @DocsEditable()
   // http://dom.spec.whatwg.org/#dom-text-replacewholetext
@@ -23494,69 +23609,6 @@
   @DocsEditable()
   final String pseudoElement;
 }
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DomName('TreeWalker')
-@Unstable()
-class TreeWalker extends Interceptor native "TreeWalker" {
-  factory TreeWalker(Node root, int whatToShow) {
-    return document.$dom_createTreeWalker(root, whatToShow, null, false);
-  }
-
-  @DomName('TreeWalker.currentNode')
-  @DocsEditable()
-  Node currentNode;
-
-  @DomName('TreeWalker.expandEntityReferences')
-  @DocsEditable()
-  // http://dom.spec.whatwg.org/#dom-traversal
-  @deprecated // deprecated
-  final bool expandEntityReferences;
-
-  @DomName('TreeWalker.filter')
-  @DocsEditable()
-  final NodeFilter filter;
-
-  @DomName('TreeWalker.root')
-  @DocsEditable()
-  final Node root;
-
-  @DomName('TreeWalker.whatToShow')
-  @DocsEditable()
-  final int whatToShow;
-
-  @DomName('TreeWalker.firstChild')
-  @DocsEditable()
-  Node firstChild() native;
-
-  @DomName('TreeWalker.lastChild')
-  @DocsEditable()
-  Node lastChild() native;
-
-  @DomName('TreeWalker.nextNode')
-  @DocsEditable()
-  Node nextNode() native;
-
-  @DomName('TreeWalker.nextSibling')
-  @DocsEditable()
-  Node nextSibling() native;
-
-  @DomName('TreeWalker.parentNode')
-  @DocsEditable()
-  Node parentNode() native;
-
-  @DomName('TreeWalker.previousNode')
-  @DocsEditable()
-  Node previousNode() native;
-
-  @DomName('TreeWalker.previousSibling')
-  @DocsEditable()
-  Node previousSibling() native;
-
-}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -24940,6 +24992,12 @@
   @DocsEditable()
   void alert(String message) native;
 
+  @DomName('Window.captureEvents')
+  @DocsEditable()
+  // http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture
+  @deprecated // deprecated
+  void captureEvents() native;
+
   @DomName('Window.close')
   @DocsEditable()
   void close() native;
@@ -24948,123 +25006,6 @@
   @DocsEditable()
   bool confirm(String message) native;
 
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, ImageBitmapCallback callback, [int sx, int sy, int sw, int sh]) {
-    if ((bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is ImageElement || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null) && sx == null && sy == null && sw == null && sh == null) {
-      _createImageBitmap_1(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback);
-      return;
-    }
-    if (sh != null && sw != null && sy != null && sx != null && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is ImageElement || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null)) {
-      _createImageBitmap_2(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh);
-      return;
-    }
-    if ((bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is VideoElement || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null) && sx == null && sy == null && sw == null && sh == null) {
-      _createImageBitmap_3(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback);
-      return;
-    }
-    if (sh != null && sw != null && sy != null && sx != null && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is VideoElement || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null)) {
-      _createImageBitmap_4(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh);
-      return;
-    }
-    if ((bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is CanvasRenderingContext2D || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null) && sx == null && sy == null && sw == null && sh == null) {
-      _createImageBitmap_5(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback);
-      return;
-    }
-    if (sh != null && sw != null && sy != null && sx != null && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is CanvasRenderingContext2D || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null)) {
-      _createImageBitmap_6(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh);
-      return;
-    }
-    if ((bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is CanvasElement || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null) && sx == null && sy == null && sw == null && sh == null) {
-      _createImageBitmap_7(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback);
-      return;
-    }
-    if (sh != null && sw != null && sy != null && sx != null && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is CanvasElement || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null)) {
-      _createImageBitmap_8(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh);
-      return;
-    }
-    if ((bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is ImageData || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null) && sx == null && sy == null && sw == null && sh == null) {
-      var data_1 = convertDartToNative_ImageData(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video);
-      _createImageBitmap_9(data_1, callback);
-      return;
-    }
-    if (sh != null && sw != null && sy != null && sx != null && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is ImageData || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null)) {
-      var data_2 = convertDartToNative_ImageData(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video);
-      _createImageBitmap_10(data_2, callback, sx, sy, sw, sh);
-      return;
-    }
-    if ((bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is ImageBitmap || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null) && sx == null && sy == null && sw == null && sh == null) {
-      _createImageBitmap_11(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback);
-      return;
-    }
-    if (sh != null && sw != null && sy != null && sx != null && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is ImageBitmap || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null)) {
-      _createImageBitmap_12(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh);
-      return;
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
-  @JSName('createImageBitmap')
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap_1(ImageElement image, ImageBitmapCallback callback) native;
-  @JSName('createImageBitmap')
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap_2(ImageElement image, ImageBitmapCallback callback, sx, sy, sw, sh) native;
-  @JSName('createImageBitmap')
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap_3(VideoElement video, ImageBitmapCallback callback) native;
-  @JSName('createImageBitmap')
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap_4(VideoElement video, ImageBitmapCallback callback, sx, sy, sw, sh) native;
-  @JSName('createImageBitmap')
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap_5(CanvasRenderingContext2D context, ImageBitmapCallback callback) native;
-  @JSName('createImageBitmap')
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap_6(CanvasRenderingContext2D context, ImageBitmapCallback callback, sx, sy, sw, sh) native;
-  @JSName('createImageBitmap')
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap_7(CanvasElement canvas, ImageBitmapCallback callback) native;
-  @JSName('createImageBitmap')
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap_8(CanvasElement canvas, ImageBitmapCallback callback, sx, sy, sw, sh) native;
-  @JSName('createImageBitmap')
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap_9(data, ImageBitmapCallback callback) native;
-  @JSName('createImageBitmap')
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap_10(data, ImageBitmapCallback callback, sx, sy, sw, sh) native;
-  @JSName('createImageBitmap')
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap_11(ImageBitmap bitmap, ImageBitmapCallback callback) native;
-  @JSName('createImageBitmap')
-  @DomName('Window.createImageBitmap')
-  @DocsEditable()
-  @Experimental() // untriaged
-  void _createImageBitmap_12(ImageBitmap bitmap, ImageBitmapCallback callback, sx, sy, sw, sh) native;
-
   @DomName('Window.find')
   @DocsEditable()
   @Experimental() // non-standard
@@ -25135,6 +25076,12 @@
   @DocsEditable()
   void print() native;
 
+  @DomName('Window.releaseEvents')
+  @DocsEditable()
+  // http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture
+  @deprecated // deprecated
+  void releaseEvents() native;
+
   @DomName('Window.resizeBy')
   @DocsEditable()
   void resizeBy(num x, num y) native;
@@ -26591,132 +26538,6 @@
 
 
 @DocsEditable()
-@DomName('EntryArray')
-// http://www.w3.org/TR/file-system-api/#the-entry-interface
-@Experimental()
-class _EntryArray extends Interceptor with ListMixin<Entry>, ImmutableListMixin<Entry> implements JavaScriptIndexingBehavior, List<Entry> native "EntryArray" {
-
-  @DomName('EntryArray.length')
-  @DocsEditable()
-  int get length => JS("int", "#.length", this);
-
-  Entry operator[](int index) {
-    if (JS("bool", "# >>> 0 !== # || # >= #", index,
-        index, index, length))
-      throw new RangeError.range(index, 0, length);
-    return JS("Entry", "#[#]", this, index);
-  }
-  void operator[]=(int index, Entry value) {
-    throw new UnsupportedError("Cannot assign element of immutable List.");
-  }
-  // -- start List<Entry> mixins.
-  // Entry is the element type.
-
-
-  void set length(int value) {
-    throw new UnsupportedError("Cannot resize immutable List.");
-  }
-
-  Entry get first {
-    if (this.length > 0) {
-      return JS('Entry', '#[0]', this);
-    }
-    throw new StateError("No elements");
-  }
-
-  Entry get last {
-    int len = this.length;
-    if (len > 0) {
-      return JS('Entry', '#[#]', this, len - 1);
-    }
-    throw new StateError("No elements");
-  }
-
-  Entry get single {
-    int len = this.length;
-    if (len == 1) {
-      return JS('Entry', '#[0]', this);
-    }
-    if (len == 0) throw new StateError("No elements");
-    throw new StateError("More than one element");
-  }
-
-  Entry elementAt(int index) => this[index];
-  // -- end List<Entry> mixins.
-
-  @DomName('EntryArray.item')
-  @DocsEditable()
-  Entry item(int index) native;
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable()
-@DomName('EntryArraySync')
-// http://www.w3.org/TR/file-system-api/#idl-def-EntrySync
-@Experimental()
-class _EntryArraySync extends Interceptor with ListMixin<_EntrySync>, ImmutableListMixin<_EntrySync> implements JavaScriptIndexingBehavior, List<_EntrySync> native "EntryArraySync" {
-
-  @DomName('EntryArraySync.length')
-  @DocsEditable()
-  int get length => JS("int", "#.length", this);
-
-  _EntrySync operator[](int index) {
-    if (JS("bool", "# >>> 0 !== # || # >= #", index,
-        index, index, length))
-      throw new RangeError.range(index, 0, length);
-    return JS("_EntrySync", "#[#]", this, index);
-  }
-  void operator[]=(int index, _EntrySync value) {
-    throw new UnsupportedError("Cannot assign element of immutable List.");
-  }
-  // -- start List<_EntrySync> mixins.
-  // _EntrySync is the element type.
-
-
-  void set length(int value) {
-    throw new UnsupportedError("Cannot resize immutable List.");
-  }
-
-  _EntrySync get first {
-    if (this.length > 0) {
-      return JS('_EntrySync', '#[0]', this);
-    }
-    throw new StateError("No elements");
-  }
-
-  _EntrySync get last {
-    int len = this.length;
-    if (len > 0) {
-      return JS('_EntrySync', '#[#]', this, len - 1);
-    }
-    throw new StateError("No elements");
-  }
-
-  _EntrySync get single {
-    int len = this.length;
-    if (len == 1) {
-      return JS('_EntrySync', '#[0]', this);
-    }
-    if (len == 0) throw new StateError("No elements");
-    throw new StateError("More than one element");
-  }
-
-  _EntrySync elementAt(int index) => this[index];
-  // -- end List<_EntrySync> mixins.
-
-  @DomName('EntryArraySync.item')
-  @DocsEditable()
-  _EntrySync item(int index) native;
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable()
 @DomName('EntrySync')
 // http://www.w3.org/TR/file-system-api/#idl-def-EntrySync
 @Experimental()
@@ -30860,9 +30681,6 @@
   if (baseClassName == 'Element') baseClassName = 'HTMLElement';
 
   var baseConstructor = JS('=Object', '#[#]', context, baseClassName);
-  if (JS('bool', "typeof(#) != 'function'", baseConstructor)) {
-    throw new ArgumentError(type);
-  }
 
   var properties = JS('=Object', '{}');
 
@@ -31193,6 +31011,19 @@
    * error.
    */
   static final supportsSimd = false;
+
+  /**
+   * 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.
+   */
+  static void upgradeCustomElements(Node node) {
+    if (JS('bool', '(#.CustomElements && #.CustomElements.upgradeAll)',
+        window, window)) {
+      JS('', '#.CustomElements.upgradeAll(#)', window, node);
+    }
+  }
 }
 // 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
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 1daeb79..dc81135 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -1361,6 +1361,16 @@
   @DocsEditable()
   void set globalCompositeOperation(String value) native "CanvasRenderingContext2D_globalCompositeOperation_Setter";
 
+  @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
+  @DocsEditable()
+  @Experimental() // untriaged
+  bool get imageSmoothingEnabled native "CanvasRenderingContext2D_imageSmoothingEnabled_Getter";
+
+  @DomName('CanvasRenderingContext2D.imageSmoothingEnabled')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set imageSmoothingEnabled(bool value) native "CanvasRenderingContext2D_imageSmoothingEnabled_Setter";
+
   @DomName('CanvasRenderingContext2D.lineCap')
   @DocsEditable()
   String get lineCap native "CanvasRenderingContext2D_lineCap_Getter";
@@ -1464,20 +1474,6 @@
   @Experimental()
   num get backingStorePixelRatio native "CanvasRenderingContext2D_webkitBackingStorePixelRatio_Getter";
 
-  @DomName('CanvasRenderingContext2D.webkitImageSmoothingEnabled')
-  @DocsEditable()
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental()
-  bool get imageSmoothingEnabled native "CanvasRenderingContext2D_webkitImageSmoothingEnabled_Getter";
-
-  @DomName('CanvasRenderingContext2D.webkitImageSmoothingEnabled')
-  @DocsEditable()
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental()
-  void set imageSmoothingEnabled(bool value) native "CanvasRenderingContext2D_webkitImageSmoothingEnabled_Setter";
-
   @DomName('CanvasRenderingContext2D.arc')
   @DocsEditable()
   void $dom_arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native "CanvasRenderingContext2D_arc_Callback";
@@ -1539,6 +1535,11 @@
   @DocsEditable()
   CanvasGradient createRadialGradient(num x0, num y0, num r0, num x1, num y1, num r1) native "CanvasRenderingContext2D_createRadialGradient_Callback";
 
+  @DomName('CanvasRenderingContext2D.drawCustomFocusRing')
+  @DocsEditable()
+  @Experimental() // untriaged
+  bool drawCustomFocusRing(Element element) native "CanvasRenderingContext2D_drawCustomFocusRing_Callback";
+
   void _drawImage(canvas_OR_image_OR_imageBitmap_OR_video, num sx_OR_x, num sy_OR_y, [num sw_OR_width, num height_OR_sh, num dx, num dy, num dw, num dh]) {
     if ((sy_OR_y is num || sy_OR_y == null) && (sx_OR_x is num || sx_OR_x == null) && (canvas_OR_image_OR_imageBitmap_OR_video is ImageElement || canvas_OR_image_OR_imageBitmap_OR_video == null) && sw_OR_width == null && height_OR_sh == null && dx == null && dy == null && dw == null && dh == null) {
       _drawImage_1(canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y);
@@ -1615,6 +1616,11 @@
 
   void _drawImage_12(canvas_OR_image_OR_imageBitmap_OR_video, sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh, dx, dy, dw, dh) native "CanvasRenderingContext2D__drawImage_12_Callback";
 
+  @DomName('CanvasRenderingContext2D.drawSystemFocusRing')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void drawSystemFocusRing(Element element) native "CanvasRenderingContext2D_drawSystemFocusRing_Callback";
+
   void fill([String winding]) {
     if (winding != null) {
       _fill_1(winding);
@@ -6986,7 +6992,7 @@
 
   @DomName('DataTransferItem.getAsString')
   @DocsEditable()
-  void _getAsString([_StringCallback callback]) native "DataTransferItem_getAsString_Callback";
+  void _getAsString(_StringCallback callback) native "DataTransferItem_getAsString_Callback";
 
   Future<String> getAsString() {
     var completer = new Completer<String>();
@@ -7718,27 +7724,6 @@
   @DocsEditable()
   Event $dom_createEvent(String eventType) native "Document_createEvent_Callback";
 
-  NodeIterator $dom_createNodeIterator(Node root, [int whatToShow, NodeFilter filter, bool expandEntityReferences]) {
-    if (expandEntityReferences != null) {
-      return _createNodeIterator_1(root, whatToShow, filter, expandEntityReferences);
-    }
-    if (filter != null) {
-      return _createNodeIterator_2(root, whatToShow, filter);
-    }
-    if (whatToShow != null) {
-      return _createNodeIterator_3(root, whatToShow);
-    }
-    return _createNodeIterator_4(root);
-  }
-
-  NodeIterator _createNodeIterator_1(root, whatToShow, filter, expandEntityReferences) native "Document__createNodeIterator_1_Callback";
-
-  NodeIterator _createNodeIterator_2(root, whatToShow, filter) native "Document__createNodeIterator_2_Callback";
-
-  NodeIterator _createNodeIterator_3(root, whatToShow) native "Document__createNodeIterator_3_Callback";
-
-  NodeIterator _createNodeIterator_4(root) native "Document__createNodeIterator_4_Callback";
-
   @DomName('Document.createRange')
   @DocsEditable()
   Range $dom_createRange() native "Document_createRange_Callback";
@@ -7760,27 +7745,6 @@
   @Experimental()
   TouchList $dom_createTouchList() native "Document_createTouchList_Callback";
 
-  TreeWalker $dom_createTreeWalker(Node root, [int whatToShow, NodeFilter filter, bool expandEntityReferences]) {
-    if (expandEntityReferences != null) {
-      return _createTreeWalker_1(root, whatToShow, filter, expandEntityReferences);
-    }
-    if (filter != null) {
-      return _createTreeWalker_2(root, whatToShow, filter);
-    }
-    if (whatToShow != null) {
-      return _createTreeWalker_3(root, whatToShow);
-    }
-    return _createTreeWalker_4(root);
-  }
-
-  TreeWalker _createTreeWalker_1(root, whatToShow, filter, expandEntityReferences) native "Document__createTreeWalker_1_Callback";
-
-  TreeWalker _createTreeWalker_2(root, whatToShow, filter) native "Document__createTreeWalker_2_Callback";
-
-  TreeWalker _createTreeWalker_3(root, whatToShow) native "Document__createTreeWalker_3_Callback";
-
-  TreeWalker _createTreeWalker_4(root) native "Document__createTreeWalker_4_Callback";
-
   @DomName('Document.elementFromPoint')
   @DocsEditable()
   Element $dom_elementFromPoint(int x, int y) native "Document_elementFromPoint_Callback";
@@ -8167,6 +8131,11 @@
   ElementList queryAll(String selectors) {
     return new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
   }
+
+  /// Checks if [register] is supported on the current platform.
+  bool get supportsRegister {
+    return true;
+  }
 }
 // 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
@@ -9046,7 +9015,7 @@
   // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
   @Experimental()
   ElementStream<Event> get onFullscreenError;
- 
+
 }
 
 // TODO(jacobr): this is an inefficient implementation but it is hard to see
@@ -10029,6 +9998,8 @@
     Point p = Element._offsetToHelper(parentOffset, parent);
     return new Point(p.x + current.offsetLeft, p.y + current.offsetTop);
   }
+
+
   // To suppress missing implicit constructor warnings.
   factory Element._() { throw new UnsupportedError("Not supported"); }
 
@@ -10267,10 +10238,10 @@
 
   bool hidden;
 
-  String id;
-
   String innerHtml;
 
+  InputMethodContext get inputMethodContext;
+
   bool get isContentEditable;
 
   String lang;
@@ -10289,8 +10260,6 @@
 
   void click();
 
-  InputMethodContext getInputContext();
-
   Element insertAdjacentElement(String where, Element element);
 
   void insertAdjacentHtml(String where, String html);
@@ -10331,6 +10300,14 @@
   @DocsEditable()
   int get clientWidth native "Element_clientWidth_Getter";
 
+  @DomName('Element.id')
+  @DocsEditable()
+  String get id native "Element_id_Getter";
+
+  @DomName('Element.id')
+  @DocsEditable()
+  void set id(String value) native "Element_id_Setter";
+
   @DomName('Element.offsetHeight')
   @DocsEditable()
   int get offsetHeight native "Element_offsetHeight_Getter";
@@ -10438,6 +10415,11 @@
   @DocsEditable()
   List<Rect> getClientRects() native "Element_getClientRects_Callback";
 
+  @DomName('Element.getDestinationInsertionPoints')
+  @DocsEditable()
+  @Experimental() // untriaged
+  List<Node> getDestinationInsertionPoints() native "Element_getDestinationInsertionPoints_Callback";
+
   @DomName('Element.getElementsByClassName')
   @DocsEditable()
   List<Node> getElementsByClassName(String name) native "Element_getElementsByClassName_Callback";
@@ -11208,6 +11190,16 @@
   // To suppress missing implicit constructor warnings.
   factory ErrorEvent._() { throw new UnsupportedError("Not supported"); }
 
+  @DomName('ErrorEvent.colno')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int get colno native "ErrorEvent_colno_Getter";
+
+  @DomName('ErrorEvent.error')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Object get error native "ErrorEvent_error_Getter";
+
   @DomName('ErrorEvent.filename')
   @DocsEditable()
   String get filename native "ErrorEvent_filename_Getter";
@@ -13012,6 +13004,18 @@
   @DocsEditable()
   Element get activeElement native "HTMLDocument_activeElement_Getter";
 
+  @DomName('HTMLDocument.captureEvents')
+  @DocsEditable()
+  // http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture
+  @deprecated // deprecated
+  void captureEvents() native "HTMLDocument_captureEvents_Callback";
+
+  @DomName('HTMLDocument.releaseEvents')
+  @DocsEditable()
+  // http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture
+  @deprecated // deprecated
+  void releaseEvents() native "HTMLDocument_releaseEvents_Callback";
+
 
   @DomName('Document.body')
   BodyElement get body => $dom_body;
@@ -13213,14 +13217,6 @@
   @DocsEditable()
   void set hidden(bool value) native "HTMLElement_hidden_Setter";
 
-  @DomName('HTMLElement.id')
-  @DocsEditable()
-  String get id native "HTMLElement_id_Getter";
-
-  @DomName('HTMLElement.id')
-  @DocsEditable()
-  void set id(String value) native "HTMLElement_id_Setter";
-
   @DomName('HTMLElement.innerHTML')
   @DocsEditable()
   String get innerHtml native "HTMLElement_innerHTML_Getter";
@@ -13229,6 +13225,11 @@
   @DocsEditable()
   void set innerHtml(String value) native "HTMLElement_innerHTML_Setter";
 
+  @DomName('HTMLElement.inputMethodContext')
+  @DocsEditable()
+  @Experimental() // untriaged
+  InputMethodContext get inputMethodContext native "HTMLElement_inputMethodContext_Getter";
+
   @DomName('HTMLElement.isContentEditable')
   @DocsEditable()
   bool get isContentEditable native "HTMLElement_isContentEditable_Getter";
@@ -13301,12 +13302,6 @@
   @DocsEditable()
   void click() native "HTMLElement_click_Callback";
 
-  @DomName('HTMLElement.getInputContext')
-  @DocsEditable()
-  // http://www.w3.org/TR/ime-api/#the-getinputcontext-method
-  @Experimental()
-  InputMethodContext getInputContext() native "HTMLElement_getInputContext_Callback";
-
   @DomName('HTMLElement.insertAdjacentElement')
   @DocsEditable()
   @Experimental() // non-standard
@@ -14172,16 +14167,6 @@
   int get width native "ImageBitmap_width_Getter";
 
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DomName('ImageBitmapCallback')
-@Experimental() // untriaged
-typedef void ImageBitmapCallback(ImageBitmap bitmap);
 // Copyright (c) 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.
@@ -15491,6 +15476,26 @@
   // To suppress missing implicit constructor warnings.
   factory KeyboardEvent._() { throw new UnsupportedError("Not supported"); }
 
+  @DomName('KeyboardEvent.DOM_KEY_LOCATION_LEFT')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const int DOM_KEY_LOCATION_LEFT = 0x01;
+
+  @DomName('KeyboardEvent.DOM_KEY_LOCATION_NUMPAD')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const int DOM_KEY_LOCATION_NUMPAD = 0x03;
+
+  @DomName('KeyboardEvent.DOM_KEY_LOCATION_RIGHT')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const int DOM_KEY_LOCATION_RIGHT = 0x02;
+
+  @DomName('KeyboardEvent.DOM_KEY_LOCATION_STANDARD')
+  @DocsEditable()
+  @Experimental() // untriaged
+  static const int DOM_KEY_LOCATION_STANDARD = 0x00;
+
   @DomName('KeyboardEvent.altGraphKey')
   @DocsEditable()
   @Experimental() // nonstandard
@@ -15514,6 +15519,11 @@
   @Experimental() // nonstandard
   int get keyLocation native "KeyboardEvent_keyLocation_Getter";
 
+  @DomName('KeyboardEvent.location')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int get location native "KeyboardEvent_location_Getter";
+
   @DomName('KeyboardEvent.metaKey')
   @DocsEditable()
   bool get metaKey native "KeyboardEvent_metaKey_Getter";
@@ -15522,9 +15532,14 @@
   @DocsEditable()
   bool get shiftKey native "KeyboardEvent_shiftKey_Getter";
 
+  @DomName('KeyboardEvent.getModifierState')
+  @DocsEditable()
+  @Experimental() // untriaged
+  bool getModifierState(String keyArgument) native "KeyboardEvent_getModifierState_Callback";
+
   @DomName('KeyboardEvent.initKeyboardEvent')
   @DocsEditable()
-  void $dom_initKeyboardEvent(String type, bool canBubble, bool cancelable, Window view, String keyIdentifier, int keyLocation, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey) native "KeyboardEvent_initKeyboardEvent_Callback";
+  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";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -19270,47 +19285,6 @@
   static const int SHOW_TEXT = 0x00000004;
 
 }
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DomName('NodeIterator')
-@Unstable()
-class NodeIterator extends NativeFieldWrapperClass1 {
-  factory NodeIterator(Node root, int whatToShow) {
-    return document.$dom_createNodeIterator(root, whatToShow, null, false);
-  }
-
-  @DomName('NodeIterator.pointerBeforeReferenceNode')
-  @DocsEditable()
-  bool get pointerBeforeReferenceNode native "NodeIterator_pointerBeforeReferenceNode_Getter";
-
-  @DomName('NodeIterator.referenceNode')
-  @DocsEditable()
-  Node get referenceNode native "NodeIterator_referenceNode_Getter";
-
-  @DomName('NodeIterator.root')
-  @DocsEditable()
-  Node get root native "NodeIterator_root_Getter";
-
-  @DomName('NodeIterator.whatToShow')
-  @DocsEditable()
-  int get whatToShow native "NodeIterator_whatToShow_Getter";
-
-  @DomName('NodeIterator.detach')
-  @DocsEditable()
-  void detach() native "NodeIterator_detach_Callback";
-
-  @DomName('NodeIterator.nextNode')
-  @DocsEditable()
-  Node nextNode() native "NodeIterator_nextNode_Callback";
-
-  @DomName('NodeIterator.previousNode')
-  @DocsEditable()
-  Node previousNode() native "NodeIterator_previousNode_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.
@@ -19571,10 +19545,6 @@
   @DocsEditable()
   int checkPermission() native "NotificationCenter_checkPermission_Callback";
 
-  @DomName('NotificationCenter.createHTMLNotification')
-  @DocsEditable()
-  Notification createHtmlNotification(String url) native "NotificationCenter_createHTMLNotification_Callback";
-
   @DomName('NotificationCenter.createNotification')
   @DocsEditable()
   Notification createNotification(String iconUrl, String title, String body) native "NotificationCenter_createNotification_Callback";
@@ -20178,7 +20148,9 @@
 @SupportedBrowser(SupportedBrowser.CHROME)
 @SupportedBrowser(SupportedBrowser.FIREFOX)
 @SupportedBrowser(SupportedBrowser.IE)
-class Performance extends NativeFieldWrapperClass1 {
+class Performance extends EventTarget {
+  // To suppress missing implicit constructor warnings.
+  factory Performance._() { throw new UnsupportedError("Not supported"); }
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -20258,6 +20230,21 @@
   // http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming-methods
   void setResourceTimingBufferSize(int maxSize) native "Performance_webkitSetResourceTimingBufferSize_Callback";
 
+  @DomName('Performance.addEventListener')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "Performance_addEventListener_Callback";
+
+  @DomName('Performance.dispatchEvent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  bool dispatchEvent(Event event) native "Performance_dispatchEvent_Callback";
+
+  @DomName('Performance.removeEventListener')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "Performance_removeEventListener_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
@@ -21209,6 +21196,51 @@
 
 
 @DocsEditable()
+@DomName('RsaKeyGenParams')
+@Experimental() // untriaged
+class RsaKeyGenParams extends Algorithm {
+  // To suppress missing implicit constructor warnings.
+  factory RsaKeyGenParams._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('RsaKeyGenParams.modulusLength')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int get modulusLength native "RsaKeyGenParams_modulusLength_Getter";
+
+  @DomName('RsaKeyGenParams.publicExponent')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Uint8List get publicExponent native "RsaKeyGenParams_publicExponent_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable()
+@DomName('RsaSsaParams')
+@Experimental() // untriaged
+class RsaSsaParams extends Algorithm {
+  // To suppress missing implicit constructor warnings.
+  factory RsaSsaParams._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('RsaSsaParams.hash')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Algorithm get hash native "RsaSsaParams_hash_Getter";
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable()
 @DomName('RTCDataChannel')
 // http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCDataChannel
 @Experimental()
@@ -21244,10 +21276,40 @@
   @DocsEditable()
   int get bufferedAmount native "RTCDataChannel_bufferedAmount_Getter";
 
+  @DomName('RTCDataChannel.id')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int get id native "RTCDataChannel_id_Getter";
+
   @DomName('RTCDataChannel.label')
   @DocsEditable()
   String get label native "RTCDataChannel_label_Getter";
 
+  @DomName('RTCDataChannel.maxRetransmitTime')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int get maxRetransmitTime native "RTCDataChannel_maxRetransmitTime_Getter";
+
+  @DomName('RTCDataChannel.maxRetransmits')
+  @DocsEditable()
+  @Experimental() // untriaged
+  int get maxRetransmits native "RTCDataChannel_maxRetransmits_Getter";
+
+  @DomName('RTCDataChannel.negotiated')
+  @DocsEditable()
+  @Experimental() // untriaged
+  bool get negotiated native "RTCDataChannel_negotiated_Getter";
+
+  @DomName('RTCDataChannel.ordered')
+  @DocsEditable()
+  @Experimental() // untriaged
+  bool get ordered native "RTCDataChannel_ordered_Getter";
+
+  @DomName('RTCDataChannel.protocol')
+  @DocsEditable()
+  @Experimental() // untriaged
+  String get protocol native "RTCDataChannel_protocol_Getter";
+
   @DomName('RTCDataChannel.readyState')
   @DocsEditable()
   String get readyState native "RTCDataChannel_readyState_Getter";
@@ -22528,6 +22590,26 @@
   // To suppress missing implicit constructor warnings.
   factory SourceBuffer._() { throw new UnsupportedError("Not supported"); }
 
+  @DomName('SourceBuffer.appendWindowEnd')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num get appendWindowEnd native "SourceBuffer_appendWindowEnd_Getter";
+
+  @DomName('SourceBuffer.appendWindowEnd')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set appendWindowEnd(num value) native "SourceBuffer_appendWindowEnd_Setter";
+
+  @DomName('SourceBuffer.appendWindowStart')
+  @DocsEditable()
+  @Experimental() // untriaged
+  num get appendWindowStart native "SourceBuffer_appendWindowStart_Getter";
+
+  @DomName('SourceBuffer.appendWindowStart')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void set appendWindowStart(num value) native "SourceBuffer_appendWindowStart_Setter";
+
   @DomName('SourceBuffer.buffered')
   @DocsEditable()
   TimeRanges get buffered native "SourceBuffer_buffered_Getter";
@@ -22559,6 +22641,11 @@
   @Experimental() // untriaged
   void appendBufferView(TypedData data) native "SourceBuffer_appendBufferView_Callback";
 
+  @DomName('SourceBuffer.remove')
+  @DocsEditable()
+  @Experimental() // untriaged
+  void remove(num start, num end) native "SourceBuffer_remove_Callback";
+
   @DomName('SourceBuffer.addEventListener')
   @DocsEditable()
   @Experimental() // untriaged
@@ -23929,7 +24016,7 @@
   @DomName('SubtleCrypto.decrypt')
   @DocsEditable()
   @Experimental() // untriaged
-  CryptoOperation decrypt(Map algorithm) native "SubtleCrypto_decrypt_Callback";
+  CryptoOperation decrypt(Map algorithm, CryptoKey key) native "SubtleCrypto_decrypt_Callback";
 
   @DomName('SubtleCrypto.digest')
   @DocsEditable()
@@ -23939,7 +24026,12 @@
   @DomName('SubtleCrypto.encrypt')
   @DocsEditable()
   @Experimental() // untriaged
-  CryptoOperation encrypt(Map algorithm) native "SubtleCrypto_encrypt_Callback";
+  CryptoOperation encrypt(Map algorithm, CryptoKey key) native "SubtleCrypto_encrypt_Callback";
+
+  @DomName('SubtleCrypto.generateKey')
+  @DocsEditable()
+  @Experimental() // untriaged
+  Object generateKey(Map algorithm, bool extractable, List<String> keyUsages) native "SubtleCrypto_generateKey_Callback";
 
   @DomName('SubtleCrypto.importKey')
   @DocsEditable()
@@ -23949,12 +24041,12 @@
   @DomName('SubtleCrypto.sign')
   @DocsEditable()
   @Experimental() // untriaged
-  CryptoOperation sign(Map algorithm) native "SubtleCrypto_sign_Callback";
+  CryptoOperation sign(Map algorithm, CryptoKey key) native "SubtleCrypto_sign_Callback";
 
   @DomName('SubtleCrypto.verify')
   @DocsEditable()
   @Experimental() // untriaged
-  CryptoOperation verify(Map algorithm) native "SubtleCrypto_verify_Callback";
+  CryptoOperation verify(Map algorithm, CryptoKey key, TypedData signature) native "SubtleCrypto_verify_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -24567,6 +24659,11 @@
   @DocsEditable()
   String get wholeText native "Text_wholeText_Getter";
 
+  @DomName('Text.getDestinationInsertionPoints')
+  @DocsEditable()
+  @Experimental() // untriaged
+  List<Node> getDestinationInsertionPoints() native "Text_getDestinationInsertionPoints_Callback";
+
   @DomName('Text.replaceWholeText')
   @DocsEditable()
   // http://dom.spec.whatwg.org/#dom-text-replacewholetext
@@ -25668,73 +25765,6 @@
   String get pseudoElement native "TransitionEvent_pseudoElement_Getter";
 
 }
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DomName('TreeWalker')
-@Unstable()
-class TreeWalker extends NativeFieldWrapperClass1 {
-  factory TreeWalker(Node root, int whatToShow) {
-    return document.$dom_createTreeWalker(root, whatToShow, null, false);
-  }
-
-  @DomName('TreeWalker.currentNode')
-  @DocsEditable()
-  Node get currentNode native "TreeWalker_currentNode_Getter";
-
-  @DomName('TreeWalker.currentNode')
-  @DocsEditable()
-  void set currentNode(Node value) native "TreeWalker_currentNode_Setter";
-
-  @DomName('TreeWalker.expandEntityReferences')
-  @DocsEditable()
-  // http://dom.spec.whatwg.org/#dom-traversal
-  @deprecated // deprecated
-  bool get expandEntityReferences native "TreeWalker_expandEntityReferences_Getter";
-
-  @DomName('TreeWalker.filter')
-  @DocsEditable()
-  NodeFilter get filter native "TreeWalker_filter_Getter";
-
-  @DomName('TreeWalker.root')
-  @DocsEditable()
-  Node get root native "TreeWalker_root_Getter";
-
-  @DomName('TreeWalker.whatToShow')
-  @DocsEditable()
-  int get whatToShow native "TreeWalker_whatToShow_Getter";
-
-  @DomName('TreeWalker.firstChild')
-  @DocsEditable()
-  Node firstChild() native "TreeWalker_firstChild_Callback";
-
-  @DomName('TreeWalker.lastChild')
-  @DocsEditable()
-  Node lastChild() native "TreeWalker_lastChild_Callback";
-
-  @DomName('TreeWalker.nextNode')
-  @DocsEditable()
-  Node nextNode() native "TreeWalker_nextNode_Callback";
-
-  @DomName('TreeWalker.nextSibling')
-  @DocsEditable()
-  Node nextSibling() native "TreeWalker_nextSibling_Callback";
-
-  @DomName('TreeWalker.parentNode')
-  @DocsEditable()
-  Node parentNode() native "TreeWalker_parentNode_Callback";
-
-  @DomName('TreeWalker.previousNode')
-  @DocsEditable()
-  Node previousNode() native "TreeWalker_previousNode_Callback";
-
-  @DomName('TreeWalker.previousSibling')
-  @DocsEditable()
-  Node previousSibling() native "TreeWalker_previousSibling_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.
@@ -25885,13 +25915,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 MediaStream || blob_OR_source_OR_stream == null)) {
+    if ((blob_OR_source_OR_stream is MediaSource || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_2(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 _WebKitMediaSource || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_3(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 MediaStream || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_4(blob_OR_source_OR_stream);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
@@ -26886,6 +26916,12 @@
   @DocsEditable()
   void cancelAnimationFrame(int id) native "Window_cancelAnimationFrame_Callback";
 
+  @DomName('Window.captureEvents')
+  @DocsEditable()
+  // http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture
+  @deprecated // deprecated
+  void captureEvents() native "Window_captureEvents_Callback";
+
   @DomName('Window.close')
   @DocsEditable()
   void close() native "Window_close_Callback";
@@ -26894,82 +26930,6 @@
   @DocsEditable()
   bool confirm(String message) native "Window_confirm_Callback";
 
-  void _createImageBitmap(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, ImageBitmapCallback callback, [int sx, int sy, int sw, int sh]) {
-    if ((callback is ImageBitmapCallback || callback == null) && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is ImageElement || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null) && sx == null && sy == null && sw == null && sh == null) {
-      _createImageBitmap_1(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback);
-      return;
-    }
-    if ((sh is int || sh == null) && (sw is int || sw == null) && (sy is int || sy == null) && (sx is int || sx == null) && (callback is ImageBitmapCallback || callback == null) && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is ImageElement || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null)) {
-      _createImageBitmap_2(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh);
-      return;
-    }
-    if ((callback is ImageBitmapCallback || callback == null) && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is VideoElement || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null) && sx == null && sy == null && sw == null && sh == null) {
-      _createImageBitmap_3(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback);
-      return;
-    }
-    if ((sh is int || sh == null) && (sw is int || sw == null) && (sy is int || sy == null) && (sx is int || sx == null) && (callback is ImageBitmapCallback || callback == null) && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is VideoElement || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null)) {
-      _createImageBitmap_4(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh);
-      return;
-    }
-    if ((callback is ImageBitmapCallback || callback == null) && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is CanvasRenderingContext2D || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null) && sx == null && sy == null && sw == null && sh == null) {
-      _createImageBitmap_5(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback);
-      return;
-    }
-    if ((sh is int || sh == null) && (sw is int || sw == null) && (sy is int || sy == null) && (sx is int || sx == null) && (callback is ImageBitmapCallback || callback == null) && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is CanvasRenderingContext2D || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null)) {
-      _createImageBitmap_6(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh);
-      return;
-    }
-    if ((callback is ImageBitmapCallback || callback == null) && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is CanvasElement || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null) && sx == null && sy == null && sw == null && sh == null) {
-      _createImageBitmap_7(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback);
-      return;
-    }
-    if ((sh is int || sh == null) && (sw is int || sw == null) && (sy is int || sy == null) && (sx is int || sx == null) && (callback is ImageBitmapCallback || callback == null) && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is CanvasElement || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null)) {
-      _createImageBitmap_8(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh);
-      return;
-    }
-    if ((callback is ImageBitmapCallback || callback == null) && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is ImageData || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null) && sx == null && sy == null && sw == null && sh == null) {
-      _createImageBitmap_9(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback);
-      return;
-    }
-    if ((sh is int || sh == null) && (sw is int || sw == null) && (sy is int || sy == null) && (sx is int || sx == null) && (callback is ImageBitmapCallback || callback == null) && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is ImageData || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null)) {
-      _createImageBitmap_10(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh);
-      return;
-    }
-    if ((callback is ImageBitmapCallback || callback == null) && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is ImageBitmap || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null) && sx == null && sy == null && sw == null && sh == null) {
-      _createImageBitmap_11(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback);
-      return;
-    }
-    if ((sh is int || sh == null) && (sw is int || sw == null) && (sy is int || sy == null) && (sx is int || sx == null) && (callback is ImageBitmapCallback || callback == null) && (bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video is ImageBitmap || bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video == null)) {
-      _createImageBitmap_12(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh);
-      return;
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
-
-  void _createImageBitmap_1(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback) native "Window__createImageBitmap_1_Callback";
-
-  void _createImageBitmap_2(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh) native "Window__createImageBitmap_2_Callback";
-
-  void _createImageBitmap_3(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback) native "Window__createImageBitmap_3_Callback";
-
-  void _createImageBitmap_4(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh) native "Window__createImageBitmap_4_Callback";
-
-  void _createImageBitmap_5(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback) native "Window__createImageBitmap_5_Callback";
-
-  void _createImageBitmap_6(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh) native "Window__createImageBitmap_6_Callback";
-
-  void _createImageBitmap_7(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback) native "Window__createImageBitmap_7_Callback";
-
-  void _createImageBitmap_8(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh) native "Window__createImageBitmap_8_Callback";
-
-  void _createImageBitmap_9(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback) native "Window__createImageBitmap_9_Callback";
-
-  void _createImageBitmap_10(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh) native "Window__createImageBitmap_10_Callback";
-
-  void _createImageBitmap_11(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback) native "Window__createImageBitmap_11_Callback";
-
-  void _createImageBitmap_12(bitmap_OR_canvas_OR_context_OR_data_OR_image_OR_video, callback, sx, sy, sw, sh) native "Window__createImageBitmap_12_Callback";
-
   @DomName('Window.find')
   @DocsEditable()
   @Experimental() // non-standard
@@ -27021,6 +26981,12 @@
   @DocsEditable()
   void print() native "Window_print_Callback";
 
+  @DomName('Window.releaseEvents')
+  @DocsEditable()
+  // http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture
+  @deprecated // deprecated
+  void releaseEvents() native "Window_releaseEvents_Callback";
+
   @DomName('Window.requestAnimationFrame')
   @DocsEditable()
   int requestAnimationFrame(RequestAnimationFrameCallback callback) native "Window_requestAnimationFrame_Callback";
@@ -28587,140 +28553,6 @@
 
 
 @DocsEditable()
-@DomName('EntryArray')
-// http://www.w3.org/TR/file-system-api/#the-entry-interface
-@Experimental()
-class _EntryArray extends NativeFieldWrapperClass1 with ListMixin<Entry>, ImmutableListMixin<Entry> implements List<Entry> {
-
-  @DomName('EntryArray.length')
-  @DocsEditable()
-  int get length native "EntryArray_length_Getter";
-
-  Entry operator[](int index) {
-    if (index < 0 || index >= length)
-      throw new RangeError.range(index, 0, length);
-    return _nativeIndexedGetter(index);
-  }
-  Entry _nativeIndexedGetter(int index) native "EntryArray_item_Callback";
-
-  void operator[]=(int index, Entry value) {
-    throw new UnsupportedError("Cannot assign element of immutable List.");
-  }
-  // -- start List<Entry> mixins.
-  // Entry is the element type.
-
-
-  void set length(int value) {
-    throw new UnsupportedError("Cannot resize immutable List.");
-  }
-
-  Entry get first {
-    if (this.length > 0) {
-      return this[0];
-    }
-    throw new StateError("No elements");
-  }
-
-  Entry get last {
-    int len = this.length;
-    if (len > 0) {
-      return this[len - 1];
-    }
-    throw new StateError("No elements");
-  }
-
-  Entry get single {
-    int len = this.length;
-    if (len == 1) {
-      return this[0];
-    }
-    if (len == 0) throw new StateError("No elements");
-    throw new StateError("More than one element");
-  }
-
-  Entry elementAt(int index) => this[index];
-  // -- end List<Entry> mixins.
-
-  @DomName('EntryArray.item')
-  @DocsEditable()
-  Entry item(int index) native "EntryArray_item_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable()
-@DomName('EntryArraySync')
-// http://www.w3.org/TR/file-system-api/#idl-def-EntrySync
-@Experimental()
-class _EntryArraySync extends NativeFieldWrapperClass1 with ListMixin<_EntrySync>, ImmutableListMixin<_EntrySync> implements List<_EntrySync> {
-
-  @DomName('EntryArraySync.length')
-  @DocsEditable()
-  int get length native "EntryArraySync_length_Getter";
-
-  _EntrySync operator[](int index) {
-    if (index < 0 || index >= length)
-      throw new RangeError.range(index, 0, length);
-    return _nativeIndexedGetter(index);
-  }
-  _EntrySync _nativeIndexedGetter(int index) native "EntryArraySync_item_Callback";
-
-  void operator[]=(int index, _EntrySync value) {
-    throw new UnsupportedError("Cannot assign element of immutable List.");
-  }
-  // -- start List<_EntrySync> mixins.
-  // _EntrySync is the element type.
-
-
-  void set length(int value) {
-    throw new UnsupportedError("Cannot resize immutable List.");
-  }
-
-  _EntrySync get first {
-    if (this.length > 0) {
-      return this[0];
-    }
-    throw new StateError("No elements");
-  }
-
-  _EntrySync get last {
-    int len = this.length;
-    if (len > 0) {
-      return this[len - 1];
-    }
-    throw new StateError("No elements");
-  }
-
-  _EntrySync get single {
-    int len = this.length;
-    if (len == 1) {
-      return this[0];
-    }
-    if (len == 0) throw new StateError("No elements");
-    throw new StateError("More than one element");
-  }
-
-  _EntrySync elementAt(int index) => this[index];
-  // -- end List<_EntrySync> mixins.
-
-  @DomName('EntryArraySync.item')
-  @DocsEditable()
-  _EntrySync item(int index) native "EntryArraySync_item_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable()
 @DomName('EntrySync')
 // http://www.w3.org/TR/file-system-api/#idl-def-EntrySync
 @Experimental()
@@ -32424,6 +32256,16 @@
    * 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
@@ -33278,15 +33120,20 @@
   // DOM node rather than just a class that extends Node.
   static bool isNode(obj) => obj is Node;
 
+  static bool _isBuiltinType(ClassMirror cls) {
+    // TODO(vsm): Find a less hackish way to do this.
+    LibraryMirror lib = cls.owner;
+    String libName = lib.uri.toString();
+    return libName.startsWith('dart:');
+  }
+
   static void register(String tag, Type type) {
     // TODO(vsm): Move these checks into native code.
     if (type == null) {
       throw new UnsupportedError("Invalid null type.");
     }
     ClassMirror cls = reflectClass(type);
-    LibraryMirror lib = cls.owner;
-    String libName = lib.uri.toString();
-    if (libName.startsWith('dart:')) {
+    if (_isBuiltinType(cls)) {
       throw new UnsupportedError("Invalid custom element from $libName.");
     }
     ClassMirror superClass = cls.superclass;
@@ -33299,17 +33146,21 @@
     bool isElement(ClassMirror cls) =>
       cls != null && cls.qualifiedName == elementName;
 
+    ClassMirror nativeClass = _isBuiltinType(superClass) ? superClass : null;
     while(!isRoot(superClass) && !isElement(superClass)) {
       superClass = superClass.superclass;
+      if (nativeClass == null && _isBuiltinType(superClass)) {
+        nativeClass = superClass;
+      }
     }
 
     if (isRoot(superClass)) {
       throw new UnsupportedError("Invalid custom element doesn't inherit from HtmlElement.");
     }
-    _register(tag, type);
+    _register(tag, type, nativeClass.reflectedType);
   }
 
-  static void _register(String tag, Type type) native "Utils_register";
+  static void _register(String tag, Type customType, Type nativeType) native "Utils_register";
 }
 
 class _NPObject extends NativeFieldWrapperClass1 {
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index f621360..1dd2b47 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -521,7 +521,7 @@
     var controller = new StreamController(sync: true);
     controller.stream
         .transform(new StringDecoder(encoding))
-        .transform(new LineTransformer())
+        .transform(new LineSplitter())
         .listen((line) => list.add(line));
     controller.add(bytes);
     controller.close();
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 1433ac8..df228f5 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -204,6 +204,17 @@
    * added to each response.
    */
   String serverHeader;
+
+  /**
+   * Get or set the timeout used for idle keep-alive connections. If no further
+   * request is seen within [idleTimeout] after the previous request was
+   * completed, the connection is droped.
+   *
+   * Default is 120 seconds.
+   *
+   * To disable, set [idleTimeout] to `null`.
+   */
+  Duration idleTimeout;
 }
 
 
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index 615c59a..7eaf153 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -1824,14 +1824,17 @@
   final _HttpServer _httpServer;
   final _HttpParser _httpParser;
   StreamSubscription _subscription;
+  Timer _idleTimer;
 
   Future _streamFuture;
 
   _HttpConnection(Socket this._socket, _HttpServer this._httpServer)
       : _httpParser = new _HttpParser.requestParser() {
+    _startTimeout();
     _socket.pipe(_httpParser);
     _subscription = _httpParser.listen(
         (incoming) {
+          _stopTimeout();
           // If the incoming was closed, close the connection.
           incoming.dataDone.then((closing) {
             if (closing) destroy();
@@ -1854,6 +1857,7 @@
                     request.persistentConnection &&
                     incoming.fullBodyRead) {
                   _state = _IDLE;
+                  _startTimeout();
                   // Resume the subscription for incoming requests as the
                   // request is now processed.
                   _subscription.resume();
@@ -1879,7 +1883,21 @@
         });
   }
 
+  void _startTimeout() {
+    assert(_state == _IDLE);
+    _stopTimeout();
+    if (_httpServer.idleTimeout == null) return;
+    _idleTimer = new Timer(_httpServer.idleTimeout, () {
+      destroy();
+    });
+  }
+
+  void _stopTimeout() {
+    if (_idleTimer != null) _idleTimer.cancel();
+  }
+
   void destroy() {
+    _stopTimeout();
     if (_state == _CLOSING || _state == _DETACHED) return;
     _state = _CLOSING;
     _socket.destroy();
@@ -1887,6 +1905,7 @@
   }
 
   Future<Socket> detachSocket() {
+    _stopTimeout();
     _state = _DETACHED;
     // Remove connection from server.
     _httpServer._connectionClosed(this);
@@ -1911,6 +1930,8 @@
 class _HttpServer extends Stream<HttpRequest> implements HttpServer {
   String serverHeader = _getHttpVersion();
 
+  Duration idleTimeout = const Duration(seconds: 120);
+
   static Future<HttpServer> bind(address, int port, int backlog) {
     return ServerSocket.bind(address, port, backlog: backlog).then((socket) {
       return new _HttpServer._(socket, true);
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index 16b3595..30a9a9f 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -89,6 +89,22 @@
    */
   static String get script => _nativeScript;
 
+  /**
+   * Returns the flags passed to the executable used to run the script in this
+   * isolate. These are the command-line flags between the executable name
+   * and the script name. Each fetch of executableArguments returns a new
+   * List, containing the flags passed to the executable.
+   */
+  static List<String> get executableArguments => _Platform.executableArguments;
+
+  /**
+   * Returns the value of the --package-root flag passed to the executable
+   * used to run the script in this isolate.  This is the directory in which
+   * Dart packages are looked up.
+   *
+   * If there is no --package-root flag, then the empty string is returned.
+   */
+  static String get packageRoot => _Platform.packageRoot;
 
   /**
    * Returns the version of the current Dart runtime.
diff --git a/sdk/lib/io/platform_impl.dart b/sdk/lib/io/platform_impl.dart
index 94d67b6..56a5869 100644
--- a/sdk/lib/io/platform_impl.dart
+++ b/sdk/lib/io/platform_impl.dart
@@ -11,6 +11,8 @@
   external static _localHostname();
   external static _executable();
   external static _environment();
+  external static List<String> _executableArguments();
+  external static String _packageRoot();
   external static String _version();
 
   static int get numberOfProcessors => _numberOfProcessors();
@@ -27,6 +29,8 @@
   }
 
   static String executable = _executable();
+  static String packageRoot = _packageRoot();
+  static List<String> get executableArguments => _executableArguments();
 
   static Map<String, String> get environment {
     var env = _environment();
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 1867050..0916023 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -441,7 +441,7 @@
   bool _closedWrite = false;  // The secure socket has been closed for writing.
   Completer _closeCompleter = new Completer();  // The network socket is gone.
   _FilterStatus _filterStatus = new _FilterStatus();
-  bool _connectPending = false;
+  bool _connectPending = true;
   bool _filterPending = false;
   bool _filterActive = false;
 
@@ -526,7 +526,6 @@
       futureSocket = new Future.value(socket);
     }
     futureSocket.then((rawSocket) {
-      _connectPending = true;
       _socket = rawSocket;
       _socket.readEventsEnabled = true;
       _socket.writeEventsEnabled = false;
@@ -775,8 +774,9 @@
     if (_status == CLOSED) {
       return;
     } else if (_connectPending) {
-      // _connectPending is true after the underlying connection has been
-      // made, but before the handshake has completed.
+      // _connectPending is true until the handshake has completed, and the
+      // _handshakeComplete future returned from SecureSocket.connect has
+      // completed.  Before this point, we must complete it with an error.
       _handshakeComplete.completeError(e);
     } else {
       _controller.addError(e);
diff --git a/sdk/lib/io/string_transformer.dart b/sdk/lib/io/string_transformer.dart
index 56e322c..5324d69 100644
--- a/sdk/lib/io/string_transformer.dart
+++ b/sdk/lib/io/string_transformer.dart
@@ -259,22 +259,6 @@
   return bytes;
 }
 
-// TODO(floitsch) Remove usage of LineTransformer
-// TODO(kevmoo) Remove usage of LineTransformer
-/**
- * Use [LineSplitter] from `dart:convert` instead.
- *
- * [LineTransformer] will be removed the 28 August 2013.
- */
- @deprecated
- class LineTransformer implements StreamTransformer<String, String> {
-  final _decoder = new LineSplitter();
-
-  Stream<String> bind(Stream<String> stream) {
-    return _decoder.bind(stream);
-  }
-}
-
 
 abstract class _SingleByteDecoder
     extends StreamEventTransformer<List<int>, String> {
diff --git a/sdk/lib/math/math.dart b/sdk/lib/math/math.dart
index 0c1f67f..93ec416 100644
--- a/sdk/lib/math/math.dart
+++ b/sdk/lib/math/math.dart
@@ -137,7 +137,35 @@
  * Returns [x] to the power of [exponent].
  *
  * If [x] is an [int] and [exponent] is a non-negative [int], the result is
- * an [int], otherwise the result it is a [double].
+ * an [int], otherwise both arguments are converted to doubles first, and the
+ * result is a [double].
+ *
+ * For integers, the power is always equal to the mathematical result of `x` to
+ * the power `exponent`, only limited by the available memory.
+ *
+ * For doubles, `pow(x, y)` handles edge cases as follows:
+ *
+ * - if `y` is zero (0.0 or -0.0), the result is always 1.0.
+ * - if `x` is 1.0, the result is always 1.0.
+ * - otherwise, if either `x` or `y` is NaN then the result is NaN.
+ * - if `x` is negative (but not -0.0) and `y` is a finite non-integer, the
+ *   result is NaN.
+ * - if `x` is Infinity and `y` is negative, the result is 0.0.
+ * - if `x` is Infinity and `y` is positive, the result is Infinity.
+ * - if `x` is 0.0 and `y` is negative, the result is Infinity.
+ * - if `x` is 0.0 and `y` is positive, the result is 0.0.
+ * - if `x` is -Infinity or -0.0 and `y` is an odd integer, then the result is
+ *   `-pow(-x ,y)`.
+ * - if `x` is -Infinity or -0.0 and `y` is not an odd integer, then the result
+ *   is the same as `pow(-x , y)`.
+ * - if `y` is Infinity and the absolute value of `x` is less than 1, the
+ *   result is 0.0.
+ * - if `y` is Infinity and `x` is -1, the result is 1.0.
+ * - if `y` is Infinity and the absolute value of `x` is greater than 1,
+ *   the result is Infinity.
+ * - if `y` is -Infinity, the result is `1/pow(x, Infinity)`.
+ *
+ * This corresponds to the `pow` function defined in the IEEE Standard 754-2008.
  *
  * Notice that an [int] result cannot overflow, but a [double] result might
  * be [double.INFINITY].
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index b0d39d9..c22d3c3 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -682,6 +682,18 @@
  */
 abstract class ClassMirror implements TypeMirror, ObjectMirror {
   /**
+   * Returns true if this mirror reflects a non-generic class or an instantiated
+   * generic class in the current isolate. Otherwise, returns false.
+   */
+  bool get hasReflectedType;
+
+  /**
+   * If [:hasReflectedType:] returns true, returns the corresponding [Type].
+   * Otherwise, an [UnsupportedError] is thrown.
+   */
+  Type get reflectedType;
+
+  /**
    * A mirror on the superclass on the reflectee.
    *
    * If this type is [:Object:] or a typedef, the superClass will be
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index ac40dc1..f5066ee1 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -622,7 +622,7 @@
 @DocsEditable()
 @DomName('SVGDescElement')
 @Unstable()
-class DescElement extends StyledElement native "SVGDescElement" {
+class DescElement extends SvgElement native "SVGDescElement" {
   // To suppress missing implicit constructor warnings.
   factory DescElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1085,7 +1085,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEBlendElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFEBlendElement" {
+class FEBlendElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEBlendElement" {
   // To suppress missing implicit constructor warnings.
   factory FEBlendElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1166,7 +1166,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEColorMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFEColorMatrixElement" {
+class FEColorMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEColorMatrixElement" {
   // To suppress missing implicit constructor warnings.
   factory FEColorMatrixElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1243,7 +1243,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEComponentTransferElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFEComponentTransferElement" {
+class FEComponentTransferElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEComponentTransferElement" {
   // To suppress missing implicit constructor warnings.
   factory FEComponentTransferElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1288,7 +1288,7 @@
 @DocsEditable()
 @DomName('SVGFECompositeElement')
 @Unstable()
-class FECompositeElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFECompositeElement" {
+class FECompositeElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFECompositeElement" {
   // To suppress missing implicit constructor warnings.
   factory FECompositeElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1382,7 +1382,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEConvolveMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFEConvolveMatrixElement" {
+class FEConvolveMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEConvolveMatrixElement" {
   // To suppress missing implicit constructor warnings.
   factory FEConvolveMatrixElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1491,7 +1491,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEDiffuseLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFEDiffuseLightingElement" {
+class FEDiffuseLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEDiffuseLightingElement" {
   // To suppress missing implicit constructor warnings.
   factory FEDiffuseLightingElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1556,7 +1556,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEDisplacementMapElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFEDisplacementMapElement" {
+class FEDisplacementMapElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEDisplacementMapElement" {
   // To suppress missing implicit constructor warnings.
   factory FEDisplacementMapElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1672,7 +1672,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEFloodElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFEFloodElement" {
+class FEFloodElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEFloodElement" {
   // To suppress missing implicit constructor warnings.
   factory FEFloodElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1809,7 +1809,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEGaussianBlurElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFEGaussianBlurElement" {
+class FEGaussianBlurElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEGaussianBlurElement" {
   // To suppress missing implicit constructor warnings.
   factory FEGaussianBlurElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1870,7 +1870,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEImageElement extends StyledElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired native "SVGFEImageElement" {
+class FEImageElement extends SvgElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired native "SVGFEImageElement" {
   // To suppress missing implicit constructor warnings.
   factory FEImageElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1931,7 +1931,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEMergeElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFEMergeElement" {
+class FEMergeElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEMergeElement" {
   // To suppress missing implicit constructor warnings.
   factory FEMergeElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2003,7 +2003,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEMorphologyElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFEMorphologyElement" {
+class FEMorphologyElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEMorphologyElement" {
   // To suppress missing implicit constructor warnings.
   factory FEMorphologyElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2073,7 +2073,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEOffsetElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFEOffsetElement" {
+class FEOffsetElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEOffsetElement" {
   // To suppress missing implicit constructor warnings.
   factory FEOffsetElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2165,7 +2165,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FESpecularLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFESpecularLightingElement" {
+class FESpecularLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFESpecularLightingElement" {
   // To suppress missing implicit constructor warnings.
   factory FESpecularLightingElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2281,7 +2281,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FETileElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFETileElement" {
+class FETileElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFETileElement" {
   // To suppress missing implicit constructor warnings.
   factory FETileElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2330,7 +2330,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FETurbulenceElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFETurbulenceElement" {
+class FETurbulenceElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFETurbulenceElement" {
   // To suppress missing implicit constructor warnings.
   factory FETurbulenceElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2423,7 +2423,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FilterElement extends StyledElement implements UriReference, ExternalResourcesRequired native "SVGFilterElement" {
+class FilterElement extends SvgElement implements UriReference, ExternalResourcesRequired native "SVGFilterElement" {
   // To suppress missing implicit constructor warnings.
   factory FilterElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2590,7 +2590,7 @@
 @DocsEditable()
 @DomName('SVGGraphicsElement')
 @Experimental() // untriaged
-class GraphicsElement extends StyledElement implements Tests native "SVGGraphicsElement" {
+class GraphicsElement extends SvgElement implements Tests native "SVGGraphicsElement" {
   // To suppress missing implicit constructor warnings.
   factory GraphicsElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2945,7 +2945,7 @@
 @DocsEditable()
 @DomName('SVGMarkerElement')
 @Unstable()
-class MarkerElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired native "SVGMarkerElement" {
+class MarkerElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired native "SVGMarkerElement" {
   // To suppress missing implicit constructor warnings.
   factory MarkerElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -3037,7 +3037,7 @@
 @DocsEditable()
 @DomName('SVGMaskElement')
 @Unstable()
-class MaskElement extends StyledElement implements ExternalResourcesRequired, Tests native "SVGMaskElement" {
+class MaskElement extends SvgElement implements ExternalResourcesRequired, Tests native "SVGMaskElement" {
   // To suppress missing implicit constructor warnings.
   factory MaskElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -4088,7 +4088,7 @@
 @DocsEditable()
 @DomName('SVGPatternElement')
 @Unstable()
-class PatternElement extends StyledElement implements FitToViewBox, UriReference, ExternalResourcesRequired, Tests native "SVGPatternElement" {
+class PatternElement extends SvgElement implements FitToViewBox, UriReference, ExternalResourcesRequired, Tests native "SVGPatternElement" {
   // To suppress missing implicit constructor warnings.
   factory PatternElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -4570,7 +4570,7 @@
 @DocsEditable()
 @DomName('SVGStopElement')
 @Unstable()
-class StopElement extends StyledElement native "SVGStopElement" {
+class StopElement extends SvgElement native "SVGStopElement" {
   // To suppress missing implicit constructor warnings.
   factory StopElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -4713,24 +4713,6 @@
 
 
 @DocsEditable()
-@DomName('SVGStyledElement')
-@Unstable()
-class StyledElement extends SvgElement native "SVGStyledElement" {
-  // To suppress missing implicit constructor warnings.
-  factory StyledElement._() { throw new UnsupportedError("Not supported"); }
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable()
 @DomName('SVGDocument')
 @Unstable()
 class SvgDocument extends Document native "SVGDocument" {
@@ -4857,17 +4839,16 @@
   factory SvgElement._() { throw new UnsupportedError("Not supported"); }
 
   // Shadowing definition.
-  String get id => JS("String", "#.id", this);
-
-  void set id(String value) {
-    JS("void", "#.id = #", this, value);
-  }
+  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
 
   @JSName('ownerSVGElement')
   @DomName('SVGElement.ownerSVGElement')
   @DocsEditable()
   final SvgSvgElement ownerSvgElement;
 
+  // Use implementation from Element.
+  // final CssStyleDeclaration style;
+
   @DomName('SVGElement.viewportElement')
   @DocsEditable()
   final SvgElement viewportElement;
@@ -5117,7 +5098,7 @@
 @DocsEditable()
 @DomName('SVGSymbolElement')
 @Unstable()
-class SymbolElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired native "SVGSymbolElement" {
+class SymbolElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired native "SVGSymbolElement" {
   // To suppress missing implicit constructor warnings.
   factory SymbolElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -5359,7 +5340,7 @@
 @DocsEditable()
 @DomName('SVGTitleElement')
 @Unstable()
-class TitleElement extends StyledElement native "SVGTitleElement" {
+class TitleElement extends SvgElement native "SVGTitleElement" {
   // To suppress missing implicit constructor warnings.
   factory TitleElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -5861,7 +5842,7 @@
 @DocsEditable()
 @DomName('SVGGradientElement')
 @Unstable()
-class _GradientElement extends StyledElement implements UriReference, ExternalResourcesRequired native "SVGGradientElement" {
+class _GradientElement extends SvgElement implements UriReference, ExternalResourcesRequired native "SVGGradientElement" {
   // To suppress missing implicit constructor warnings.
   factory _GradientElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -5999,7 +5980,7 @@
 @DocsEditable()
 @DomName('SVGFEDropShadowElement')
 @Experimental() // nonstandard
-abstract class _SVGFEDropShadowElement extends StyledElement implements FilterPrimitiveStandardAttributes native "SVGFEDropShadowElement" {
+abstract class _SVGFEDropShadowElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEDropShadowElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGFEDropShadowElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -6101,7 +6082,7 @@
 @DocsEditable()
 @DomName('SVGGlyphRefElement')
 @Unstable()
-abstract class _SVGGlyphRefElement extends StyledElement implements UriReference native "SVGGlyphRefElement" {
+abstract class _SVGGlyphRefElement extends SvgElement implements UriReference native "SVGGlyphRefElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGGlyphRefElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -6150,7 +6131,7 @@
 @DocsEditable()
 @DomName('SVGMissingGlyphElement')
 @Unstable()
-abstract class _SVGMissingGlyphElement extends StyledElement native "SVGMissingGlyphElement" {
+abstract class _SVGMissingGlyphElement extends SvgElement native "SVGMissingGlyphElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGMissingGlyphElement._() { throw new UnsupportedError("Not supported"); }
 }
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index 69dc8ab..1095161 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -711,7 +711,7 @@
 @DocsEditable()
 @DomName('SVGDescElement')
 @Unstable()
-class DescElement extends StyledElement {
+class DescElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory DescElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1199,7 +1199,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEBlendElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FEBlendElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FEBlendElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1281,7 +1281,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEColorMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FEColorMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FEColorMatrixElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1359,7 +1359,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEComponentTransferElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FEComponentTransferElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FEComponentTransferElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1405,7 +1405,7 @@
 @DocsEditable()
 @DomName('SVGFECompositeElement')
 @Unstable()
-class FECompositeElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FECompositeElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FECompositeElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1500,7 +1500,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEConvolveMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FEConvolveMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FEConvolveMatrixElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1610,7 +1610,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEDiffuseLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FEDiffuseLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FEDiffuseLightingElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1676,7 +1676,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEDisplacementMapElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FEDisplacementMapElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FEDisplacementMapElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1796,7 +1796,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEFloodElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FEFloodElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FEFloodElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -1946,7 +1946,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEGaussianBlurElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FEGaussianBlurElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FEGaussianBlurElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2008,7 +2008,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEImageElement extends StyledElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired {
+class FEImageElement extends SvgElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired {
   // To suppress missing implicit constructor warnings.
   factory FEImageElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2066,7 +2066,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEMergeElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FEMergeElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FEMergeElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2142,7 +2142,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEMorphologyElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FEMorphologyElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FEMorphologyElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2213,7 +2213,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FEOffsetElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FEOffsetElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FEOffsetElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2309,7 +2309,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FESpecularLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FESpecularLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FESpecularLightingElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2429,7 +2429,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FETileElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FETileElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FETileElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2479,7 +2479,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FETurbulenceElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+class FETurbulenceElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FETurbulenceElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2573,7 +2573,7 @@
 @SupportedBrowser(SupportedBrowser.IE, '10')
 @SupportedBrowser(SupportedBrowser.SAFARI)
 @Unstable()
-class FilterElement extends StyledElement implements UriReference, ExternalResourcesRequired {
+class FilterElement extends SvgElement implements UriReference, ExternalResourcesRequired {
   // To suppress missing implicit constructor warnings.
   factory FilterElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -2761,7 +2761,7 @@
 @DocsEditable()
 @DomName('SVGGraphicsElement')
 @Experimental() // untriaged
-class GraphicsElement extends StyledElement implements Tests {
+class GraphicsElement extends SvgElement implements Tests {
   // To suppress missing implicit constructor warnings.
   factory GraphicsElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -3136,7 +3136,7 @@
 @DocsEditable()
 @DomName('SVGMarkerElement')
 @Unstable()
-class MarkerElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired {
+class MarkerElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired {
   // To suppress missing implicit constructor warnings.
   factory MarkerElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -3227,7 +3227,7 @@
 @DocsEditable()
 @DomName('SVGMaskElement')
 @Unstable()
-class MaskElement extends StyledElement implements ExternalResourcesRequired, Tests {
+class MaskElement extends SvgElement implements ExternalResourcesRequired, Tests {
   // To suppress missing implicit constructor warnings.
   factory MaskElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -4594,7 +4594,7 @@
 @DocsEditable()
 @DomName('SVGPatternElement')
 @Unstable()
-class PatternElement extends StyledElement implements FitToViewBox, UriReference, ExternalResourcesRequired, Tests {
+class PatternElement extends SvgElement implements FitToViewBox, UriReference, ExternalResourcesRequired, Tests {
   // To suppress missing implicit constructor warnings.
   factory PatternElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -5130,7 +5130,7 @@
 @DocsEditable()
 @DomName('SVGStopElement')
 @Unstable()
-class StopElement extends StyledElement {
+class StopElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory StopElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -5294,29 +5294,6 @@
 
 
 @DocsEditable()
-@DomName('SVGStyledElement')
-@Unstable()
-class StyledElement extends SvgElement {
-  // To suppress missing implicit constructor warnings.
-  factory StyledElement._() { throw new UnsupportedError("Not supported"); }
-
-  @DomName('SVGStyledElement.className')
-  @DocsEditable()
-  AnimatedString get $dom_svgClassName native "SVGStyledElement_className_Getter";
-
-  @DomName('SVGStyledElement.style')
-  @DocsEditable()
-  CssStyleDeclaration get style native "SVGStyledElement_style_Getter";
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable()
 @DomName('SVGDocument')
 @Unstable()
 class SvgDocument extends Document {
@@ -5447,18 +5424,20 @@
   // To suppress missing implicit constructor warnings.
   factory SvgElement._() { throw new UnsupportedError("Not supported"); }
 
-  @DomName('SVGElement.id')
+  @DomName('SVGElement.className')
   @DocsEditable()
-  String get id native "SVGElement_id_Getter";
-
-  @DomName('SVGElement.id')
-  @DocsEditable()
-  void set id(String value) native "SVGElement_id_Setter";
+  @Experimental() // untriaged
+  AnimatedString get $dom_svgClassName native "SVGElement_className_Getter";
 
   @DomName('SVGElement.ownerSVGElement')
   @DocsEditable()
   SvgSvgElement get ownerSvgElement native "SVGElement_ownerSVGElement_Getter";
 
+  @DomName('SVGElement.style')
+  @DocsEditable()
+  @Experimental() // untriaged
+  CssStyleDeclaration get style native "SVGElement_style_Getter";
+
   @DomName('SVGElement.viewportElement')
   @DocsEditable()
   SvgElement get viewportElement native "SVGElement_viewportElement_Getter";
@@ -5723,7 +5702,7 @@
 @DocsEditable()
 @DomName('SVGSymbolElement')
 @Unstable()
-class SymbolElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired {
+class SymbolElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired {
   // To suppress missing implicit constructor warnings.
   factory SymbolElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -5986,7 +5965,7 @@
 @DocsEditable()
 @DomName('SVGTitleElement')
 @Unstable()
-class TitleElement extends StyledElement {
+class TitleElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory TitleElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -6524,7 +6503,7 @@
 @DocsEditable()
 @DomName('SVGGradientElement')
 @Unstable()
-class _GradientElement extends StyledElement implements UriReference, ExternalResourcesRequired {
+class _GradientElement extends SvgElement implements UriReference, ExternalResourcesRequired {
   // To suppress missing implicit constructor warnings.
   factory _GradientElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -6670,7 +6649,7 @@
 @DocsEditable()
 @DomName('SVGFEDropShadowElement')
 @Experimental() // nonstandard
-abstract class _SVGFEDropShadowElement extends StyledElement implements FilterPrimitiveStandardAttributes {
+abstract class _SVGFEDropShadowElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory _SVGFEDropShadowElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -6794,7 +6773,7 @@
 @DocsEditable()
 @DomName('SVGGlyphRefElement')
 @Unstable()
-abstract class _SVGGlyphRefElement extends StyledElement implements UriReference {
+abstract class _SVGGlyphRefElement extends SvgElement implements UriReference {
   // To suppress missing implicit constructor warnings.
   factory _SVGGlyphRefElement._() { throw new UnsupportedError("Not supported"); }
 
@@ -6846,7 +6825,7 @@
 @DocsEditable()
 @DomName('SVGMissingGlyphElement')
 @Unstable()
-abstract class _SVGMissingGlyphElement extends StyledElement {
+abstract class _SVGMissingGlyphElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory _SVGMissingGlyphElement._() { throw new UnsupportedError("Not supported"); }
 
diff --git a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
index a145ff2..c72a299 100644
--- a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
+++ b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
@@ -934,6 +934,16 @@
   /// Extracted w value.
   double get w => _storage[3];
 
+  /// Extract the sign bit from each lane return them in the first 4 bits.
+  int get signMask {
+    var view = new Uint32List.view(_storage.buffer);
+    var mx = (view[0] & 0x80000000) >> 31;
+    var my = (view[1] & 0x80000000) >> 31;
+    var mz = (view[2] & 0x80000000) >> 31;
+    var mw = (view[3] & 0x80000000) >> 31;
+    return mx | my << 1 | mz << 2 | mw << 3;
+  }
+
   /// Mask passed to [shuffle].
   static const int XXXX = 0x0;
   static const int XXXY = 0x40;
@@ -1192,7 +1202,6 @@
   static const int WWWZ = 0xBF;
   static const int WWWW = 0xFF;
 
-
   /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
   Float32x4 shuffle(int m) {
     if (m < 0 || m > 255) {
@@ -1396,6 +1405,24 @@
     return new Uint32x4(_x, _y, _z, _w);
   }
 
+  Uint32x4 operator+(Uint32x4 other) {
+    var r = new Uint32x4(0, 0, 0, 0);
+    r._storage[0] = (_storage[0] + other._storage[0]);
+    r._storage[1] = (_storage[1] + other._storage[1]);
+    r._storage[2] = (_storage[2] + other._storage[2]);
+    r._storage[3] = (_storage[3] + other._storage[3]);
+    return r;
+  }
+
+  Uint32x4 operator-(Uint32x4 other) {
+    var r = new Uint32x4(0, 0, 0, 0);
+    r._storage[0] = (_storage[0] - other._storage[0]);
+    r._storage[1] = (_storage[1] - other._storage[1]);
+    r._storage[2] = (_storage[2] - other._storage[2]);
+    r._storage[3] = (_storage[3] - other._storage[3]);
+    return r;
+  }
+
   /// Extract 32-bit mask from x lane.
   int get x => _storage[0];
   /// Extract 32-bit mask from y lane.
@@ -1405,6 +1432,15 @@
   /// Extract 32-bit mask from w lane.
   int get w => _storage[3];
 
+  /// Extract the top bit from each lane return them in the first 4 bits.
+  int get signMask {
+    int mx = (_storage[0] & 0x80000000) >> 31;
+    int my = (_storage[1] & 0x80000000) >> 31;
+    int mz = (_storage[2] & 0x80000000) >> 31;
+    int mw = (_storage[3] & 0x80000000) >> 31;
+    return mx | my << 1 | mz << 2 | mw << 3;
+  }
+
   /// Returns a new [Uint32x4] copied from [this] with a new x value.
   Uint32x4 withX(int x) {
     int _x = x;
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index 7184e47..71d6a8d 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -876,6 +876,9 @@
   /// Extracted w value.
   double get w;
 
+  /// Extract the sign bits from each lane return them in the first 4 bits.
+  int get signMask;
+
   /// Mask passed to [shuffle].
   static const int XXXX = 0x0;
   static const int XXXY = 0x40;
@@ -1201,6 +1204,10 @@
   Uint32x4 operator&(Uint32x4 other);
   /// The bit-wise xor operator.
   Uint32x4 operator^(Uint32x4 other);
+  /// Addition operator.
+  Uint32x4 operator+(Uint32x4 other);
+  /// Subtraction operator.
+  Uint32x4 operator-(Uint32x4 other);
 
   /// Extract 32-bit mask from x lane.
   int get x;
@@ -1211,6 +1218,9 @@
   /// Extract 32-bit mask from w lane.
   int get w;
 
+  /// Extract the top bit from each lane return them in the first 4 bits.
+  int get signMask;
+
   /// Returns a new [Uint32x4] copied from [this] with a new x value.
   Uint32x4 withX(int x);
   /// Returns a new [Uint32x4] copied from [this] with a new y value.
diff --git a/tests/benchmark_smoke/benchmark_smoke.status b/tests/benchmark_smoke/benchmark_smoke.status
index 0ccd5ca..ed281f3 100644
--- a/tests/benchmark_smoke/benchmark_smoke.status
+++ b/tests/benchmark_smoke/benchmark_smoke.status
@@ -2,12 +2,6 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $runtime == ie9 && ($system == linux || $system == macos) ]
-*: Skip
-
-[ $runtime == safari && ($system == linux || $system == windows) ]
-*: Skip
-
 [ $runtime == vm ]
 *: Skip
 
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
index cb4f01a..4d9ef03 100644
--- a/tests/co19/co19-analyzer.status
+++ b/tests/co19/co19-analyzer.status
@@ -3,7 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dartanalyzer ]
-
 # not clear: g([var foo = foo + 10]) is parameter 'foo' in the scope of its own initialzer?
 Language/06_Functions/2_Formal_Parameters_A02_t02: fail
 
@@ -16,13 +15,20 @@
 # TBF: _f is private, so does not collide
 Language/07_Classes/1_Instance_Methods_A05_t08: fail
 
+# TBD: should we check that argument for dynamic parameter of constant constructor is not compatible with operation that is performed with it?
+Language/12_Expressions/01_Constants_A16_t03: fail
+
+# TBD: should we report _error_ when constant creation uses arguments with types incompatible with parameters?
+Language/12_Expressions/12_Instance_Creation/2_Const_A09_t02: fail
+Language/12_Expressions/12_Instance_Creation/2_Const_A09_t03: fail
+
+# TBF: infinite look: class A {const A();final m = const A();}
+Language/12_Expressions/01_Constants_A17_t03: fail
+
 # co19 issue #380, Strings class has been removed
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: fail, OK
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: fail, OK
 
-# co19 issue #389, ceil, floor, truncate and round return integers
-LibTest/core/int/operator_division_A01_t01: fail, OK
-
 # co19 issue #397, List.addLast removed
 LibTest/core/Iterable/where_A01_t07: fail, OK
 
@@ -123,69 +129,106 @@
 Language/07_Classes/4_Abstract_Instance_Members_A04_t05: fail, OK
 Language/07_Classes/4_Abstract_Instance_Members_A04_t06: fail, OK
 
+# co19 issue #513, rules for finals were loosened, contradiction in spec was fixed
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A21_t01: fail, OK
+
+# co19 issue #514, it is still an error to have both a n initializing formal and an initializer in the constructor's initializer list
+Language/05_Variables/05_Variables_A05_t03: fail, OK
+
+# co19 issue #515, it is a compile-time error if there is more than one entity with the same name declared in the same scope
+Language/07_Classes/3_Setters_A08_t01: fail, OK
+Language/07_Classes/3_Setters_A08_t02: fail, OK
+Language/07_Classes/3_Setters_A08_t03: fail, OK
+Language/07_Classes/3_Setters_A08_t04: fail, OK
+
+# co19 issue #516, it is a compile-time error if a class has both a getter and a method with the same name.
+Language/07_Classes/3_Setters_A08_t05: fail, OK
+
+# co19 issue #438, Static variables are initialized lazily, need not be constants
+Language/12_Expressions/01_Constants_A16_t01: fail, OK
+Language/12_Expressions/01_Constants_A16_t02: fail, OK
+
+# co19 issue #517, +5 is not a valid expression
+Language/12_Expressions/01_Constants_A01_t01: fail, OK
+Language/12_Expressions/03_Numbers_A01_t01: fail, OK
+Language/12_Expressions/03_Numbers_A01_t02: fail, OK
+Language/12_Expressions/03_Numbers_A01_t03: fail, OK
+Language/12_Expressions/03_Numbers_A01_t04: fail, OK
+Language/12_Expressions/03_Numbers_A01_t08: fail, OK
+Language/12_Expressions/03_Numbers_A01_t10: fail, OK
+Language/13_Statements/02_Expression_Statements_A01_t06: fail, OK
+
+# co19 issue #518, It is a compile-time error if evaluation of a compile-time constant would raise an exception
+Language/12_Expressions/01_Constants_A11_t01: fail, OK
+Language/12_Expressions/01_Constants_A12_t01: fail, OK
+Language/12_Expressions/01_Constants_A13_t06: fail, OK
+
+# co19 issue #397, List.addLast being removed
+Language/12_Expressions/06_Lists_A06_t01: fail, OK
+
+# co19 issue #519, ++5 is not assignable
+Language/12_Expressions/07_Maps_A01_t01: fail, OK
+
+# co19 issue #420, "throw" requires expression, "rethrow" should be used instead
+Language/12_Expressions/08_Throw_A05_t01: fail, OK
+Language/12_Expressions/08_Throw_A05_t02: fail, OK
+Language/12_Expressions/08_Throw_A05_t03: fail, OK
+
+# co19 issue #454 (wrongly closed)
+Language/12_Expressions/12_Instance_Creation/1_New_A01_t04: fail, OK
+
+# co19 issue #521, attempt to create instance of not a class
+Language/12_Expressions/12_Instance_Creation/1_New_A02_t01: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A02_t02: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A02_t03: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A02_t05: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A02_t07: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t03: fail, OK
+
+# co19 issue #523, new malbound type
+Language/12_Expressions/12_Instance_Creation/1_New_A05_t01: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A05_t02: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A05_t03: fail, OK
+
+# co19 issue #524, new abstract class
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t01: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t02: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: fail, OK
+
+# co19 issue #526, use undefined constructor
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t04: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t05: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t06: fail, OK
+
+# co19 issue #527, not enough or extra positional parameters; no such named paramater
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t07: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t08: fail, OK
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t09: fail, OK
+
+# co19 issue #528, Const: wrong number of type arguments
+Language/12_Expressions/12_Instance_Creation_A01_t02: fail, OK
+Language/12_Expressions/12_Instance_Creation_A01_t05: fail, OK
+Language/12_Expressions/12_Instance_Creation_A01_t06: fail, OK
+
+# co19 issue #529, const instance creation with invalid type arguments
+Language/12_Expressions/12_Instance_Creation_A01_t08: fail, OK
+
+# co19 issue #388 (wrongly closed), StringBuffer methods changed
+Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t05: fail, OK
+Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: fail, OK
+
+# co19 issue #433 (wrongly closed), missing @static-warning annotation
+Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t01: fail, OK
+Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t07: fail, OK
+
+# co19 issue #530, garbage
+Language/12_Expressions/32_Type_Test_A04_t02: fail, OK
+
+# co19 issue #531, void f(void f()) {f();} is error. Gilad: The formal parameter conflicts with the name of the function.
+Language/13_Statements/04_Local_Function_Declaration_A01_t01: fail, OK
+
+
 # co19-roll r546 (11.08.2013) caused these failures
-Language/05_Variables/05_Variables_A05_t01: fail # co19-roll r546: Please triage this failure
-Language/05_Variables/05_Variables_A05_t02: fail # co19-roll r546: Please triage this failure
-Language/05_Variables/05_Variables_A05_t03: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/3_Setters_A08_t01: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/3_Setters_A08_t02: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/3_Setters_A08_t03: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/3_Setters_A08_t04: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/3_Setters_A08_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A04_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A04_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A01_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A11_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A12_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A13_t06: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A16_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A16_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A16_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A17_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/03_Numbers_A01_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/03_Numbers_A01_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/03_Numbers_A01_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/03_Numbers_A01_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/03_Numbers_A01_t08: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/03_Numbers_A01_t10: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/06_Lists_A06_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A01_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/08_Throw_A05_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/08_Throw_A05_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/08_Throw_A05_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A01_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A02_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A02_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A02_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A02_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A02_t07: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A05_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A05_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A05_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t06: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t07: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t08: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t09: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/2_Const_A09_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/2_Const_A09_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation_A01_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation_A01_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation_A01_t06: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation_A01_t08: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/2_Cascaded_Invocation_A01_t19: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A03_t07: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/32_Type_Test_A04_t02: fail # co19-roll r546: Please triage this failure
-Language/13_Statements/02_Expression_Statements_A01_t06: fail # co19-roll r546: Please triage this failure
-Language/13_Statements/04_Local_Function_Declaration_A01_t01: fail # co19-roll r546: Please triage this failure
 Language/13_Statements/11_Return_A07_t01: fail # co19-roll r546: Please triage this failure
 Language/13_Statements/11_Try_A02_t03: fail # co19-roll r546: Please triage this failure
 Language/13_Statements/11_Try_A03_t03: fail # co19-roll r546: Please triage this failure
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
new file mode 100644
index 0000000..97bece2
--- /dev/null
+++ b/tests/co19/co19-co19.status
@@ -0,0 +1,135 @@
+# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# This file contains the tests that have been identified as broken and have been filed
+# on the co19 issue tracker.
+# In order to qualify here these tests need to fail both on the VM and dart2js.
+
+### GENERAL FAILURES ###
+
+[ $runtime == vm || $compiler == dart2js ]
+Language/07_Classes/6_Constructors_A02_t01: SKIP # co19 issue 415.
+Language/16_Reference/1_Lexical_Rules/2_Comments_A04_t03: FAIL, OK # co19 issue 505
+Language/15_Types/1_Static_Types_A03_t01: FAIL, OK # co19 issue 506
+Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t01: FAIL, OK # co19 issue 426
+
+LibTest/math/acos_A01_t01: PASS, FAIL, OK # co19 issue 44
+LibTest/math/asin_A01_t01: PASS, FAIL, OK # co19 issue 44
+LibTest/math/atan_A01_t01: PASS, FAIL, OK # co19 issue 44
+LibTest/math/cos_A01_t01: PASS, FAIL, OK # co19 issue 44
+LibTest/math/exp_A01_t01: PASS, FAIL, OK # co19 issue 44
+LibTest/math/max_A01_t03: FAIL, OK # co19 issue 467
+LibTest/math/min_A01_t03: FAIL, OK # co19 issue 467
+LibTest/math/pow_A01_t01: FAIL, OK # co19 issue 44
+LibTest/math/pow_A11_t01: FAIL, OK # co19 issue 512
+LibTest/math/pow_A13_t01: FAIL, OK # co19 issue 507
+LibTest/math/sin_A01_t01: PASS, FAIL, OK # co19 issue 44
+LibTest/math/tan_A01_t01: PASS, FAIL, OK  # co19 issue 44
+
+LibTest/collection/Queue/iterator_current_A01_t02: FAIL, OK # co19 issue 475
+LibTest/collection/Queue/iterator_moveNext_A01_t02: FAIL, OK # co19 issue 475
+
+LibTest/core/double/ceil_A01_t03: FAIL, OK # co19 issue 389
+LibTest/core/double/ceil_A01_t04: FAIL, OK # co19 issue 389
+LibTest/core/double/floor_A01_t03: FAIL, OK # co19 issue 389
+LibTest/core/double/floor_A01_t04: FAIL, OK # co19 issue 389
+LibTest/core/double/round_A01_t02: FAIL, OK # co19 issue 389
+LibTest/core/double/round_A01_t04: FAIL, OK # co19 issue 389
+LibTest/core/double/parse_A02_t01: FAIL, OK # co19 issue 418
+LibTest/core/double/truncate_A01_t03: FAIL, OK # co19 issue 389
+LibTest/core/double/truncate_A01_t04: FAIL, OK # co19 issue 389
+
+LibTest/core/int/toStringAsExponential_A02_t01: FAIL, OK # co19 issue 477
+LibTest/core/Iterable/any_A01_t04: FAIL, OK # co19 issue 508.
+LibTest/core/List/skip_A03_t01: FAIL, OK # co19 issue 502
+LibTest/core/List/take_A02_t01: FAIL, OK # co19 issue 502
+LibTest/core/Match/pattern_A01_t01: FAIL, OK # co19 Issue 400, 422
+LibTest/core/RegExp/allMatches_A01_t01: FAIL, OK # co19 Issue 400, 422
+
+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.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
+LibTest/core/DateTime/isAtSameMomentAs_A01_t01: FAIL, OK # co19 issue 503
+LibTest/core/DateTime/year_A01_t01: FAIL, OK # co19 issue 504
+LibTest/core/double/parse_A01_t01: FAIL, OK # co19 issue 503
+
+LibTest/isolate/SendPort/send_A02_t02: SKIP # co19 issue 493
+LibTest/isolate/SendPort/send_A02_t03: SKIP # co19 issue 495
+
+Utils/tests/Expect/listEquals_A02_t01: FAIL, OK # co19 issue 499
+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 # co19 issue 540
+LibTest/isolate_api/streamSpawnFunction_A02_t03: Pass, Fail # co19 issue 540
+
+### CHECKED MODE FAILURES ###
+
+[ ($runtime == vm || $compiler == dart2js) && $checked]
+Language/13_Statements/09_Switch_A05_t01: FAIL, OK  # co19 issue 498
+Language/14_Libraries_and_Scripts/1_Imports_A03_t26: FAIL, OK  # co19 issue 498
+Language/15_Types/1_Static_Types_A03_t03: FAIL, OK  # co19 issue 498
+Language/15_Types/1_Static_Types_A03_t04: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/asBroadcastStream_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/contains_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/contains_A02_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/distinct_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/drain_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/firstWhere_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/firstWhere_A02_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/first_A03_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/fold_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/fold_A01_t02: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/forEach_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/forEach_A02_t02: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/handleError_A02_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/isBroadcast_A01_t02: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/lastWhere_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/lastWhere_A02_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/listen_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/listen_A02_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/listen_A03_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/map_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/reduce_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/reduce_A01_t02: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/singleWhere_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/skip_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/take_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/take_A01_t02: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/toList_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/toSet_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/transform_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/where_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/EventTransformStream/where_A01_t02: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/drain_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/firstWhere_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/firstWhere_A02_t01: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/fold_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/fold_A01_t02: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/lastWhere_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/lastWhere_A02_t01: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/reduce_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/reduce_A01_t02: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/singleWhere_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/take_A01_t02: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/transform_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/where_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/async/Stream/where_A01_t02: FAIL, OK  # co19 issue 498
+LibTest/async/StreamEventTransformer/bind_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/core/DateTime/compareTo_A02_t01: FAIL, OK  # co19 issue 498
+LibTest/core/List/join_A01_t01: FAIL, OK  # co19 issue 498
+LibTest/core/List/removeAt_A02_t01: FAIL, OK  # co19 issue 498
+LibTest/core/TypeError/column_A01_t01: FAIL, OK # co19 issue 510
+LibTest/core/TypeError/dstName_A01_t01: FAIL, OK # co19 issue 510
+LibTest/core/TypeError/dstType_A01_t01: FAIL, OK # co19 issue 510
+LibTest/core/TypeError/failedAssertion_A01_t01: FAIL, OK # co19 issue 510
+LibTest/core/TypeError/line_A01_t01: FAIL, OK # co19 issue 510
+LibTest/core/TypeError/srcType_A01_t01: FAIL, OK # co19 issue 510
+LibTest/core/TypeError/url_A01_t01: FAIL, OK # co19 issue 510
+LibTest/isolate/IsolateStream/last_A01_t01: FAIL, OK # co19 issue 498
+LibTest/isolate/IsolateStream/length_A01_t01: FAIL, OK # co19 issue 498
+LibTest/isolate/IsolateStream/single_A01_t01: FAIL, OK # co19 issue 498
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 13a1129..a7ed9ce 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -3,6 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2dart ]
+LibTest/async/Stream/Stream.periodic_A01_t01: Pass, Fail # Issue 12562.
 
 LibTest/math/max_A01_t03: Fail # co19 issue 467
 LibTest/math/min_A01_t03: Fail # co19 issue 467
@@ -132,6 +133,7 @@
 LibTest/math/pow_A01_t01: Fail # Inherited from VM.
 LibTest/math/pow_A11_t01: Fail # Inherited from VM.
 LibTest/math/pow_A13_t01: Fail # Inherited from VM.
+LibTest/math/pow_A18_t01: Fail # Inherited from VM.
 LibTest/math/sin_A01_t01: Fail # Inherited from VM.
 LibTest/math/tan_A01_t01: Fail # Issue co19 - 44
 
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 1cbc686..e373794 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -2,7 +2,7 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $compiler == dart2js && ($runtime == d8 || $runtime == drt) ]
+[ $compiler == dart2js && $runtime == drt ]
 LibTest/core/List/sort_A01_t02: Pass, Fail # v8 bug: Issue 12293
 LibTest/core/List/sort_A01_t03: Pass, Fail # v8 bug: Issue 12293
 LibTest/core/Map/Map_class_A01_t04: Pass, Fail # v8 bug: Issue 12293
@@ -13,12 +13,12 @@
 
 [ $compiler == dart2js && $checked && $runtime == ie9 ]
 LibTest/core/Map/Map_class_A01_t04: Slow, Pass
+LibTest/isolate/isolate_api/spawnUri_A02_t03: Pass, Fail # Issue 8920
+
 
 # Crashes first, please. Then untriaged bugs. There is a section below
 # for co19 bugs.
 [ $compiler == dart2js ]
-LibTest/math/max_A01_t03: Fail # co19 issue 467
-LibTest/math/min_A01_t03: Fail # co19 issue 467
 
 Language/03_Overview/1_Scoping_A02_t05: Fail # TODO(ahe): Please triage this failure.
 Language/03_Overview/1_Scoping_A02_t06: Fail # TODO(ahe): Please triage this failure.
@@ -32,16 +32,9 @@
 Language/07_Classes/1_Instance_Methods_A06_t02: Fail # TODO(ahe): Please triage this failure.
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: Fail # TODO(ahe): Please triage this failure.
 Language/07_Classes/6_Constructors/2_Factories_A07_t01: Fail # TODO(ahe): Please triage this failure.
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/collection/Queue/iterator_current_A01_t02: Fail # co19 issue 475
-LibTest/collection/Queue/iterator_moveNext_A01_t02: Fail # co19 issue 475
 LibTest/core/List/List_A03_t01: Fail # TODO(kasperl): Please triage this failure.
 LibTest/core/double/INFINITY_A01_t04: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/double/NEGATIVE_INFINITY_A01_t04: Fail # TODO(ahe): Please triage this failure.
-LibTest/core/int/toStringAsExponential_A02_t01: Fail # co19 issue 477.
-LibTest/math/pow_A01_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/math/pow_A11_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/math/pow_A13_t01: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/List/sort_A01_t04: Pass, Slow # http://dartbug.com/11846
 
 
@@ -58,10 +51,6 @@
 LibTest/isolate/isolate_api/spawnUri_A02_t03: Fail, Pass # TODO(ahe): Please triage this failure.
 
 
-[ $compiler == dart2js && $runtime == jsshell && $system == macos ]
-LibTest/math/cos_A01_t01: Fail # TODO(ahe): Please triage this failure.
-
-
 [ $compiler == dart2js ]
 
 LibTest/isolate/ReceivePort/receive_A01_t02: Fail # Issue 6750
@@ -87,14 +76,11 @@
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Issue: 8920
 LibTest/core/String/contains_A01_t02: Fail # Issue: 8920
 LibTest/isolate/ReceivePort/toSendPort_A01_t02: Pass, Fail # Issue: 8920
-
-
-# These tests are passing with 'runtime == ie9' but are either skipped or fail
-# on other configurations
-[ $compiler == dart2js && ($runtime == ie10 || $runtime == ff || $runtime == chrome || $runtime == chromeOnAndroid || $runtime == drt || $runtime == safari || $runtime == opera || $runtime == d8 || $runtime == jsshell) ]
-LibTest/math/exp_A01_t01: Fail, OK # co19 issue 44
-LibTest/math/sin_A01_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/math/tan_A01_t01: Fail # TODO(ahe): Please triage this failure.
+LibTest/isolate/ReceivePort/toSendPort_A01_t01: Pass, Fail # Issue: 8920
+LibTest/core/DateTime/timeZoneName_A01_t01: Fail # Issue: 8920
+LibTest/async/Stream/listen_A04_t01: Pass, Timeout # Issue: 8920
+LibTest/async/Completer/completeError_A02_t01: Pass, Fail # Issue 8920
+LibTest/async/DeferredLibrary/DeferredLibrary_A01_t01: Pass, Timeout # Issue 8920
 
 [ $compiler == dart2js && $runtime == jsshell ]
 LibTest/core/Map/Map_class_A01_t04: Pass, Slow # Issue 8096
@@ -102,19 +88,10 @@
 LibTest/core/int/operator_truncating_division_A01_t01: Fail # TODO(ngeoaffray): Please triage these failure.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # TODO(ngeoaffray): Please triage these failure.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: Fail # TODO(ngeoaffray): Please triage these failure.
-LibTest/math/acos_A01_t01: Fail # TODO(ngeoaffray): Please triage these failure.
-LibTest/math/asin_A01_t01: Fail # TODO(ngeoaffray): Please triage these failure.
 
 [ $compiler == dart2js && $checked ]
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A17_t03: Fail # TODO(ahe): Please triage this failure.
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A17_t04: Fail # TODO(ahe): Please triage this failure.
-LibTest/core/TypeError/column_A01_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/core/TypeError/dstName_A01_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/core/TypeError/dstType_A01_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/core/TypeError/failedAssertion_A01_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/core/TypeError/line_A01_t01: Fail # co19 issue 479
-LibTest/core/TypeError/srcType_A01_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/core/TypeError/url_A01_t01: Fail # TODO(ahe): Please triage this failure.
 
 
 [ $compiler == dart2js ]
@@ -130,9 +107,7 @@
 Language/07_Classes/1_Instance_Methods_A02_t05: Fail, OK # These tests need to be updated for new optional parameter syntax and semantics, co19 issue 258:
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A13_t01: Fail, OK # These tests need to be updated for new optional parameter syntax and semantics, co19 issue 258:
 
-LibTest/isolate/SendPort/send_A02_t02: Fail, OK # co19 issue 293
-LibTest/isolate/SendPort/send_A02_t03: Fail, OK # co19 issue 293
-LibTest/isolate/SendPort/send_A02_t04: Fail, OK # co19 issue 293
+LibTest/isolate/SendPort/send_A02_t04: Fail, Pass, OK # co19 issue 293 Passes on IE
 
 LibTest/core/RegExp/firstMatch_A01_t01: Fail, OK # co19 issue 294
 LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A04_t01: Fail, OK # co19 issue 294
@@ -148,8 +123,6 @@
 Language/06_Functions/2_Formal_Parameters_A03_t06: Fail # TODO(ahe): Enforce optional parameter semantics.
 
 LibTest/isolate/SendPort/send_A02_t01: Fail # Compile-time error: error: not a compile-time constant
-LibTest/isolate/SendPort/send_A02_t02: Fail # Compile-time error: error: not a compile-time constant
-LibTest/isolate/SendPort/send_A02_t03: Fail # Compile-time error: error: not a compile-time constant
 
 LibTest/isolate/isolate_api/spawnUri_A02_t01: Fail # Runtime error: Expect.throws() fails
 LibTest/isolate/isolate_api/spawnUri_A01_t01: Fail # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
@@ -195,24 +168,8 @@
 
 Language/03_Overview/2_Privacy_A01_t11: Pass, OK # co19 issue 316
 
-LibTest/core/double/ceil_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
-LibTest/core/double/ceil_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
-LibTest/core/double/floor_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
-LibTest/core/double/floor_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
-LibTest/core/double/round_A01_t02: Fail # truncate/ceil/floor/round returns ints, issue 389
-LibTest/core/double/round_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
-LibTest/core/double/truncate_A01_t03: Fail # truncate/ceil/floor/round returns ints, issue 389
-LibTest/core/double/truncate_A01_t04: Fail # truncate/ceil/floor/round returns ints, issue 389
-
 LibTest/core/Iterable/where_A01_t07: Fail # Issue 397
 
-LibTest/core/Iterable/any_A01_t04: Fail # setRange now takes end-argument. Issue 402
-
-LibTest/core/double/parse_A02_t01: Fail # Issue 418
-
-LibTest/core/Match/pattern_A01_t01: Fail # co19 Issue 400, 422
-LibTest/core/RegExp/allMatches_A01_t01: Fail # co19 Issue 400, 422
-
 
 LibTest/core/String/indexOf_A01_t02: Fail # Issue 427
 LibTest/core/String/lastIndexOf_A01_t02: Fail # Issue 427
@@ -241,10 +198,9 @@
 LibTest/core/int/toRadixString_A01_t01: Fail, OK # Bad test: uses Expect.fail, Expect.throws, assumes case of result, and uses unsupported radixes.
 LibTest/core/String/contains_A01_t02: Fail, OK # co19 issue 105.
 
-[ $compiler == dart2js && $system == macos ]
-LibTest/math/acos_A01_t01: Fail, OK # co19 issue 44
-LibTest/math/asin_A01_t01: Fail, OK # co19 issue 44
-LibTest/math/atan_A01_t01: Fail, OK # co19 issue 44
+[ $compiler == dart2js && $runtime == ie9 ]
+LibTest/math/cos_A01_t01: Fail # co19 issue 44
+LibTest/async/EventTransformStream/listen_A04_t01: Pass, Timeout # Issue 12595
 
 #
 # The following tests are failing. Please add the error message
@@ -301,7 +257,6 @@
 Language/07_Classes/4_Abstract_Instance_Members_A04_t01: Fail # Checks that a compile-time error is produced when the overriding abstract method has fewer named parameters than the instance method being overridden (2 vs 3) and neither  have any required parameters.
 Language/07_Classes/4_Abstract_Instance_Members_A04_t05: Fail # Checks that a compile-time error is produced when the overriding non-abstract  instance method has the same set of named parameters as the abstract method being overriden,  but in a different order.
 Language/07_Classes/4_Abstract_Instance_Members_A04_t06: Fail # Checks that a compile-time error is produced when the overriding non-abstract  instance method has almost the same set of named parameters as the abstract method being overriden,  except for one that has a different name.
-Language/07_Classes/6_Constructors_A02_t01: Fail # Checks that a compile-error is produced when a named constructor definition does not begin with the name of its class.
 
 #
 # Unexpected compile-time errors.
@@ -453,7 +408,6 @@
 Language/14_Libraries_and_Scripts/5_URIs_A01_t21: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail # co19-roll r546: Please triage this failure
-Language/15_Types/1_Static_Types_A03_t01: fail # co19-roll r546: Please triage this failure
 Language/15_Types/3_Type_Declarations/1_Typedef_A06_t01: fail # co19-roll r546: Please triage this failure
 Language/15_Types/3_Type_Declarations/1_Typedef_A06_t02: fail # co19-roll r546: Please triage this failure
 Language/15_Types/3_Type_Declarations/1_Typedef_A06_t03: fail # co19-roll r546: Please triage this failure
@@ -468,21 +422,12 @@
 Language/15_Types/4_Interface_Types_A11_t04: fail # co19-roll r546: Please triage this failure
 Language/15_Types/4_Interface_Types_A12_t10: fail # co19-roll r546: Please triage this failure
 Language/16_Reference/1_Lexical_Rules/1_Reserved_Words_A40_t04: fail # co19-roll r546: Please triage this failure
-Language/16_Reference/1_Lexical_Rules/2_Comments_A04_t03: fail # co19-roll r546: Please triage this failure
 Language/16_Reference/1_Lexical_Rules_A02_t06: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/Stream.periodic_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/Stream.periodic_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Timer/run_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Timer/Timer.periodic_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/core/DateTime/DateTime_A01_t03: fail # co19-roll r546: Please triage this failure
-LibTest/core/DateTime/isAtSameMomentAs_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/core/DateTime/parse_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/DateTime/year_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/core/double/parse_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/core/Duration/operator_div_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/core/List/List_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/skip_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/take_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/isolate_api/spawnFunction_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/isolate_api/spawnFunction_A03_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/isolate_api/spawnFunction_A04_t01: fail # co19-roll r546: Please triage this failure
@@ -503,9 +448,6 @@
 LibTest/isolate/IsolateStream/contains_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/SendPort/send_A01_t01: fail # co19-roll r546: Please triage this failure
 Utils/tests/Expect/identical_A01_t01: fail # co19-roll r546: Please triage this failure
-Utils/tests/Expect/listEquals_A02_t01: fail # co19-roll r546: Please triage this failure
-Utils/tests/Expect/listEquals_A03_t01: fail # co19-roll r546: Please triage this failure
-Utils/tests/Expect/setEquals_A02_t01: fail # co19-roll r546: Please triage this failure
 
 # co19-roll r546 (11.08.2013) caused these failures
 [ $compiler == dart2js && $checked ]
@@ -524,71 +466,14 @@
 Language/12_Expressions/20_Logical_Boolean_Expressions_A03_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/27_Unary_Expressions_A02_t03: fail # co19-roll r546: Please triage this failure
 Language/13_Statements/06_For/1_For_Loop_A01_t08: fail # co19-roll r546: Please triage this failure
-Language/13_Statements/09_Switch_A05_t01: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t26: fail # co19-roll r546: Please triage this failure
-Language/15_Types/1_Static_Types_A03_t03: fail # co19-roll r546: Please triage this failure
-Language/15_Types/1_Static_Types_A03_t04: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/asBroadcastStream_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/contains_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/contains_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/distinct_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/drain_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/firstWhere_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/firstWhere_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/first_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/fold_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/fold_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/forEach_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/forEach_A02_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/handleError_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/isBroadcast_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/lastWhere_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/lastWhere_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/listen_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/listen_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/listen_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/map_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/reduce_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/reduce_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/singleWhere_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/skip_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/take_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/take_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/toList_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/toSet_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/transform_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/where_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/where_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/drain_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/firstWhere_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/firstWhere_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/fold_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/fold_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/lastWhere_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/lastWhere_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/reduce_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/reduce_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/singleWhere_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/take_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/transform_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/where_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/where_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/StreamEventTransformer/bind_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/DateTime/compareTo_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/core/List/getRange_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/join_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/removeAt_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/core/Set/intersection_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateStream/last_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateStream/length_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateStream/single_A01_t01: fail # co19-roll r546: Please triage this failure
 
 
 # Could this be dart issue 7728?
 # co19-roll r546 (11.08.2013) caused these failures
 [ $compiler == dart2js && ($runtime == d8 || $runtime == jsshell) ]
 LibTest/async/Future/Future.delayed_A01_t01: Fail # co19-roll r546: Please triage this failure
-LibTest/async/Future/Future.delayed_A01_t02: Fail # co19-roll r546: Please triage this failure
 LibTest/async/Future/Future.delayed_A03_t01: fail # co19-roll r546: Please triage this failure
 LibTest/async/Stream/first_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/async/Stream/first_A02_t02: fail # co19-roll r546: Please triage this failure
@@ -598,4 +483,3 @@
 LibTest/async/Stream/Stream.periodic_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/async/Timer/cancel_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/async/Timer/Timer_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Timer/Timer.periodic_A01_t01: fail # co19-roll r546: Please triage this failure
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 96d4ddb..c52aec6 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -2,29 +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.
 
-[ $compiler == none]
-LibTest/math/max_A01_t03: Fail # co19 issue 467
-LibTest/math/min_A01_t03: Fail # co19 issue 467
-
 [ $runtime == vm && $system == windows ]
 LibTest/core/Stopwatch/elapsed_A01_t01: Pass, Fail # Issue 11382.
 LibTest/core/Stopwatch/elapsed_A01_t03: Pass, Fail # Issue 12383.
 
-[ $runtime == vm ]
-Language/07_Classes/6_Constructors_A02_t01: Skip # co19 issue 415.
-
 [ $compiler == none && $runtime == vm ]
 # The following tests fail because they contain number literals with a + prefix (co19 issue 428)
 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 # Dart issue 5743
-LibTest/collection/Queue/iterator_current_A01_t02: Fail # co19 issue 475
-LibTest/collection/Queue/iterator_moveNext_A01_t02: Fail # co19 issue 475
-LibTest/core/int/toStringAsExponential_A02_t01: Fail # co19 issue 477
-
-LibTest/core/Match/pattern_A01_t01: Fail # co19 issue 422
-LibTest/core/RegExp/allMatches_A01_t01: Fail # co19 issue 422
+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
@@ -33,35 +20,14 @@
 Language/07_Classes/4_Abstract_Instance_Members_A04_t05: Fail # Dart issue 978
 Language/07_Classes/4_Abstract_Instance_Members_A04_t06: Fail # Dart issue 978
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: Fail # Dart issue 6954
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t01: Fail # co19 issue 426
-LibTest/core/double/parse_A02_t01: Fail # co19 issue 418
-LibTest/math/pow_A01_t01: Fail # co19 issue 44
-LibTest/math/pow_A11_t01: Fail # Dart issue 449
-LibTest/math/pow_A13_t01: Fail # Dart issue 449
+LibTest/math/pow_A18_t01: Fail # co19 issue 507
 
 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
 
-LibTest/core/double/truncate_A01_t03: Fail # truncate/ceil/floor/round returns ints, co19 issue 389
-LibTest/core/double/truncate_A01_t04: Fail # truncate/ceil/floor/round returns ints, co19 issue 389
-LibTest/core/double/ceil_A01_t03: Fail # truncate/ceil/floor/round returns ints, co19 issue 389
-LibTest/core/double/ceil_A01_t04: Fail # truncate/ceil/floor/round returns ints, co19 issue 389
-LibTest/core/double/floor_A01_t03: Fail # truncate/ceil/floor/round returns ints, co19 issue 389
-LibTest/core/double/floor_A01_t04: Fail # truncate/ceil/floor/round returns ints, co19 issue 389
-LibTest/core/double/round_A01_t02: Fail # truncate/ceil/floor/round returns ints, co19 issue 389
-LibTest/core/double/round_A01_t04: Fail # truncate/ceil/floor/round returns ints, co19 issue 389
 
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # Issue 6085
 
-LibTest/async/Future/asStream_A01_t01: Fail # Future constructors have changed # co19 issue 408
-LibTest/async/Future/forEach_A03_t01: Fail # Future constructors have changed # co19 issue 408
-LibTest/async/Future/asStream_A01_t02: Fail # Future constructors have changed # co19 issue 408
-LibTest/async/Future/asStream_A02_t01: Fail # Future constructors have changed # co19 issue 408
-
-# Some of these tests are expected to fail for another reason. These are marked as Skip.
-Language/07_Classes/07_Classes_A02_t29: Skip # co19 issue 490
-Language/07_Classes/07_Classes_A02_t31: Skip # co19 issue 490
-
 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
@@ -77,14 +43,8 @@
 LibTest/core/double/toRadixString_A01_t01: Fail # co19 issue 491
 LibTest/core/int/toRadixString_A01_t01: Fail # co19 issue 492
 
-LibTest/math/sin_A01_t01: Pass, Fail, OK # co19 issue 44
-
-LibTest/isolate/SendPort/send_A02_t02: Skip # co19 issue 493
-
 LibTest/core/String/contains_A01_t02: Fail  # Issue 12508
 
-LibTest/isolate/SendPort/send_A02_t03: Skip # co19 issue 495
-
 LibTest/isolate/ReceivePort/receive_A01_t02: Fail # VM triage, check spec.
 LibTest/isolate/isolate_api/spawnUri_A02_t02: Fail # VM triage, check spec.
 LibTest/isolate/isolate_api/spawnUri_A02_t03: Fail # VM triage, check spec.
@@ -94,12 +54,9 @@
 
 LibTest/core/Iterable/where_A01_t07: Fail # Issue 397
 
-LibTest/core/List/getRange_A04_t01: Fail # getRange now takes end-argument and returns Iterable. Issue 399
 LibTest/core/Set/isSubsetOf_A01_t01: fail # Issue 400
 LibTest/core/Set/isSubsetOf_A01_t02: fail # Issue 400
 
-LibTest/core/Iterable/any_A01_t04: Fail # setRange now takes end-argument. Issue 402
-
 LibTest/core/String/indexOf_A01_t02: Fail # Issue 427
 LibTest/core/String/lastIndexOf_A01_t02: Fail # Issue 427
 
@@ -122,31 +79,20 @@
 Language/03_Overview/1_Scoping_A02_t28: Fail # Issue 463
 Language/03_Overview/2_Privacy_A01_t06: Fail # Issue 463
 
+LibTest/async/Timer/Timer.periodic_A02_t01: Pass, Fail # co19 issue 537
+
 # end [ $compiler == none && $runtime == vm ]
 
 
 [ $compiler == none && $runtime == vm && $checked ]
 LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issue 408
-LibTest/core/List/every_A01_t01: Fail # insertRange is removed. Issue 403
 LibTest/core/List/getRange_A01_t01: Fail # getRange now takes end-argument and returns Iterable. Issue 399
-LibTest/core/Set/intersection_A03_t01: Fail # co19 issue 480
-LibTest/core/TypeError/column_A01_t01: Fail # co19 issue 479
-LibTest/core/TypeError/dstName_A01_t01: Fail # co19 issue 479
-LibTest/core/TypeError/dstType_A01_t01: Fail # co19 issue 479
-LibTest/core/TypeError/failedAssertion_A01_t01: Fail # co19 issue 479
-LibTest/core/TypeError/line_A01_t01: Fail # co19 issue 479
-LibTest/core/TypeError/srcType_A01_t01: Fail # co19 issue 479
-LibTest/core/TypeError/url_A01_t01: Fail # co19 issue 479
-LibTest/core/int/operator_division_A01_t01: Fail # ~/ returns ints, issue 361
+LibTest/core/Set/intersection_A03_t01: Fail # co19 issue 510
+LibTest/core/int/operator_division_A01_t01: Fail # co19 issue 509
 
 LibTest/core/Set/intersection_A01_t01: Fail # issue 390
 LibTest/core/Set/intersection_A01_t02: Fail # issue 390
 LibTest/core/Set/intersection_A01_t03: Fail # issue 390
-LibTest/collection/Queue/Queue.from_A01_t01: Pass # Issue 400 and 463
-LibTest/collection/Queue/Queue.from_A01_t02: Pass # Issue 400 and 463
-LibTest/core/List/List.from_A01_t01: Pass # Issue 400 and 463
-LibTest/core/List/every_A01_t01: Pass # Issue 400 and 463
-LibTest/core/Match/str_A01_t01: Pass # Issue 400 and 463
 
 # Passing for the wrong reasons:
 LibTest/async/Completer/completeError_A03_t02: Pass # No AsyncError anymore. Issue 407 and 463
@@ -159,104 +105,80 @@
 [ $compiler == none && $runtime == vm && $mode == debug ]
 LibTest/isolate/isolate_api/spawnFunction_A02_t01: Crash
 Language/12_Expressions/00_Object_Identity/1_Object_Identity_A04_t02: Crash # co19-roll r546: Please triage this failure
-LibTest/async/Stream/Stream.periodic_A01_t01: Fail # co19-roll r546: Please triage this failure
 LibTest/async/Stream/Stream.periodic_A03_t01: Fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateStream/contains_A02_t01: Fail # co19-roll r546: Please triage this failure
 
-[ $compiler == none && $runtime == vm && $system == macos ]
-LibTest/math/exp_A01_t01: Fail, OK # Issue co19 - 44
-LibTest/math/acos_A01_t01: Fail, OK # Issue co19 - 44
-LibTest/math/asin_A01_t01: Fail, OK # Issue co19 - 44
-LibTest/math/atan_A01_t01: Fail, OK # Issue co19 - 44
-LibTest/math/tan_A01_t01: Fail, OK  # Issue co19 - 44
-
-[ $compiler == none && $runtime == vm && $system == linux ]
-LibTest/math/exp_A01_t01: Fail
-
-[ $compiler == none && $runtime == vm && $system != windows && $arch != x64 && $arch != arm ]
-LibTest/math/tan_A01_t01: Pass, Fail
-
 [ $compiler == none && $runtime == vm && $arch != x64 ]
 LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
 
-[ $compiler == none && $runtime == vm && $arch == simarm ]
-LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
-
 [ $compiler == none && $runtime == vm && $arch == mips ]
-LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
 LibTest/math/log_A01_t01: Fail
-LibTest/math/asin_A01_t01: Fail
-LibTest/math/acos_A01_t01: Fail
 LibTest/core/double/toInt_A01_t01: Fail
 
-[ $compiler == none && $runtime == vm && $arch == simmips ]
-LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
-
 # co19-roll r546 (11.08.2013) caused these failures
 [ $compiler == none && $runtime == vm ]
-Language/05_Variables/05_Variables_A05_t01: fail # co19-roll r546: Please triage this failure
-Language/05_Variables/05_Variables_A05_t02: fail # co19-roll r546: Please triage this failure
-Language/05_Variables/05_Variables_A05_t03: fail # co19-roll r546: Please triage this failure
-Language/05_Variables/05_Variables_A06_t01: fail # co19-roll r546: Please triage this failure
-Language/05_Variables/05_Variables_A06_t02: fail # co19-roll r546: Please triage this failure
-Language/05_Variables/05_Variables_A06_t03: fail # co19-roll r546: Please triage this failure
-Language/05_Variables/05_Variables_A06_t04: fail # co19-roll r546: Please triage this failure
-Language/05_Variables/05_Variables_A06_t05: fail # co19-roll r546: Please triage this failure
-Language/05_Variables/05_Variables_A06_t06: fail # co19-roll r546: Please triage this failure
-Language/05_Variables/05_Variables_A16_t02: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/07_Classes_A11_t02: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/07_Classes_A11_t04: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/3_Setters_A08_t01: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/3_Setters_A08_t02: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/3_Setters_A08_t03: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/3_Setters_A08_t04: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/3_Setters_A08_t05: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A01_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A16_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A16_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A17_t03: crash # co19-roll r546: Please triage this failure
-Language/12_Expressions/03_Numbers_A01_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/03_Numbers_A01_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/03_Numbers_A01_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/03_Numbers_A01_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/03_Numbers_A01_t08: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/03_Numbers_A01_t10: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/05_Strings/1_String_Interpolation_A03_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/05_Strings/1_String_Interpolation_A04_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/05_Strings_A02_t46: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/05_Strings_A02_t48: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/05_Strings_A20_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A01_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A08_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A08_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/1_New_A08_t03: fail # co19-roll r546: Please triage this failure
+Language/05_Variables/05_Variables_A05_t01: fail # Dart issue 12539
+Language/05_Variables/05_Variables_A05_t02: fail # Dart issue 12539
+Language/05_Variables/05_Variables_A05_t03: fail # Dart issue 12539
+Language/05_Variables/05_Variables_A06_t01: fail # Dart issue 12543
+Language/05_Variables/05_Variables_A06_t02: fail # Dart issue 12543
+Language/05_Variables/05_Variables_A06_t03: fail # Dart issue 12543
+Language/05_Variables/05_Variables_A06_t04: fail # Dart issue 12543
+Language/05_Variables/05_Variables_A06_t05: fail # Dart issue 12543
+Language/05_Variables/05_Variables_A06_t06: fail # Dart issue 12543
+Language/05_Variables/05_Variables_A16_t02: fail # Dart issue 12544
+Language/07_Classes/07_Classes_A11_t02: fail # Dart issue 12545
+Language/07_Classes/07_Classes_A11_t04: fail # Dart issue 12545
+Language/07_Classes/3_Setters_A08_t01: fail # co19 issue 520
+Language/07_Classes/3_Setters_A08_t02: fail # co19 issue 520
+Language/07_Classes/3_Setters_A08_t03: fail # co19 issue 520
+Language/07_Classes/3_Setters_A08_t04: fail # co19 issue 520
+Language/07_Classes/3_Setters_A08_t05: fail # co19 issue 520
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: fail # Dart issue 12543
+Language/12_Expressions/01_Constants_A01_t01: fail # co19 issue 522
+Language/12_Expressions/01_Constants_A16_t01: fail # co19 issue 525
+Language/12_Expressions/01_Constants_A16_t02: fail # co19 issue 525
+Language/12_Expressions/03_Numbers_A01_t01: fail # co19 issue 522
+Language/12_Expressions/03_Numbers_A01_t02: fail # co19 issue 522
+Language/12_Expressions/03_Numbers_A01_t03: fail # co19 issue 522
+Language/12_Expressions/03_Numbers_A01_t04: fail # co19 issue 522
+Language/12_Expressions/03_Numbers_A01_t08: fail # co19 issue 522
+Language/12_Expressions/03_Numbers_A01_t10: fail # co19 issue 522
+Language/12_Expressions/05_Strings/1_String_Interpolation_A03_t02: fail # co19 issue 397
+Language/12_Expressions/05_Strings/1_String_Interpolation_A04_t02: fail # co19 issue 397
+Language/12_Expressions/05_Strings_A02_t46: fail # Dart issue 12547
+Language/12_Expressions/05_Strings_A02_t48: fail # Dart issue 12547
+Language/12_Expressions/05_Strings_A20_t01: fail # Dart issue 12518
+Language/12_Expressions/07_Maps_A01_t01: fail # co19 issue 522
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: fail # Dart issue 12549
+Language/12_Expressions/12_Instance_Creation/1_New_A08_t01: fail # co19 issue 397
+Language/12_Expressions/12_Instance_Creation/1_New_A08_t02: fail # co19 issue 397
+Language/12_Expressions/12_Instance_Creation/1_New_A08_t03: fail # co19 issue 397
 Language/12_Expressions/12_Instance_Creation/1_New_A09_t09: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/2_Const_A10_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A05_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t09: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/17_Getter_Invocation_A02_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/18_Assignment_A05_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/18_Assignment_A05_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/18_Assignment_A05_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/18_Assignment_A08_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/30_Identifier_Reference_A05_t02: fail # co19-roll r546: Please triage this failure
+Language/12_Expressions/12_Instance_Creation/2_Const_A10_t01: fail # co19 issue 525
+Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: fail # co19 issue 532
+Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A05_t01: fail # Dart issue 12550
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t02: fail # co19 issue 532
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: fail # co19 issue 532
+Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t05: fail # co19 issue 533
+Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t09: fail # Dart issue 12549
+Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t04: fail # Dart issue 12549
+Language/12_Expressions/17_Getter_Invocation_A02_t01: fail # co19 issue 532
+Language/12_Expressions/18_Assignment_A05_t02: fail # co19 issue 532
+Language/12_Expressions/18_Assignment_A05_t04: fail # co19 issue 532
+Language/12_Expressions/18_Assignment_A05_t05: fail # co19 issue 532
+Language/12_Expressions/18_Assignment_A08_t04: fail # co19 issue 532
+Language/12_Expressions/30_Identifier_Reference_A05_t02: fail # Dart issue 12551
 Language/12_Expressions/30_Identifier_Reference_A08_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/32_Type_Test_A04_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/32_Type_Test_A04_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/32_Type_Test_A04_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/33_Type_Cast_A03_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/33_Type_Cast_A03_t03: fail # co19-roll r546: Please triage this failure
-Language/13_Statements/02_Expression_Statements_A01_t06: fail # co19-roll r546: Please triage this failure
-Language/13_Statements/03_Variable_Declaration_A04_t07: fail # co19-roll r546: Please triage this failure
-Language/13_Statements/03_Variable_Declaration_A04_t08: fail # co19-roll r546: Please triage this failure
-Language/13_Statements/06_For_A01_t11: fail # co19-roll r546: Please triage this failure
+Language/12_Expressions/32_Type_Test_A04_t02: fail # co19 issue 503
+Language/12_Expressions/32_Type_Test_A04_t03: fail # co19 issue 534
+Language/12_Expressions/32_Type_Test_A04_t04: fail # co19 issue 534
+Language/12_Expressions/33_Type_Cast_A03_t02: fail # co19 issue 534
+Language/12_Expressions/33_Type_Cast_A03_t03: fail # co19 issue 534
+Language/13_Statements/02_Expression_Statements_A01_t06: fail # co19 issue 517
+Language/13_Statements/03_Variable_Declaration_A04_t07: fail # co19 issue 535
+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
@@ -286,116 +208,40 @@
 Language/14_Libraries_and_Scripts/2_Exports_A04_t02: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/2_Exports_A04_t03: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/2_Exports_A05_t01: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/5_URIs_A01_t01: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/5_URIs_A01_t04: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/5_URIs_A01_t05: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/5_URIs_A01_t11: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/5_URIs_A01_t14: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/5_URIs_A01_t15: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/5_URIs_A01_t21: fail # co19-roll r546: Please triage this failure
-Language/15_Types/1_Static_Types_A03_t01: fail # co19-roll r546: Please triage this failure
-Language/16_Reference/1_Lexical_Rules/2_Comments_A04_t03: fail # co19-roll r546: Please triage this failure
-LibTest/async/Future/asStream_A01_t01: pass # co19-roll r546: Please triage this failure
-LibTest/async/Future/asStream_A01_t02: pass # co19-roll r546: Please triage this failure
-LibTest/async/Future/asStream_A02_t01: pass # co19-roll r546: Please triage this failure
-LibTest/async/Future/forEach_A03_t01: pass # co19-roll r546: Please triage this failure
-LibTest/async/StreamSink/close_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/Stream.periodic_A01_t01: fail, pass # co19-roll r546: Please triage this failure
-LibTest/async/Stream/Stream.periodic_A03_t01: fail, pass # co19-roll r546: Please triage this failure
-LibTest/async/Timer/run_A01_t01: fail, pass # co19-roll r546: Please triage this failure
-LibTest/async/Timer/Timer_A02_t01: fail, pass # co19-roll r546: Please triage this failure
-LibTest/async/Timer/Timer_A02_t01: fail, pass # co19-roll r546: Please triage this failure
-LibTest/async/Timer/Timer.periodic_A02_t01: fail, pass # co19-roll r546: Please triage this failure
-LibTest/core/DateTime/isAtSameMomentAs_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/DateTime/parse_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/DateTime/year_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/double/parse_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/getRange_A04_t01: pass # co19-roll r546: Please triage this failure
-LibTest/core/List/skip_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/take_A02_t01: fail # co19-roll r546: Please triage this failure
+Language/14_Libraries_and_Scripts/5_URIs_A01_t01: fail # Issue 12521
+Language/14_Libraries_and_Scripts/5_URIs_A01_t04: fail # Issue 12521
+Language/14_Libraries_and_Scripts/5_URIs_A01_t05: fail # Issue 12521
+Language/14_Libraries_and_Scripts/5_URIs_A01_t11: fail # Issue 12521
+Language/14_Libraries_and_Scripts/5_URIs_A01_t14: fail # Issue 12521
+Language/14_Libraries_and_Scripts/5_URIs_A01_t15: fail # Issue 12521
+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
 LibTest/isolate/IsolateSink/addError_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateSink/addError_A01_t02: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateStream/any_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateStream/contains_A02_t01: fail, pass # co19-roll r546: Please triage this failure
+LibTest/isolate/isolate_api/streamSpawnFunction_A02_t03: fail, pass # co19-roll r546: Please triage this failure
 LibTest/isolate/SendPort/send_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/SendPort/send_A02_t04: fail # co19-roll r546: Please triage this failure
-Utils/tests/Expect/listEquals_A02_t01: fail # co19-roll r546: Please triage this failure
-Utils/tests/Expect/listEquals_A03_t01: fail # co19-roll r546: Please triage this failure
-Utils/tests/Expect/setEquals_A02_t01: fail # co19-roll r546: Please triage this failure
+LibTest/isolate/SendPort/send_A02_t04: fail # co19 issue 501
 
 
-
-# co19-roll r546 (11.08.2013) caused these failures
 [ $compiler == none && $runtime == vm && $checked ]
-Language/12_Expressions/12_Instance_Creation_A01_t08: fail # co19-roll r546: Please triage this failure
-Language/13_Statements/09_Switch_A05_t01: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t26: fail # co19-roll r546: Please triage this failure
-Language/15_Types/1_Static_Types_A03_t03: fail # co19-roll r546: Please triage this failure
-Language/15_Types/1_Static_Types_A03_t04: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/asBroadcastStream_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/contains_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/contains_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/distinct_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/drain_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/firstWhere_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/firstWhere_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/first_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/fold_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/fold_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/forEach_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/forEach_A02_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/handleError_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/isBroadcast_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/lastWhere_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/lastWhere_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/listen_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/listen_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/listen_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/map_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/reduce_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/reduce_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/singleWhere_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/skip_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/take_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/take_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/toList_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/toSet_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/transform_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/where_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/where_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/drain_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/firstWhere_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/firstWhere_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/fold_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/fold_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/lastWhere_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/lastWhere_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/reduce_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/reduce_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/singleWhere_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/take_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/transform_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/where_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/where_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/StreamEventTransformer/bind_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/DateTime/compareTo_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/join_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/removeAt_A02_t01: fail # co19-roll r546: Please triage this failure
+Language/12_Expressions/12_Instance_Creation_A01_t08: FAIL, OK  # co19 issue 498
 LibTest/core/Set/intersection_A01_t01: pass # co19-roll r546: Please triage this failure
 LibTest/core/Set/intersection_A01_t03: pass # co19-roll r546: Please triage this failure
 LibTest/core/Set/intersection_A03_t01: pass # co19-roll r546: Please triage this failure
-LibTest/core/int/ceilToDouble_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/int/floorToDouble_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/int/roundToDouble_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/int/truncateToDouble_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateStream/last_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateStream/length_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateStream/single_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/isolate_api/spawnFunction_A03_t01: fail # co19-roll r546: Please triage this failure
+LibTest/core/int/ceilToDouble_A01_t01: fail  # co19 issue 498
+LibTest/core/int/floorToDouble_A01_t01: fail  # co19 issue 498
+LibTest/core/int/roundToDouble_A01_t01: fail  # co19 issue 498
+LibTest/core/int/truncateToDouble_A01_t01: fail  # co19 issue 498
+LibTest/isolate/isolate_api/spawnFunction_A03_t01: fail # co19 issue 497
 
 # co19-roll r546 (11.08.2013) caused these failures
 [ $compiler == none && $runtime == vm && $unchecked ]
-Language/12_Expressions/12_Instance_Creation/2_Const_A09_t02: Fail # co19-roll r546: Please triage this failure
+Language/12_Expressions/12_Instance_Creation/2_Const_A09_t02: Fail # co19 issue 496
 
diff --git a/tests/co19/test_config.dart b/tests/co19/test_config.dart
index ec8cc08..5756107 100644
--- a/tests/co19/test_config.dart
+++ b/tests/co19/test_config.dart
@@ -14,7 +14,8 @@
       : super(configuration,
               "co19",
               new Path("tests/co19/src"),
-              ["tests/co19/co19-analyzer.status",
+              ["tests/co19/co19-co19.status",
+               "tests/co19/co19-analyzer.status",
                "tests/co19/co19-analyzer2.status",
                "tests/co19/co19-runtime.status",
                "tests/co19/co19-dart2dart.status",
diff --git a/tests/compiler/dart2js/import_test.dart b/tests/compiler/dart2js/import_test.dart
new file mode 100644
index 0000000..54748c4
--- /dev/null
+++ b/tests/compiler/dart2js/import_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 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 the compiler can handle missing files used in imports, exports,
+// part tags or as the main source file.
+
+library dart2js.test.import;
+
+import 'package:expect/expect.dart';
+import 'memory_compiler.dart';
+
+const MEMORY_SOURCE_FILES = const {
+  'main.dart': '''
+
+library main;
+
+import 'dart:thisLibraryShouldNotExist';
+import 'package:thisPackageShouldNotExist/thisPackageShouldNotExist.dart';
+export 'foo.dart';
+
+part 'bar.dart';
+
+main() {
+  int i = "";
+}
+''',
+};
+
+testMissingImports() {
+  var collector = new DiagnosticCollector();
+  var compiler = compilerFor(MEMORY_SOURCE_FILES, diagnosticHandler: collector);
+  compiler.run(Uri.parse('memory:main.dart'));
+  Expect.equals(4, collector.errors.length);
+  Expect.equals(1, collector.warnings.length);
+}
+
+testMissingMain() {
+  var collector = new DiagnosticCollector();
+  var compiler = compilerFor({}, diagnosticHandler: collector);
+  compiler.run(Uri.parse('memory:missing.dart'));
+  Expect.equals(1, collector.errors.length);
+  Expect.equals(0, collector.warnings.length);
+}
+
+void main() {
+  testMissingImports();
+  testMissingMain();
+}
diff --git a/tests/compiler/dart2js/library_load_test.dart b/tests/compiler/dart2js/library_load_test.dart
new file mode 100644
index 0000000..36c9adf
--- /dev/null
+++ b/tests/compiler/dart2js/library_load_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";
+import 'mock_compiler.dart';
+
+class ScanMockCompiler extends MockCompiler {
+  ScanMockCompiler() {
+    isolateHelperLibrary = null;
+    foreignLibrary = null;
+  }
+
+  LibraryElement scanBuiltinLibrary(String filename) {
+    return createLibrary(filename, "main(){}");
+  }
+}
+
+void main() {
+  Compiler compiler = new ScanMockCompiler();
+  Expect.equals(null, compiler.isolateHelperLibrary);
+  Expect.equals(null, compiler.foreignLibrary);
+  compiler.onLibraryLoaded(mockLibrary(compiler, "mock"),
+			    new Uri(scheme: 'dart', path: '_isolate_helper'));
+  Expect.isTrue(compiler.isolateHelperLibrary != null);
+  compiler.onLibraryLoaded(mockLibrary(compiler, "mock"),
+			    new Uri(scheme: 'dart', path: '_foreign_helper'));
+  Expect.isTrue(compiler.isolateHelperLibrary != null);
+  Expect.equals(new Uri(scheme: 'dart', path: '_isolate_helper'),
+		 compiler.isolateHelperLibrary.canonicalUri);
+  Expect.isTrue(compiler.foreignLibrary != null);
+  Expect.equals(new Uri(scheme: 'dart', path: '_foreign_helper'),
+		 compiler.foreignLibrary.canonicalUri);
+}
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index 5418963..04a95df 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -11,35 +11,91 @@
        show NullSink;
 
 import '../../../sdk/lib/_internal/compiler/compiler.dart'
-       show DiagnosticHandler;
+       show Diagnostic, DiagnosticHandler;
 
 import 'dart:async';
 
 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart';
 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart';
 
+class DiagnosticMessage {
+  final Uri uri;
+  final int begin;
+  final int end;
+  final String message;
+  final Diagnostic kind;
+
+  DiagnosticMessage(this.uri, this.begin, this.end, this.message, this.kind);
+}
+
+class DiagnosticCollector {
+  List<DiagnosticMessage> messages = <DiagnosticMessage>[];
+
+  void call(Uri uri, int begin, int end, String message,
+                         Diagnostic kind) {
+    messages.add(new DiagnosticMessage(uri, begin, end, message, kind));
+  }
+
+  Iterable<DiagnosticMessage> filterMessagesByKind(Diagnostic kind) {
+    return messages.where(
+      (DiagnosticMessage message) => message.kind == kind);
+  }
+
+  Iterable<DiagnosticMessage> get errors {
+    return filterMessagesByKind(Diagnostic.ERROR);
+  }
+
+  Iterable<DiagnosticMessage> get warnings {
+    return filterMessagesByKind(Diagnostic.WARNING);
+  }
+
+  Iterable<DiagnosticMessage> get hints {
+    return filterMessagesByKind(Diagnostic.HINT);
+  }
+}
+
+DiagnosticHandler createDiagnosticHandler(DiagnosticHandler diagnosticHandler,
+                                          SourceFileProvider provider,
+                                          bool showDiagnostics) {
+  var handler = diagnosticHandler;
+  if (showDiagnostics) {
+    if (diagnosticHandler == null) {
+      handler = new FormattingDiagnosticHandler(provider);
+    } else {
+      var formattingHandler = new FormattingDiagnosticHandler(provider);
+      handler = (Uri uri, int begin, int end, String message, Diagnostic kind) {
+        diagnosticHandler(uri, begin, end, message, kind);
+        formattingHandler(uri, begin, end, message, kind);
+      };
+    }
+  } else if (diagnosticHandler == null) {
+    handler = (Uri uri, int begin, int end, String message, Diagnostic kind) {};
+  }
+  return handler;
+}
+
 Compiler compilerFor(Map<String,String> memorySourceFiles,
                      {DiagnosticHandler diagnosticHandler,
                       List<String> options: const [],
-                      Compiler cachedCompiler}) {
+                      Compiler cachedCompiler,
+                      bool showDiagnostics: true}) {
   Uri script = currentDirectory.resolve(nativeToUriPath(Platform.script));
   Uri libraryRoot = script.resolve('../../../sdk/');
   Uri packageRoot = script.resolve('./packages/');
 
   MemorySourceFileProvider.MEMORY_SOURCE_FILES = memorySourceFiles;
   var provider = new MemorySourceFileProvider();
-  if (diagnosticHandler == null) {
-    diagnosticHandler = new FormattingDiagnosticHandler(provider);
-  }
+  var handler =
+      createDiagnosticHandler(diagnosticHandler, provider, showDiagnostics);
 
   EventSink<String> outputProvider(String name, String extension) {
     if (name != '') throw 'Attempt to output file "$name.$extension"';
     return new NullSink('$name.$extension');
   }
 
-  Compiler compiler = new Compiler(provider.readStringFromUri,
+  Compiler compiler = new Compiler(provider,
                                    outputProvider,
-                                   diagnosticHandler,
+                                   handler,
                                    libraryRoot,
                                    packageRoot,
                                    options);
@@ -49,7 +105,7 @@
     cachedCompiler.libraries.forEach((String uri, library) {
       if (library.isPlatformLibrary) {
         compiler.libraries[uri] = library;
-        compiler.onLibraryScanned(library, library.canonicalUri);
+        compiler.onLibraryLoaded(library, library.canonicalUri);
       }
     });
 
@@ -79,16 +135,16 @@
 
 Future<MirrorSystem> mirrorSystemFor(Map<String,String> memorySourceFiles,
                                      {DiagnosticHandler diagnosticHandler,
-                                      List<String> options: const []}) {
+                                      List<String> options: const [],
+                                      bool showDiagnostics: true}) {
   Uri script = currentDirectory.resolve(nativeToUriPath(Platform.script));
   Uri libraryRoot = script.resolve('../../../sdk/');
   Uri packageRoot = script.resolve('./packages/');
 
   MemorySourceFileProvider.MEMORY_SOURCE_FILES = memorySourceFiles;
   var provider = new MemorySourceFileProvider();
-  if (diagnosticHandler == null) {
-    diagnosticHandler = new FormattingDiagnosticHandler(provider);
-  }
+  var handler =
+      createDiagnosticHandler(diagnosticHandler, provider, showDiagnostics);
 
   List<Uri> libraries = <Uri>[];
   memorySourceFiles.forEach((String path, _) {
@@ -96,5 +152,5 @@
   });
 
   return analyze(libraries, libraryRoot, packageRoot,
-                 provider, diagnosticHandler, options);
+                 provider, handler, options);
 }
diff --git a/tests/compiler/dart2js/memory_source_file_helper.dart b/tests/compiler/dart2js/memory_source_file_helper.dart
index 987fff7..f8ecb27 100644
--- a/tests/compiler/dart2js/memory_source_file_helper.dart
+++ b/tests/compiler/dart2js/memory_source_file_helper.dart
@@ -21,7 +21,7 @@
        show SourceFileProvider;
 
 export '../../../sdk/lib/_internal/compiler/implementation/source_file_provider.dart'
-       show FormattingDiagnosticHandler;
+       show SourceFileProvider, FormattingDiagnosticHandler;
 
 class MemorySourceFileProvider extends SourceFileProvider {
   static Map MEMORY_SOURCE_FILES;
diff --git a/tests/compiler/dart2js/message_kind_helper.dart b/tests/compiler/dart2js/message_kind_helper.dart
index f972a96..6302bf1 100644
--- a/tests/compiler/dart2js/message_kind_helper.dart
+++ b/tests/compiler/dart2js/message_kind_helper.dart
@@ -14,8 +14,13 @@
 
 const String ESCAPE_REGEXP = r'[[\]{}()*+?.\\^$|]';
 
-Compiler check(MessageKind kind, Compiler cachedCompiler) {
-  Expect.isNotNull(kind.howToFix);
+Compiler check(MessageKind kind, Compiler cachedCompiler,
+               {bool expectNoHowToFix: false}) {
+  if (expectNoHowToFix) {
+    Expect.isNull(kind.howToFix);
+  } else {
+    Expect.isNotNull(kind.howToFix);
+  }
   Expect.isFalse(kind.examples.isEmpty);
 
   for (String example in kind.examples) {
@@ -37,7 +42,9 @@
 
     Expect.isFalse(messages.isEmpty, 'No messages in """$example"""');
 
-    String pattern = '${kind.template}\n${kind.howToFix}'.replaceAllMapped(
+    String expectedText = kind.howToFix == null
+        ? kind.template : '${kind.template}\n${kind.howToFix}';
+    String pattern = expectedText.replaceAllMapped(
         new RegExp(ESCAPE_REGEXP), (m) => '\\${m[0]}');
     pattern = pattern.replaceAll(new RegExp(r'#\\\{[^}]*\\\}'), '.*');
 
diff --git a/tests/compiler/dart2js/message_kind_test.dart b/tests/compiler/dart2js/message_kind_test.dart
index 55f9bed..6a2e641 100644
--- a/tests/compiler/dart2js/message_kind_test.dart
+++ b/tests/compiler/dart2js/message_kind_test.dart
@@ -27,9 +27,15 @@
     }
   });
   List<String> names = kinds.keys.toList()..sort();
-  List<String> examples = <String>[];
+  Map<String, bool> examples = <String, bool>{};
   for (String name in names) {
     MessageKind kind = kinds[name];
+    bool expectNoHowToFix = false;
+    if (name == 'READ_SCRIPT_ERROR') {
+      // For this we can give no how-to-fix since the underlying error is
+      // unknown.
+      expectNoHowToFix = true;
+    }
     if (name == 'GENERIC' // Shouldn't be used.
         // We can't provoke a crash.
         || name == 'COMPILER_CRASHED'
@@ -37,16 +43,17 @@
         // We cannot provide examples for patch errors.
         || name.startsWith('PATCH_')) continue;
     if (kind.examples != null) {
-      examples.add(name);
+      examples[name] = expectNoHowToFix;
     } else {
       print("No example in '$name'");
     }
   };
   var cachedCompiler;
-  for (String name in examples) {
+  examples.forEach((String name, bool expectNoHowToFix) {
     Stopwatch sw = new Stopwatch()..start();
-    cachedCompiler = check(kinds[name], cachedCompiler);
+    cachedCompiler = check(kinds[name], cachedCompiler,
+                           expectNoHowToFix: expectNoHowToFix);
     sw.stop();
     print("Checked '$name' in ${sw.elapsedMilliseconds}ms.");
-  }
+  });
 }
diff --git a/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart b/tests/compiler/dart2js/mirror_helper_unique_minification_test.dart
new file mode 100644
index 0000000..35885cd
--- /dev/null
+++ b/tests/compiler/dart2js/mirror_helper_unique_minification_test.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.
+
+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/dart_backend/dart_backend.dart'
+show
+    DartBackend;
+
+main() {
+  testUniqueMinification();
+  testNoUniqueMinification();
+}
+
+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 testUniqueMinification() {
+  Compiler compiler = runCompiler(useMirrorHelperLibrary: true, minify: true);
+  DartBackend backend = compiler.backend;
+  Map<Node, String> renames = backend.renames;
+
+  //'Foo' appears twice, so toSet() reduces the length by 1.
+  Expect.equals(renames.values.toSet().length, renames.values.length - 1);
+}
+
+void testNoUniqueMinification() {
+  Compiler compiler = runCompiler(useMirrorHelperLibrary: false, minify: true);
+  DartBackend backend = compiler.backend;
+  Map<Node, String> renames = backend.renames;
+
+  //'Foo' appears twice and now 'invocation' and 'hest' can get the same name.
+  Expect.equals(renames.values.toSet().length, renames.values.length - 2);
+}
+
+const MEMORY_SOURCE_FILES = const <String, String> {
+  'main.dart': """
+import 'dart:mirrors';
+
+class Foo {
+  noSuchMethod(invocation) {
+    MirrorSystem.getName(const Symbol('hest'));
+  }
+}
+
+main() {
+  new Foo().fisk();
+  var hest;
+}
+"""};
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 2d72fc5..688f4bc 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -154,6 +154,8 @@
   class JSNull extends Interceptor {
     bool operator==(other) => identical(null, other);
     get hashCode => throw "JSNull.hashCode not implemented.";
+    String toString() => 'Null';
+    Type get runtimeType => null;
   }
   class JSBool extends Interceptor implements bool {
   }
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index 74194b5..5eb96d2 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -426,6 +426,29 @@
   return a;
 }
 
+testSpecialization1() {
+  var a = topLevelGetter();
+  a - 42;
+  return a;
+}
+
+testSpecialization2() {
+  var a = topLevelGetter();
+  // Make [a] a captured variable. This should disable receiver
+  // specialization on [a].
+  (() => a.toString())();
+  a - 42;
+  return a;
+}
+
+testSpecialization3() {
+  var a = returnDynamic() ? null : 42;
+  a.toString();
+  // Test that calling an [Object] method on [a] will not lead to
+  // infer that [a] is not null;
+  return a;
+}
+
 testReturnInvokeDynamicGetter() => new A().myFactory();
 
 var topLevelConstList = const [42];
@@ -565,6 +588,9 @@
   testReturnInvokeDynamicGetter();
   testCascade1();
   testCascade2();
+  testSpecialization1();
+  testSpecialization2();
+  testSpecialization3();
 }
 """;
 
@@ -687,4 +713,7 @@
   checkReturn('testCascade1', typesTask.growableListType);
   checkReturn('testCascade2', new TypeMask.nonNullExact(
       typesTask.rawTypeOf(findElement(compiler, 'CascadeHelper'))));
+  checkReturn('testSpecialization1', typesTask.numType);
+  checkReturn('testSpecialization2', typesTask.dynamicType);
+  checkReturn('testSpecialization3', typesTask.intType.nullable());
 }
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 3824d9e..4e70d58 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -15,7 +15,6 @@
 deferred/deferred_class_test: Pass, Crash # Issue 9158
 
 [ $compiler == dart2js && $checked ]
-parameter_bailout_test: Fail, OK
 variable_type_test/03: Fail, OK
 variable_type_test/01: Fail, OK
 
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index d2fd801..ecd14b0 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -4,14 +4,13 @@
 
 reg_exp_unicode_2_test: Fail # Bug 6592
 
-[ $compiler == dart2js && ($runtime == d8 || $runtime == drt) ]
+[ $compiler == dart2js && $runtime == drt ]
 hash_set_test: Pass, Fail # v8 bug: Issue 12293
 list_test: Pass, Fail # v8 bug: Issue 12293
 
 
 [ $compiler == none ]
 unicode_test: Fail        # Bug 6706
-*dartc_test: Skip
 compare_to2_test: Fail    # Bug 4018
 
 symbol_test/01: Fail, Pass # bug 11669
@@ -42,12 +41,6 @@
 date_time7_test: Fail
 unicode_test: Fail
 
-[ $runtime == ie9 && ($system == linux || $system == macos) ]
-*: Skip
-
-[ $runtime == safari && ($system == linux || $system == windows) ]
-*: Skip
-
 [ $runtime == vm ]
 string_trim_unicode_test: Fail  # Bug 6569
 
diff --git a/tests/html/async_test.dart b/tests/html/async_test.dart
index 1d7768f..616258c 100644
--- a/tests/html/async_test.dart
+++ b/tests/html/async_test.dart
@@ -40,10 +40,8 @@
 cancellingIsolate() {
   port.receive((msg, replyTo) {
     expect(msg, 'START');
-    final oneshot = new Timer(const Duration(milliseconds: 30), () {
-      fail('Should never be invoked');
-    });
     bool shot = false;
+    var oneshot;
     var periodic;
     periodic = new Timer.periodic(const Duration(milliseconds: 10), (timer) {
       expect(shot, isFalse);
@@ -57,6 +55,13 @@
         replyTo.send('DONE');
       });
     });
+    // We launch the oneshot timer after the periodic timer. Otherwise a
+    // (very long) context switch could make this test flaky: assume the
+    // oneshot timer is created first and then there is a 30ms context switch.
+    // when the periodic timer is scheduled it would execute after the oneshot.
+    oneshot = new Timer(const Duration(milliseconds: 30), () {
+      fail('Should never be invoked');
+    });
   });
 }
 
diff --git a/tests/html/custom/attribute_changed_callback_test.dart b/tests/html/custom/attribute_changed_callback_test.dart
new file mode 100644
index 0000000..3e78587
--- /dev/null
+++ b/tests/html/custom/attribute_changed_callback_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 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 attribute_changed_callback_test;
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'dart:html';
+
+class A extends HtmlElement {
+  static final tag = 'x-a';
+  factory A() => new Element.tag(tag);
+
+  static var attributeChangedInvocations = 0;
+
+  void onAttributeChanged(name, oldValue, newValue) {
+    attributeChangedInvocations++;
+  }
+}
+
+class B extends HtmlElement {
+  static final tag = 'x-b';
+  factory B() => new Element.tag(tag);
+
+  static var invocations = [];
+
+  void onCreated() {
+    invocations.add('created');
+  }
+
+  void onAttributeChanged(name, oldValue, newValue) {
+    invocations.add('$name: $oldValue => $newValue');
+  }
+}
+
+main() {
+  useHtmlConfiguration();
+
+  // Adapted from Blink's fast/dom/custom/attribute-changed-callback test.
+
+  test('transfer attribute changed callback', () {
+    document.register(A.tag, A);
+    var element = new A();
+
+    element.attributes['a'] = 'b';
+    expect(A.attributeChangedInvocations, 1);
+  });
+
+  test('add, change and remove an attribute', () {
+    document.register(B.tag, B);
+    var b = new B();
+    b.id = 'x';
+    expect(B.invocations, ['created', 'id: null => x']);
+
+    B.invocations = [];
+    b.attributes.remove('id');
+    expect(B.invocations, ['id: x => null']);
+
+    B.invocations = [];
+    b.attributes['data-s'] = 't';
+    expect(B.invocations, ['data-s: null => t']);
+
+    B.invocations = [];
+    b.classList.toggle('u');
+    expect(B.invocations, ['class: null => u']);
+
+    b.attributes['data-v'] = 'w';
+    B.invocations = [];
+    b.attributes['data-v'] = 'x';
+    expect(B.invocations, ['data-v: w => x']);
+
+    B.invocations = [];
+    b.attributes['data-v'] = 'x';
+    expect(B.invocations, []);
+  });
+}
diff --git a/tests/html/custom/constructor_calls_created_synchronously_test.dart b/tests/html/custom/constructor_calls_created_synchronously_test.dart
new file mode 100644
index 0000000..ae11d86
--- /dev/null
+++ b/tests/html/custom/constructor_calls_created_synchronously_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.
+
+library constructor_calls_created_synchronously_test;
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'dart:html';
+
+class A extends HtmlElement {
+  static final tag = 'x-a';
+  factory A() => new Element.tag(tag);
+
+  static int ncallbacks = 0;
+
+  void onCreated() {
+    ncallbacks++;
+  }
+}
+
+main() {
+  useHtmlConfiguration();
+
+  // Adapted from Blink's
+  // fast/dom/custom/constructor-calls-created-synchronously test.
+
+  test('createdCallback', () {
+    document.register(A.tag, A);
+    var x = new A();
+    expect(A.ncallbacks, 1);
+  });
+}
diff --git a/tests/html/custom/created_callback_test.dart b/tests/html/custom/created_callback_test.dart
new file mode 100644
index 0000000..2f3cd51
--- /dev/null
+++ b/tests/html/custom/created_callback_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 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 created_callback_test;
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'dart:html';
+
+class A extends HtmlElement {
+  static final tag = 'x-a';
+  factory A() => new Element.tag(tag);
+
+  static int createdInvocations = 0;
+
+  void onCreated() {
+    createdInvocations++;
+  }
+}
+
+class B extends HtmlElement {
+  static final tag = 'x-b';
+  factory B() => new Element.tag(tag);
+}
+
+class C extends HtmlElement {
+  static final tag = 'x-c';
+  factory C() => new Element.tag(tag);
+
+  static int createdInvocations = 0;
+  static var div;
+
+  void onCreated() {
+    createdInvocations++;
+
+    if (this.id != 'u') {
+      return;
+    }
+
+    var t = div.query('#t');
+    var v = div.query('#v');
+    var w = div.query('#w');
+
+    expect(query('x-b:not(:unresolved)'), this);
+    expect(queryAll(':unresolved'), [v, w]);
+
+    // As per:
+    // http://www.w3.org/TR/2013/WD-custom-elements-20130514/#serializing-and-parsing
+    // creation order is t, u, v, w (postorder).
+    expect(t is C, isTrue);
+    // Note, this is different from JavaScript where this would be false.
+    expect(v is C, isTrue);
+  }
+}
+
+main() {
+  useHtmlConfiguration();
+
+  // Adapted from Blink's
+  // fast/dom/custom/created-callback test.
+
+  test('transfer created callback', () {
+    document.register(A.tag, A);
+    var x = new A();
+    expect(A.createdInvocations, 1);
+  });
+
+  test(':unresolved and created callback timing', () {
+    document.register(B.tag, B);
+    document.register(C.tag, C);
+
+    var div = new DivElement();
+    C.div = div;
+    div.innerHtml = """
+<x-c id="t"></x-c>
+<x-b id="u"></x-b>
+<x-c id="v"></x-c>
+<x-b id="w"></x-b>
+""";
+
+    expect(C.createdInvocations, 2);
+    expect(div.query('#w') is B, isTrue);
+  });
+
+  // TODO(vsm): Port additional test from upstream here:
+  // http://src.chromium.org/viewvc/blink/trunk/LayoutTests/fast/dom/custom/created-callback.html?r1=156141&r2=156185
+}
diff --git a/tests/html/custom/document_register_basic_test.dart b/tests/html/custom/document_register_basic_test.dart
new file mode 100644
index 0000000..718358a
--- /dev/null
+++ b/tests/html/custom/document_register_basic_test.dart
@@ -0,0 +1,131 @@
+// Copyright (c) 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 document_register_basic_test;
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'dart:html';
+
+class Foo extends HtmlElement {
+  static final tag = 'x-foo';
+  factory Foo() => new Element.tag(tag);
+
+  get thisIsACustomClass => true;
+}
+
+class Bar extends HtmlElement {
+  static final tag = 'x-bar';
+  factory Bar() => new Element.tag(tag);
+
+  get thisIsACustomClass => true;
+}
+
+class Baz extends Foo {
+  static final tag = 'x-baz';
+  factory Baz() => new Element.tag(tag);
+
+  get thisIsAlsoACustomClass => true;
+}
+
+class BadB {
+}
+
+class BadE implements HtmlElement {
+  static final tag = 'x-tag-e';
+  factory BadE() => new Element.tag(tag);
+}
+
+main() {
+  useHtmlConfiguration();
+
+  // Adapted from Blink's fast/dom/custom/document-register-basic test.
+
+  test('Testing document.register() basic behaviors', () {
+    document.register(Foo.tag, Foo);
+
+    // Cannot register an existing dart:html type.
+    expect(() => document.register('x-bad-a', HtmlElement), throws);
+
+    // Invalid user type.  Doesn't inherit from HtmlElement.
+    expect(() => document.register('x-bad-b', BadB), throws);
+
+    // Not a type.
+    expect(() => document.register('x-bad-c', null), throws);
+
+    // Cannot register system type.
+    expect(() => document.register('x-bad-d', Object), throws);
+
+    // Must extend HtmlElement, not just implement it.
+    expect(() => document.register(BadE.tag, BadE), throws);
+
+    // Constructor initiated instantiation
+    var createdFoo = new Foo();
+    expect(createdFoo.thisIsACustomClass, isTrue);
+
+    // Dart type correctness
+    expect(createdFoo is HtmlElement, isTrue);
+    expect(createdFoo is Foo, isTrue);
+    expect(createdFoo.runtimeType, Foo);
+
+    // Native getter
+    expect(createdFoo.tagName, "X-FOO");
+
+    // Native setter
+    createdFoo.innerHtml = "Hello";
+    expect(createdFoo.text, "Hello");
+
+    // Native method
+    var childDiv = new DivElement();
+    createdFoo.append(childDiv);
+    expect(createdFoo.lastChild, childDiv);
+
+    // Parser initiated instantiation
+    var container = new DivElement()..id = "container";
+    document.body.append(container);
+    container.innerHtml = "<x-foo></x-foo>";
+    var parsedFoo = container.firstChild;
+
+    expect(parsedFoo is Foo, isTrue);
+    expect(parsedFoo.tagName, "X-FOO");
+
+    // Ensuring the wrapper is retained
+    var someProperty = new Expando();
+    someProperty[parsedFoo] = "hello";
+    expect(container.firstChild, parsedFoo);
+    expect(someProperty[container.firstChild], someProperty[parsedFoo]);
+
+    // Having another constructor
+    document.register(Bar.tag, Bar);
+    var createdBar = new Bar();
+    expect(createdBar is Bar, isTrue);
+    expect(createdBar is Foo, isFalse);
+    expect(createdBar.tagName, "X-BAR");
+
+    // Having a subclass
+    document.register(Baz.tag, Baz);
+    var createdBaz = new Baz();
+    expect(createdBaz.tagName, "X-BAZ");
+    expect(createdBaz.thisIsACustomClass, isTrue);
+    expect(createdBaz.thisIsAlsoACustomClass, isTrue);
+
+    // With irregular cases
+    var createdUpperBar = new Element.tag("X-BAR");
+    var createdMixedBar = new Element.tag("X-Bar");
+    expect(createdUpperBar is Bar, isTrue);
+    expect(createdUpperBar.tagName, "X-BAR");
+    expect(createdMixedBar is Bar, isTrue);
+    expect(createdMixedBar.tagName, "X-BAR");
+
+    container.innerHtml = "<X-BAR></X-BAR><X-Bar></X-Bar>";
+    expect(container.firstChild is Bar, isTrue);
+    expect(container.firstChild.tagName, "X-BAR");
+    expect(container.lastChild is Bar, isTrue);
+    expect(container.lastChild.tagName, "X-BAR");
+
+    // Constructors shouldn't interfere with each other
+    expect((new Foo()).tagName, "X-FOO");
+    expect((new Bar()).tagName, "X-BAR");
+    expect((new Baz()).tagName, "X-BAZ");
+  });
+}
diff --git a/tests/html/custom/document_register_type_extensions_test.dart b/tests/html/custom/document_register_type_extensions_test.dart
new file mode 100644
index 0000000..cacb251
--- /dev/null
+++ b/tests/html/custom/document_register_type_extensions_test.dart
@@ -0,0 +1,197 @@
+// Copyright (c) 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 document_register_type_extensions_test;
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'dart:html';
+
+class Foo extends HtmlElement {
+  static final tag = 'x-foo';
+  factory Foo() => new Element.tag(tag);
+}
+
+class Bar extends InputElement {
+  static final tag = 'x-bar';
+  factory Bar() => document.$dom_createElement('input', tag);
+}
+
+class Baz extends Foo {
+  static final tag = 'x-baz';
+  factory Baz() => new Element.tag(tag);
+}
+
+class Qux extends Bar {
+  static final tag = 'x-qux';
+  factory Qux() => document.$dom_createElement('input', tag);
+}
+
+class FooBad extends DivElement {
+  static final tag = 'x-foo';
+  factory FooBad() => document.$dom_createElement('div', tag);
+}
+
+main() {
+  useHtmlConfiguration();
+
+  // Adapted from Blink's fast/dom/custom/document-register-type-extension test.
+
+  var testForm = new FormElement()..id = 'testForm';
+  document.body.append(testForm);
+
+  var isFormControl = (element) {
+    testForm.append(element);
+    return element.form == testForm;
+  };
+
+  test('construction', () {
+    document.register(Foo.tag, Foo);
+    document.register(Bar.tag, Bar);
+    document.register(Baz.tag, Baz);
+    document.register(Qux.tag, Qux);
+
+    expect(() => document.register(FooBad.tag, Foo), throws);
+
+    // Constructors
+
+    var fooNewed = new Foo();
+    var fooOuterHtml = "<x-foo></x-foo>";
+    expect(fooNewed.outerHtml, fooOuterHtml);
+    expect(fooNewed is Foo, isTrue);
+    expect(fooNewed is HtmlElement, isTrue);
+    expect(fooNewed is UnknownElement, isFalse);
+
+    var barNewed = new Bar();
+    var barOuterHtml = '<input is="x-bar">';
+    expect(barNewed.outerHtml, barOuterHtml);
+    expect(barNewed is Bar, isTrue);
+    expect(barNewed is InputElement, isTrue);
+    expect(isFormControl(barNewed), isTrue);
+
+    var bazNewed = new Baz();
+    var bazOuterHtml = "<x-baz></x-baz>";
+    expect(bazNewed.outerHtml, bazOuterHtml);
+    expect(bazNewed is Baz, isTrue);
+    expect(bazNewed is HtmlElement, isTrue);
+    expect(bazNewed is UnknownElement, isFalse);
+
+    var quxNewed = new Qux();
+    var quxOuterHtml = '<input is="x-qux">';
+    expect(quxNewed.outerHtml, quxOuterHtml);
+    expect(quxNewed is Qux, isTrue);
+    expect(quxNewed is InputElement, isTrue);
+    expect(isFormControl(quxNewed), isTrue);
+
+    // new Element.tag
+
+    var fooCreated = new Element.tag('x-foo');
+    expect(fooCreated.outerHtml, fooOuterHtml);
+    expect(fooCreated is Foo, isTrue);
+
+    var barCreated = new Element.tag('x-bar');
+    expect(barCreated.outerHtml, "<x-bar></x-bar>");
+    expect(barCreated is Bar, isFalse);
+    expect(barCreated is UnknownElement, isFalse);
+    expect(barCreated is HtmlElement, isTrue);
+
+    var bazCreated = new Element.tag('x-baz');
+    expect(bazCreated.outerHtml, bazOuterHtml);
+    expect(bazCreated is Baz, isTrue);
+    expect(bazCreated is UnknownElement, isFalse);
+
+    var quxCreated = new Element.tag('x-qux');
+    expect(quxCreated.outerHtml, "<x-qux></x-qux>");
+    expect(quxCreated is Qux, isFalse);
+    expect(quxCreated is UnknownElement, isFalse);
+    expect(quxCreated is HtmlElement, isTrue);
+
+    // create with type extensions
+    // TODO(vsm): How should we expose this?
+
+    var divFooCreated = document.$dom_createElement("div", Foo.tag);
+    expect(divFooCreated.outerHtml, '<div is="x-foo"></div>');
+    expect(divFooCreated is Foo, isFalse);
+    expect(divFooCreated is DivElement, isTrue);
+
+    var inputBarCreated =
+	document.$dom_createElement("input", Bar.tag);
+    expect(inputBarCreated.outerHtml, barOuterHtml);
+    expect(inputBarCreated is Bar, isTrue);
+    expect(inputBarCreated is UnknownElement, isFalse);
+    expect(isFormControl(inputBarCreated), isTrue);
+
+    var divBarCreated = document.$dom_createElement("div", Bar.tag);
+    expect(divBarCreated.outerHtml, '<div is="x-bar"></div>');
+    expect(divBarCreated is Bar, isFalse);
+    expect(divBarCreated is DivElement, isTrue);
+
+    var fooBarCreated =
+	document.$dom_createElement(Foo.tag, Bar.tag);
+    expect(fooBarCreated.outerHtml, '<x-foo is="x-bar"></x-foo>');
+    expect(fooBarCreated is Foo, isTrue);
+
+    var barFooCreated = document.$dom_createElement(Bar.tag,
+						      Foo.tag);
+    expect(barFooCreated.outerHtml, '<x-bar is="x-foo"></x-bar>');
+    expect(barFooCreated is UnknownElement, isFalse);
+    expect(barFooCreated is HtmlElement, isTrue);
+
+    var fooCreatedNull = document.$dom_createElement(Foo.tag, null);
+    expect(fooCreatedNull.outerHtml, fooOuterHtml);
+    expect(fooCreatedNull is Foo, isTrue);
+
+    var fooCreatedEmpty = document.$dom_createElement(Foo.tag, "");
+    expect(fooCreatedEmpty.outerHtml, fooOuterHtml);
+    expect(fooCreatedEmpty is Foo, isTrue);
+
+    expect(() => document.$dom_createElement('@invalid', 'x-bar'), throws);
+
+    // Create NS with type extensions
+
+    var fooCreatedNS =
+	document.$dom_createElementNS("http://www.w3.org/1999/xhtml",
+				      Foo.tag, null);
+    expect(fooCreatedNS.outerHtml, fooOuterHtml);
+    expect(fooCreatedNS is Foo, isTrue);
+
+    var barCreatedNS =
+	document.$dom_createElementNS("http://www.w3.org/1999/xhtml", "input",
+				      Bar.tag);
+    expect(barCreatedNS.outerHtml, barOuterHtml);
+    expect(barCreatedNS is Bar, isTrue);
+    expect(isFormControl(barCreatedNS), isTrue);
+
+    expect(() =>
+	     document.$dom_createElementNS(
+	         'http://example.com/2013/no-such-namespace',
+		 'xml:lang', 'x-bar'), throws);
+
+    // Parser
+
+    createElementFromHtml(html) {
+	var container = new DivElement()..innerHtml = html;
+	return container.firstChild;
+    }
+
+    var fooParsed = createElementFromHtml('<x-foo>');
+    expect(fooParsed is Foo, isTrue);
+
+    var barParsed = createElementFromHtml('<input is=x-bar>');
+    expect(barParsed is Bar, isTrue);
+    expect(isFormControl(barParsed), isTrue);
+
+    var divFooParsed = createElementFromHtml('<div is=x-foo>');
+    expect(divFooParsed is Foo, isFalse);
+    expect(divFooParsed is DivElement, isTrue);
+
+    var namedBarParsed = createElementFromHtml('<x-bar>');
+    expect(namedBarParsed is Bar, isFalse);
+    expect(namedBarParsed is UnknownElement, isFalse);
+    expect(namedBarParsed is HtmlElement, isTrue);
+
+    var divBarParsed = createElementFromHtml('<div is=x-bar>');
+    expect(divBarParsed is Bar, isFalse);
+    expect(divBarParsed is DivElement, isTrue);
+  });
+}
diff --git a/tests/html/custom_elements_test.dart b/tests/html/custom_elements_test.dart
index a78892b..8f627e7 100644
--- a/tests/html/custom_elements_test.dart
+++ b/tests/html/custom_elements_test.dart
@@ -3,9 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library custom_elements_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'dart:async';
 import 'dart:html';
+import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
 
 class CustomMixin {
   var mixinMethodCalled;
@@ -35,9 +36,23 @@
 
 class NotAnElement {}
 
+loadPolyfills() {
+  if (!document.supportsRegister) {
+    // Cache blocker is a workaround for:
+    // https://code.google.com/p/dart/issues/detail?id=11834
+    var cacheBlocker = new DateTime.now().millisecondsSinceEpoch;
+    return HttpRequest.getString('/root_dart/pkg/custom_element/lib/'
+      'custom-elements.debug.js?cacheBlock=$cacheBlocker').then((code) {
+      document.head.children.add(new ScriptElement()..text = code);
+    });
+  }
+}
+
 main() {
   useHtmlIndividualConfiguration();
 
+  setUp(loadPolyfills);
+
   group('register', () {
     test('register', () {
       var tag = nextTag;
@@ -83,11 +98,14 @@
     });
   });
 
+  // TODO(vsm): Modify this test once we agree on the proper semantics.
+  /*
   group('preregister', () {
-    // TODO(vsm): Modify this test once we agree on the proper semantics.
+
     test('pre-registration construction', () {
       var tag = nextTag;
       var dom = new Element.html('<div><$tag></$tag></div>');
+
       var preElement = dom.children[0];
       expect(preElement, isNotNull);
       expect(preElement is HtmlElement, isTrue);
@@ -98,6 +116,7 @@
       });
 
       document.register(tag, CustomType);
+      Platform.upgradeCustomElements(dom);
 
       var postElement = dom.children[0];
       expect(postElement, isNotNull);
@@ -118,7 +137,7 @@
       expect(firedOnPre, isTrue);
       expect(firedOnPost, isTrue);
     });
-  });
+  });*/
 
   group('innerHtml', () {
     test('query', () {
diff --git a/tests/html/html.status b/tests/html/html.status
index 8cdf46d..7c00a70 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -2,12 +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.
 
+# Skipped for in-progress Dartium rull on 8-16-2013
+node_test/iterating: Fail
+websocket_test: skip
+
 async_window_test: Skip #TODO(gram): investigating
 event_test: Skip  # Issue 1996
 interactive_test: Skip # Must be run manually.
 
 [ $compiler == dart2js && $runtime != drt ]
-custom_elements_test: Skip
+custom/*: Skip
+
+[ $compiler == dart2js && $browser ]
+# Issue 9325 failures
+custom/attribute_changed_callback_test: Fail
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium) && $mode == debug && $system == macos]
 audiobuffersourcenode_test: Pass, Fail, Crash # http://crbug.com/256601
@@ -15,15 +23,14 @@
 [ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 # postMessage in dartium always transfers the typed array buffer, never a view
 postmessage_structured_test/typed_arrays: Fail
-events_test: Pass, Fail # Issue 12489
 custom_elements_test/lifecycle: Fail   # Issue 9326 - Implement "extends Element" in dartium
+# Issue 9326 failures
+custom/attribute_changed_callback_test: Fail
+custom/created_callback_test: Fail
 
 [ $compiler == none && $runtime == drt && $system == windows ]
 worker_test/functional: Pass, Crash # Issue 9929.
 
-[ $compiler == dart2js && $checked ]
-template_element_test: Fail # BUG(11480): Triage.
-
 [ $compiler == dart2js && ($runtime == ie9 || $runtime == ie10 || $runtime == safari || $runtime == ff || $runtime == chrome || $runtime == chromeOnAndroid || $runtime == opera || $runtime == drt || $runtime == dartium)]
 dom_isolates_test: Skip # Need to migrate to new spawnDomFunction.
 
@@ -41,10 +48,11 @@
 [ $compiler == dart2js && $browser && $checked ]
 postmessage_structured_test/typed_arrays: Fail # Issue 10097
 postmessage_structured_test/primitives: Fail # Issue 10097
-
-# Layout tests are only supported on DRT.
-[ $runtime == ie9 || $runtime == ie10 || $runtime == safari || $runtime == ff || $runtime == chrome || $runtime == opera ]
-*layout_test: Skip
+# Issue 9325 failures
+custom/constructor_calls_created_synchronously_test: Fail
+custom/created_callback_test: Fail
+custom/document_register_basic_test: Fail
+custom/document_register_type_extensions_test: Fail
 
 [ $runtime == chrome ]
 canvasrenderingcontext2d_test/drawImage_video_element: Pass,Fail # Issue 11836
@@ -55,6 +63,8 @@
 xhr_test: Pass, Fail # Issue 11884
 xhr_cross_origin_test: Pass, Fail # Issue 11884
 
+fileapi_test/directoryReader: Fail  # Issue 12573
+
 [ $runtime == chrome || $runtime == chromeOnAndroid || $runtime == drt || $runtime == safari ]
 audiocontext_test: Skip # Issue 9322
 
@@ -277,7 +287,6 @@
 blob_constructor_test: Fail
 canvas_test: Fail
 canvas_test: Pass,Fail
-canvas_using_html_test: Fail
 cssstyledeclaration_test: Fail
 document_test/document: Fail # Issue: 7413
 element_add_test: Fail
@@ -288,7 +297,6 @@
 element_test/eventListening: Crash
 element_test/eventListening: Fail # Issue: 7413
 element_test/queryAll: Fail
-element_webkit_test: Fail
 fileapi_test: Skip # Timeout.
 form_data_test: Fail # Issue: 7413
 htmlelement_test: Fail
@@ -342,7 +350,7 @@
 input_element_test/supported_datetime-local: Fail
 input_element_test/supported_month: Fail
 input_element_test/supported_number: Fail
-input_element_test/supported_range: Fail
+input_element_test/supported_range: Fail, Pass # FF 23 is introducing support.
 input_element_test/supported_time: Fail
 input_element_test/supported_week: Fail
 media_stream_test/supported_MediaStreamEvent: Fail
@@ -361,12 +369,6 @@
 [ $runtime == ff && $system == linux ]
 rtc_test/functionality: Fail # Issue: 12109.
 
-[ $runtime == ie9 && ($system == linux || $system == macos) ]
-*: Skip
-
-[ $runtime == safari && ($system == linux || $system == windows) ]
-*: Skip
-
 # 'html' tests import the HTML library, so they only make sense in
 # a browser environment.
 [ $runtime == vm ]
@@ -387,4 +389,3 @@
 js_test: Skip                      # Test cannot run under CSP restrictions (times out).
 postmessage_structured_test: Skip  # Test cannot run under CSP restrictions (times out).
 safe_dom_test: Skip                # Test cannot run under CSP restrictions (times out).
-shadow_dom_layout_test: Fail, OK   # Test cannot run under CSP restrictions.
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 73c3a5c..3655cf9 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -62,23 +62,8 @@
 
 [ $runtime == safari ]
 cross_isolate_message_test: Skip      # Depends on 32/64 bit Safari. See Issue 1120
-mixed_test: Pass,Fail               # Depends on 32/64 bit Safari. See Issue 1120
-mixed2_test: Pass,Fail              # Depends on 32/64 bit Safari. See Issue 1120
 message_test: Skip
 
-# TODO(ager): Update these.
-[ $runtime == ie9 && $system == windows ]
-v2*: Skip
-
-[ $runtime == safari && $system == macos ]
-v2*: Skip
-
-[ $runtime == ie9 && ($system == linux || $system == macos) ]
-*: Skip
-
-[ $runtime == safari && ($system == linux || $system == windows) ]
-*: Skip
-
 [ $runtime == opera ]
 isolate2_negative_test: Skip # Timeout.
 unresolved_ports_negative_test: Skip # See Issue 6839
@@ -125,3 +110,8 @@
 
 [ $arch == simmips ]
 *: Skip
+
+[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
+# Skipped for in-progress Dartium rull on 8-16-2013
+isolate_stress_test: Skip
+
diff --git a/tests/json/json.status b/tests/json/json.status
index 0d01775..ebf041d 100644
--- a/tests/json/json.status
+++ b/tests/json/json.status
@@ -2,12 +2,6 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $runtime == ie9 && ($system == linux || $system == macos) ]
-*: Skip
-
-[ $runtime == safari && ($system == linux || $system == windows) ]
-*: Skip
-
 [ $runtime == vm ]
 *: Skip
 
diff --git a/tests/language/compile_time_constant10_test.dart b/tests/language/compile_time_constant10_test.dart
index a2d1a02..a29cb8a 100644
--- a/tests/language/compile_time_constant10_test.dart
+++ b/tests/language/compile_time_constant10_test.dart
@@ -34,7 +34,7 @@
 class CT {
   final x1;
   final x2;
-  bool id;
+  final bool id;
   const CT(var x1, var x2)
       : this.x1 = x1, this.x2 = x2, this.id = identical(x1, x2);
   void test(void expect(a,b), name) {
diff --git a/tests/language/dynamic_prefix_core_test.dart b/tests/language/dynamic_prefix_core_test.dart
new file mode 100644
index 0000000..1aba87f
--- /dev/null
+++ b/tests/language/dynamic_prefix_core_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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 explicit import of dart:core in the source code..
+
+library DynamicPrefixCoreTest.dart;
+import "package:expect/expect.dart";
+import "dart:core" as mycore;
+
+void main() {
+  // Should still be available because it is not a member of dart:core.
+  Expect.isTrue(dynamic is Type);
+  
+  Expect.throws(() => mycore.dynamic is Type,
+                (e) => e is NoSuchMethodError,
+                'dynamic is not a member of dart:core');
+}
diff --git a/tests/language/f_bounded_quantification4_test.dart b/tests/language/f_bounded_quantification4_test.dart
new file mode 100644
index 0000000..922e225
--- /dev/null
+++ b/tests/language/f_bounded_quantification4_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test for F-Bounded Quantification.
+
+import "package:expect/expect.dart";
+
+class A<T extends B<T>> { }
+
+class B<T> extends A<T> { }
+
+main() {
+  Expect.equals("B<B>", new B<B>().runtimeType.toString());
+}
+
diff --git a/tests/language/field_override3_test.dart b/tests/language/field_override3_test.dart
new file mode 100644
index 0000000..fff5fd0
--- /dev/null
+++ b/tests/language/field_override3_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that we report a compile-time error when a static field conflicts with
+// an inherited instance member of the same name.
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo = 42;  /// 00: compile-time error
+  get foo => 42;  /// 01: compile-time error
+  foo() => 42;  /// 02: compile-time error
+  set foo(value) { }  /// 03: compile-time error
+}
+
+class B extends A {
+  static var foo = 42;
+}
+
+main() {
+  Expect.equals(42, B.foo);
+}
diff --git a/tests/language/field_override4_test.dart b/tests/language/field_override4_test.dart
new file mode 100644
index 0000000..46e6c73
--- /dev/null
+++ b/tests/language/field_override4_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that we report a compile-time error when an instance field conflicts
+// with an inherited instance method of the same name.
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo = 42;  /// 00: ok
+  get foo => 42;  /// 01: ok
+  foo() => 42;  /// 02: compile-time error
+  set foo(value) { }  /// 03: ok
+}
+
+class B extends A {
+  var foo = 42;
+}
+
+main() {
+  Expect.equals(42, new B().foo);
+}
diff --git a/tests/language/getter_override2_test.dart b/tests/language/getter_override2_test.dart
new file mode 100644
index 0000000..ec162de
--- /dev/null
+++ b/tests/language/getter_override2_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that we report a compile-time error when an instance getter conflicts
+// with an inherited instance method of the same name.
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo = 42;  /// 00: ok
+  get foo => 42;  /// 01: ok
+  foo() => 42;  /// 02: compile-time error
+  set foo(value) { }  /// 03: ok
+}
+
+class B extends A {
+  get foo => 42;
+}
+
+main() {
+  Expect.equals(42, new B().foo);
+}
diff --git a/tests/language/getter_override_test.dart b/tests/language/getter_override_test.dart
new file mode 100644
index 0000000..e61ecd7
--- /dev/null
+++ b/tests/language/getter_override_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that we report a compile-time error when a static getter conflicts with
+// an inherited instance member of the same name.
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo = 42;  /// 00: compile-time error
+  get foo => 42;  /// 01: compile-time error
+  foo() => 42;  /// 02: compile-time error
+  set foo(value) { }  /// 03: static type warning
+}
+
+class B extends A {
+  static get foo => 42;
+}
+
+main() {
+  Expect.equals(42, B.foo);
+}
diff --git a/tests/language/inference_captured_variable2_test.dart b/tests/language/inference_captured_variable2_test.dart
new file mode 100644
index 0000000..ddc3162
--- /dev/null
+++ b/tests/language/inference_captured_variable2_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.
+
+// Ensure that dart2js's receiver specialization optimization works
+// with captured variables.
+
+import "package:expect/expect.dart";
+
+var list = [new Object(), 31];
+
+main() {
+  Expect.throws(() => foo()() + 42, (e) => e is NoSuchMethodError);
+}
+
+foo() {
+  var a = list[0];
+  var closure = (() => a - 42);
+  return () => a + 54;
+}
diff --git a/tests/language/inference_captured_variable_test.dart b/tests/language/inference_captured_variable_test.dart
new file mode 100644
index 0000000..cdb8931
--- /dev/null
+++ b/tests/language/inference_captured_variable_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.
+
+// Ensure that dart2js's receiver specialization optimization works
+// with captured variables.
+
+import "package:expect/expect.dart";
+
+var list = [new Object(), 31];
+
+main() {
+  Expect.throws(() => foo()() + 42, (e) => e is NoSuchMethodError);
+}
+
+foo() {
+  var a = list[0];
+  var closure = (() => a + 42);
+  if (list[1] == 0) {
+    a.toInt();
+    return closure;
+  }
+  return closure;
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index a16ddfb..cdac989 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -5,16 +5,6 @@
 # This directory contains tests that are intended to show the
 # current state of the language.
 
-# In order to maintain maximum test coverage for all builds,
-# please use the following procedure to mark a test
-# failed on architectures other than the one you are working on.
-#
-# 1) Copy the old version of the test to
-#    tests/language/src/test_name_[dartc|vm]_test.dart.
-#    to maintain coverage.
-# 2) File a bug on each architecture for the failure due to the language change.
-# 3) Update the language/src directory with the updated test.
-
 [ $compiler == dart2js && ($runtime == ie9 || $runtime == ie10) ]
 licm2_test: Skip # Issue: 12298
 
@@ -29,7 +19,6 @@
 mixin_super_constructor_positionals_test: Fail
 built_in_identifier_prefix_test: Fail # http://dartbug.com/6970
 library_juxtaposition_test: Fail # Issue 6877
-pseudo_kw_illegal_test/14: Fail  # Issue 356
 switch_int_double_test/01: Fail # Issue 7307
 switch_int_double_test/02: Fail # Issue 7307
 
@@ -42,26 +31,16 @@
 closure_in_initializer_test: Fail # Issue 6422
 
 # Regular bugs which should be fixed.
-const_init6_negative_test: Fail       # Issue 811
 super_first_constructor_test: Fail # Issue 1372.
 
 parameter_initializer6_negative_test: Fail # Issue 3502
 
 named_parameters_aggregated_test/05: Fail # Compile-time error reported instead of static type warning.
 
-lazy_static3_test: Fail # Issue 3558
-
-# DartC specific tests that should not be run by the VM
-*dartc_test: Skip
-*dartc_negative_test: Skip
-
-compile_time_constant10_test/none: Fail # issue 5214
+lazy_static3_test: Fail # Issue 12593
 
 export_cyclic_test: Fail, Crash # issue 6060
 duplicate_export_negative_test: Fail # issue 6134
-type_annotation_test/04: Fail # Issue 6970
-type_annotation_test/06: Fail # Issue 6973
-type_annotation_test/09: Fail # Issue 6973
 
 on_catch_malformed_type_test: Fail # Issue 8601
 
@@ -106,17 +85,12 @@
 
 [ $runtime == vm || ($runtime == drt && $compiler == none) ]
 first_class_types_literals_test: Fail # issue 11761
-call_test: Fail # Issue 1604
+call_test: Fail # Issue 12602
+dynamic_prefix_core_test: Fail # Issue 12478
 
 [ $runtime == chrome ]
 
 
-[ $runtime == ie9 && ($system == linux || $system == macos) ]
-*: Skip
-
-[ $runtime == safari && ($system == linux || $system == windows) ]
-*: Skip
-
 [ $browser ]
 
 
@@ -147,8 +121,6 @@
 import_core_prefix_test: Fail
 prefix16_test: Fail
 prefix22_test: Fail
-type_annotation_test/04: Fail
-type_annotation_test/06: Fail
 
 # Calling unresolved class constructor:
 call_nonexistent_constructor_test: Fail
@@ -157,6 +129,20 @@
 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
 
 # Missing compile-time error when modifying final local variables
 final_variable_assignment_test/01: Fail
@@ -205,17 +191,15 @@
 # chokes on things like typedef(x) => "typedef $x" and alike.
 abstract_syntax_test/01: Fail
 abstract_syntax_test/02: Fail
-pseudo_kw_illegal_test/14: Fail
 pseudo_kw_test: Fail
 # external keyword is not yet supported by dart2js/dart2dart.
 external_test/*: Skip
-lazy_static3_test: Fail, OK # Issue 3558
+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
-interface_factory_constructor_negative_test: Fail
 method_override4_test: Fail
 method_override5_test: Fail
 operator1_negative_test: Fail
@@ -269,8 +253,6 @@
 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
 
-compile_time_constant10_test/none: Fail # Triage this.
-
 # Only checked mode reports an error on type assignment
 # problems in compile time constants.
 compile_time_constant_checked_test/02: Fail, OK
@@ -291,6 +273,7 @@
 
 [ $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
@@ -305,6 +288,3 @@
 
 [ $compiler == dart2js ]
 null_test/none: Fail  # Issue 12482
-
-[ $compiler == dartanalyzer ]
-null_test/03: Fail  # Issue 12484
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index 9368478..34b721d 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -37,9 +37,10 @@
 number_identifier_negative_test: fail
 
 # TBF: we should check conflicts not only for methods, but for accessors too
-override_field_test/01: fail
 override_field_test/02: fail
 override_field_test/03: fail
+method_override7_test/03: Fail # Issue 11496
+method_override8_test/03: Fail # Issue 11496
 
 # TBF: prefix T hidden by type variable T in 'new T.Class()'
 prefix10_negative_test: fail
@@ -132,9 +133,6 @@
 # test issue 11581, it is not warning to call dynamic
 call_through_getter_test: fail
 
-# test issue 11582, non-final field with 'const' constructor
-compile_time_constant10_test/none: fail
-
 # test issue 11583, int is valid key for constant map literal
 compile_time_constant_c_test/01: fail
 
@@ -175,9 +173,6 @@
 # test issue 11595, It is static warning to create instance (new) of the malformed type
 instantiate_type_variable_negative_test: fail
 
-# test issue 11596. e is Unknown is not a compile time error
-is_not_class2_negative_test: fail
-
 # test issue 11598, Any use of a malbounded type gives rise to a static warning
 mixin_type_parameters_errors_test/01: fail
 mixin_type_parameters_errors_test/02: fail
@@ -205,12 +200,8 @@
 
 # test issue 11964, Any use of a malformed type gives rise to a static warning.
 prefix8_negative_test: fail
-prefix9_negative_test: fail
 prefix11_negative_test: fail
 
-# test issue 11965, 'source' is not built-in identifier anymore
-pseudo_kw_illegal_test/14: fail
-
 # test issue 12156, fails only at runtime
 static_call_wrong_argument_count_negative_test: fail
 
@@ -244,7 +235,7 @@
 # test issue 12184, It is static warning, not error, to assign to a constant variable.
 static_final_field2_negative_test: fail
 
-# test issue 12191, ambuguous import is always warning now
+# test issue 12191, ambiguous import is always warning now
 prefix3_negative_test: fail
 library_ambiguous_test/00: fail
 library_ambiguous_test/01: fail
@@ -261,6 +252,17 @@
 # test issue 12397; it is static warning, not error to use variable before declaration (or hidden)
 scope_negative_test: fail
 
+# test issue 12539, rules for finals were loosened, contradiction in spec was fixed
+const_syntax_test/09: fail
+
+# 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
+
+null_test/03: Fail  # Issue 12484
+
 [ $compiler == dartanalyzer && $checked ]
 factory1_test/00: fail
 factory1_test/01: fail
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 5acf485..6a18173 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -21,7 +21,6 @@
 
 # TBF: It is a compile-time error if the superclass of a class C appears in the implements clause of C.
 const_constructor_super_test/01: fail
-compile_time_constant10_test/none: fail
 compile_time_constant_c_test/01: fail
 
 # TBF: m([int p = 'String']) and call 'const' instance creation
@@ -182,9 +181,6 @@
 # test issue 11581, it is not warning to call dynamic
 call_through_getter_test: fail
 
-# test issue 11582, non-final field with 'const' constructor
-compile_time_constant10_test/none: fail
-
 # test issue 11583, int is valid key for constant map literal
 compile_time_constant_c_test/01: fail
 
@@ -225,9 +221,6 @@
 # test issue 11595, It is static warning to create instance (new) of the malformed type
 instantiate_type_variable_negative_test: fail
 
-# test issue 11596. e is Unknown is not a compile time error
-is_not_class2_negative_test: fail
-
 # test issue 11598, Any use of a malbounded type gives rise to a static warning
 mixin_type_parameters_errors_test/01: fail
 mixin_type_parameters_errors_test/02: fail
@@ -255,12 +248,8 @@
 
 # test issue 11964, Any use of a malformed type gives rise to a static warning.
 prefix8_negative_test: fail
-prefix9_negative_test: fail
 prefix11_negative_test: fail
 
-# test issue 11965, 'source' is not built-in identifier anymore
-pseudo_kw_illegal_test/14: fail
-
 # test issue 12156, fails only at runtime
 static_call_wrong_argument_count_negative_test: fail
 
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index f560c23..a3223eb 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -38,15 +38,14 @@
 malformed_test/06: Fail
 
 # Fails due to inlining. Not all expected frames are in the trace.
-full_stacktrace1_test: Pass, Fail  # issue 9895
-full_stacktrace2_test: Pass, Fail  # issue 9895
-full_stacktrace3_test: Pass, Fail  # issue 9895
+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.
 
 # VM specific tests that should not be run by dart2js.
 *vm_test: Skip
-*vm_negative_test: Skip
 
 [ $compiler == dart2js && $checked ]
 checked_setter2_test: Fail # dartbug.com/11273
@@ -63,7 +62,6 @@
 f_bounded_quantification_test/01: Fail
 f_bounded_quantification_test/02: Fail
 closure_type_test: Fail # does not detect type error in checked mode.
-type_annotation_test/09: Fail # Named constructors interpreted as a type.
 function_subtype_setter0_test: Fail # dartbug.com/11273
 
 [ $compiler == dart2js && $unchecked ]
@@ -92,16 +90,19 @@
 compile_time_constant_checked3_test/05: Fail, OK
 compile_time_constant_checked3_test/06: Fail, OK
 
+[ $compiler == dart2js && $minified ]
+f_bounded_quantification4_test: Fail # Issue 12605.
+
 [ $compiler == dart2js ]
 function_type_alias6_test/00: Crash # dartbug.com/9792
 function_type_alias9_test/00: Crash # dartbug.com/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 # Issues 563, 1533
+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 563: identity of NaN
+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)
@@ -117,11 +118,26 @@
 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
 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.
 
@@ -193,7 +209,6 @@
 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.
-type_dartc_test: Fail # Expect.equals(expected: <1>, actual: <0>) -- checked mode test.
 
 class_cycle_negative_test: Fail, OK # Bad test: assumes eager loading.
 external_test/16: Fail, OK # Bad test: assumes eager loading.
@@ -204,13 +219,9 @@
 #
 # The following tests are all negative tests that should be fixed.
 #
-abstract_static_negative_test: Fail # Negative language test.
 abstract_syntax_test/01: Fail # Negative language test.
 abstract_syntax_test/02: Fail # Negative language test.
 const_constructor_syntax_test/04: Fail # Negative language test.
-const_field_negative_test: Fail # Negative language test.
-const_init4_negative_test: Fail # Negative language test.
-const_init_negative_test: Fail # Negative language test.
 const_syntax_test/04: Fail # Negative language test.
 constructor2_negative_test: Fail # Negative language test.
 constructor_return_negative_test: Fail # Negative language test.
@@ -224,15 +235,10 @@
 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.
-interface_factory3_negative_test: Fail # Negative language test.
-interface_factory_constructor_negative_test: Fail # Negative language test.
 list_literal1_negative_test: Fail # Negative language test.
 map_literal1_negative_test: Fail # Negative language test.
 number_identifier_negative_test: Fail # Negative language test.
 operator1_negative_test: Fail # Negative language test.
-prefix23_negative_test: Fail # Negative language test.
-pseudo_kw_illegal_test/03: Fail # Negative language test.
-pseudo_kw_illegal_test/14: Fail # Negative language test.
 scope_negative_test: Fail # Negative language test.
 static_final_field_negative_test: Fail # Negative language test.
 static_top_level_test/00: Fail # Negative language test.
@@ -243,7 +249,6 @@
 static_top_level_test/05: Fail # Negative language test.
 static_top_level_test/06: Fail # Negative language test.
 static_top_level_test/07: Fail # Negative language test.
-string_interpolation7_negative_test: Fail # Negative language test.
 throw7_negative_test: Fail # Negative language test.
 
 numbers_test: Fail, OK # (unintended?) VM specific test.
@@ -292,8 +297,6 @@
 
 
 [ $compiler == dart2js && $runtime == safari ]
-null_pointer_exception_test: Fail # Uncaught error: Instance of 'TypeError'
-string_interpolate_npe_test: Fail # Uncaught error: Instance of 'TypeError'
 arithmetic_test: Fail # Issue: 7414
 
 
@@ -304,9 +307,7 @@
 closure3_test: Fail
 execute_finally3_test: Fail
 method_invocation_test: Fail
-null_pointer_exception_test: Fail
 stack_overflow_test: Fail
 stack_overflow_stacktrace_test: Fail
-string_interpolate_npe_test: Fail
 closure_call_wrong_argument_count_negative_test: Skip
 label_test: Skip
diff --git a/tests/language/method_override7_test.dart b/tests/language/method_override7_test.dart
new file mode 100644
index 0000000..5290609
--- /dev/null
+++ b/tests/language/method_override7_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that we report a compile-time error when a static function conflicts
+// with an inherited instance member of the same name.
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo = 42;  /// 00: compile-time error
+  get foo => 42;  /// 01: compile-time error
+  foo() => 42;  /// 02: compile-time error
+  set foo(value) { }  /// 03: static type warning
+}
+
+class B extends A {
+  static foo() => 42;
+}
+
+main() {
+  Expect.equals(42, B.foo());
+}
diff --git a/tests/language/method_override8_test.dart b/tests/language/method_override8_test.dart
new file mode 100644
index 0000000..4255160
--- /dev/null
+++ b/tests/language/method_override8_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that we report a compile-time error when an instance method conflicts
+// with an inherited instance field or getter of the same name.
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo = 42;  /// 00: compile-time error
+  get foo => 42;  /// 01: compile-time error
+  foo() => 42;  /// 02: ok
+  set foo(value) { }  /// 03: static type warning
+}
+
+class B extends A {
+  foo() => 42;
+}
+
+main() {
+  Expect.equals(42, new B().foo());
+}
diff --git a/tests/language/pseudo_kw_illegal_test.dart b/tests/language/pseudo_kw_illegal_test.dart
index fcaf3c5..32d8041 100644
--- a/tests/language/pseudo_kw_illegal_test.dart
+++ b/tests/language/pseudo_kw_illegal_test.dart
@@ -16,7 +16,6 @@
 class operator { }    /// 12: compile-time error
 class part { }        /// 18: compile-time error
 class set { }         /// 13: compile-time error
-class source { }      /// 14: compile-time error
 class static { }      /// 15: compile-time error
 class typedef { }     /// 16: compile-time error
 
diff --git a/tests/language/refine_receiver_null_test.dart b/tests/language/refine_receiver_null_test.dart
new file mode 100644
index 0000000..c65afa8
--- /dev/null
+++ b/tests/language/refine_receiver_null_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to infer that code following
+// a dynamic call could assume the receiver is not null. This does not
+// work for Object methods.
+
+import "package:expect/expect.dart";
+import "compiler_annotations.dart";
+
+main() {
+  var a = true ? null : 42;
+  a.toString();
+  foo(a);
+}
+
+@DontInline()
+foo(a) {
+  var f = () => 42;
+  Expect.throws(() => a + 42, (e) => e is NoSuchMethodError);
+}
diff --git a/tests/language/setter_override2_test.dart b/tests/language/setter_override2_test.dart
new file mode 100644
index 0000000..e5ac9d0
--- /dev/null
+++ b/tests/language/setter_override2_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 that we do not report a compile-time error when an instance setter named
+// foo= is declared in a class inheriting an instance method, field, or getter
+// named foo, or an instance setter named foo=.
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo = 42;  /// 00: ok
+  get foo => 42;  /// 01: ok
+  foo() => 42;  /// 02: ok
+  set foo(value) { }  /// 03: ok
+}
+
+class B extends A {
+  var foo_;
+  set foo(value) { foo_ = value; }
+}
+
+main() {
+  var b = new B();
+  b.foo = 42;
+  Expect.equals(42, b.foo_);
+}
diff --git a/tests/language/setter_override_test.dart b/tests/language/setter_override_test.dart
new file mode 100644
index 0000000..577fbc1
--- /dev/null
+++ b/tests/language/setter_override_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 that we do not report a compile-time error when a static setter named
+// foo= is declared in a class inheriting an instance method or getter named
+// foo, and that we do report an error if an instance setter named foo= or
+// instance field name foo is inherited.
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo = 42;  /// 00: compile-time error
+  get foo => 42;  /// 01: static type warning
+  foo() => 42;  /// 02: static type warning
+  set foo(value) { }  /// 03: compile-time error
+}
+
+class B extends A {
+  static var foo_;
+  static set foo(value) { foo_ = value; }
+}
+
+main() {
+  B.foo = 42;
+  Expect.equals(42, B.foo_);
+}
diff --git a/tests/lib/analyzer/analyze_tests.status b/tests/lib/analyzer/analyze_tests.status
index de9d41a..b1e51479 100644
--- a/tests/lib/analyzer/analyze_tests.status
+++ b/tests/lib/analyzer/analyze_tests.status
@@ -2,13 +2,18 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+# The testing infrastructure is using the dart:io Path and LineTransformer
+# classes.
+standalone/io/skipping_dart2js_compilations_test: Skip # http/dartbug.com/12449
+standalone/io/dependency_graph_test: Skip # http/dartbug.com/12449
+standalone/io/status_file_parser_test: Skip # http/dartbug.com/12449
+
 [ $compiler == dartanalyzer ]
 javascript_int_overflow_literal_test/01: fail, ok
 
 # https://code.google.com/p/dart/issues/detail?id=11665
 standalone/io/directory_invalid_arguments_test: fail
 standalone/io/file_constructor_test: fail
-standalone/io/file_fuzz_test: fail
 standalone/io/http_cookie_date_test: fail
 standalone/io/http_headers_test: fail
 standalone/io/http_parser_test: fail
diff --git a/tests/lib/convert/unicode_tests.dart b/tests/lib/convert/unicode_tests.dart
index 1f90b7b..52a7b09 100644
--- a/tests/lib/convert/unicode_tests.dart
+++ b/tests/lib/convert/unicode_tests.dart
@@ -45,6 +45,24 @@
                             0x79, 0x7A ];
 const ASCII_STRING = "abcdefghijklmnopqrstuvwxyz";
 
+const BIGGEST_ASCII_BYTES = const [ 0x7F ];
+const BIGGEST_ASCII_STRING = "\x7F";
+
+const SMALLEST_2_UTF8_UNIT_BYTES = const [ 0xC2, 0x80 ];
+const SMALLEST_2_UTF8_UNIT_STRING = "\u{80}";
+
+const BIGGEST_2_UTF8_UNIT_BYTES = const [ 0xDF, 0xBF ];
+const BIGGEST_2_UTF8_UNIT_STRING = "\u{7FF}";
+
+const SMALLEST_3_UTF8_UNIT_BYTES = const [ 0xE0, 0xA0, 0x80 ];
+const SMALLEST_3_UTF8_UNIT_STRING = "\u{800}";
+
+const BIGGEST_3_UTF8_UNIT_BYTES = const [ 0xEF, 0xBF, 0xBF ];
+const BIGGEST_3_UTF8_UNIT_STRING = "\u{FFFF}";
+
+const SMALLEST_4_UTF8_UNIT_BYTES = const [ 0xF0, 0x90, 0x80, 0x80 ];
+const SMALLEST_4_UTF8_UNIT_STRING = "\u{10000}";
+
 const _TEST_PAIRS = const [
     const [ const [], "" ],
     const [ INTER_BYTES, INTER_STRING ],
@@ -53,7 +71,14 @@
     const [ SIVA_BYTES2, SIVA_STRING2 ],
     const [ BEE_BYTES, BEE_STRING ],
     const [ DIGIT_BYTES, DIGIT_STRING ],
-    const [ ASCII_BYTES, ASCII_STRING ]];
+    const [ ASCII_BYTES, ASCII_STRING ],
+    const [ BIGGEST_ASCII_BYTES, BIGGEST_ASCII_STRING ],
+    const [ SMALLEST_2_UTF8_UNIT_BYTES, SMALLEST_2_UTF8_UNIT_STRING ],
+    const [ BIGGEST_2_UTF8_UNIT_BYTES, BIGGEST_2_UTF8_UNIT_STRING ],
+    const [ SMALLEST_3_UTF8_UNIT_BYTES, SMALLEST_3_UTF8_UNIT_STRING ],
+    const [ BIGGEST_3_UTF8_UNIT_BYTES, BIGGEST_3_UTF8_UNIT_STRING ],
+    const [ SMALLEST_4_UTF8_UNIT_BYTES, SMALLEST_4_UTF8_UNIT_STRING ],
+    ];
 
 List<List> _expandTestPairs() {
   assert(2 == BEE_STRING.length);
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 97c4189..49dda71 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -2,12 +2,14 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $compiler == dart2js && ($runtime == d8 || $runtime == drt) ]
+[ $compiler == dart2js && $runtime == drt ]
 convert/chunked_conversion_utf87_test: Pass, Fail # v8 bug: Issue 12293
 typed_data/byte_data_test: Pass, Fail # v8 bug: Issue 12293
 
 [ $compiler == dart2js ]
-math/*: Skip
+math/double_pow_test: Fail
+math/low_test: Fail
+math/random_test: Fail
 mirrors/invoke_test: Fail # Issue 11954
 mirrors/class_mirror_type_variables_test: Fail # Issue 12087
 mirrors/invoke_private_test: Fail # Issue 12164
@@ -21,6 +23,7 @@
 mirrors/null_test : Fail # Issue 12129
 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/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
@@ -28,12 +31,13 @@
 async/stream_controller_async_test: Fail, Pass # http://dartbug.com/11953
 
 
-[ $compiler == dart2js && ($runtime == d8) ]
-typed_data/byte_data_test: Fail, OK # d8 doesn't support DataView
-
 [ $csp ]
 mirrors/*: Skip # Issue 6490
 
+[ $compiler == dart2js && $runtime != jsshell && $runtime != safari && $runtime != ff && $runtime != ie9 && $runtime != ie10]
+math/math_test: Fail
+math/math2_test: Fail
+
 [ $compiler == dart2js && $jscl ]
 async/future_test: Fail # Timer interface not supported; dartbug.com/7728.
 async/slow_consumer2_test: Fail # Timer interface not supported; dartbug.com/7728.
@@ -82,7 +86,10 @@
 [ $runtime == ie9 ]
 # IE9 doesn't support typed arrays.
 typed_data/*: Fail # Issue 11971
-convert/chunked_conversion_utf88_test: Pass, Slow  # Issue 12029
+convert/chunked_conversion_utf88_test: Pass, Slow, Timeout  # Issue 12029
+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
 
 [ $runtime == opera ]
 async/multiple_timer_test: Pass, Fail
@@ -99,7 +106,6 @@
 
 [ $runtime == vm || ($compiler == none && $runtime == drt) ]
 async/run_async3_test: Fail # _enqueueImmediate runs after Timer. http://dartbug.com/9001.
-mirrors/operator_test: Fail # http://dartbug.com/11944
 mirrors/mixin_test: Fail # TODO(ahe): This test is slightly broken. http://dartbug.com/12464
 mirrors/hierarchy_test: Fail # TODO(ahe): This test is slightly broken. http://dartbug.com/12464
 
@@ -118,3 +124,7 @@
 [ $arch == simmips || $arch == mips ]
 convert/chunked_conversion_utf88_test: Pass, Slow # Issue 12025.
 convert/streamed_conversion_json_utf8_decode_test: Pass, Slow
+
+[ $arch == simarm || $arch == arm ]
+typed_data/uint32x4_arithmetic_test: Crash # Unimplemented
+
diff --git a/tests/lib/math/double_pow_test.dart b/tests/lib/math/double_pow_test.dart
new file mode 100644
index 0000000..c3ce04c
--- /dev/null
+++ b/tests/lib/math/double_pow_test.dart
@@ -0,0 +1,158 @@
+// 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 math_test;
+import "package:expect/expect.dart";
+import 'dart:math';
+
+void checkVeryClose(double a, double b) {
+  // We find a ulp (unit in the last place) by shifting the original number
+  // to the right. This only works if we are not too close to infinity or if
+  // we work with denormals.
+  // We special case or 0.0, but not for infinity.
+  if (a == 0.0) {
+    final minimalDouble = 4.9406564584124654e-324;
+    Expect.equals(true, b.abs() <= minimalDouble);
+    return;
+  }
+  if (b == 0.0) {
+    // No need to look if they are close. Otherwise the check for 'a' above
+    // whould have triggered.
+    Expect.equals(a, b);
+  }
+  final double shiftRightBy52 = 2.220446049250313080847263336181640625e-16;
+  final double shiftedA = (a * shiftRightBy52).abs();
+  // Compared to 'a', 'shiftedA' is now ~1-2 ulp.
+
+  final double limitLow = a - shiftedA;
+  final double limitHigh = a + shiftedA;
+  Expect.equals(false, a == limitLow);
+  Expect.equals(false, a == limitHigh);
+  Expect.equals(true, limitLow <= b);
+  Expect.equals(true, b <= limitHigh);
+}
+
+const NaN = double.NAN;
+const Infinity = double.INFINITY;
+
+var samples = [
+  NaN,
+  -Infinity,
+  -3.0,  // Odd integer
+  -2.0,  // Even integer
+  -1.5,  // Non-integer, magnitude > 1
+  -1.0,  // Unit
+  -0.5,  // Non-integer, magnitude < 1.
+  -0.0,
+  0.5,  // Non-integer, magnitude < 1.
+  1.0,  // Unit
+  1.5,  // Non-integer, magnitude > 1
+  2.0,  // Even integer
+  3.0,  // Odd integer
+  Infinity
+];
+
+main() {
+  // Tests of pow(x, y):
+  for (var d in samples) {
+    // if `y` is zero (0.0 or -0.0), the result is always 1.0.
+    Expect.identical(1.0, pow(d, 0.0), "$d");
+    Expect.identical(1.0, pow(d, -0.0), "$d");
+  }
+  for (var d in samples) {
+    // if `x` is 1.0, the result is always 1.0.
+    Expect.identical(1.0, pow(1.0, d), "$d");
+  }
+  for (var d in samples) {
+    // otherwise, if either `x` or `y` is NaN then the result is NaN.
+    if (d != 0.0) Expect.identical(NaN, pow(NaN, d), "$d");
+    if (d != 1.0) Expect.identical(NaN, pow(d, NaN), "$d");
+  }
+
+  for (var d in samples) {
+    // if `x` is a finite and strictly negative and `y` is a finite non-integer,
+    // the result is NaN.
+    if (d < 0 && !d.isInfinite) {
+      Expect.identical(NaN, pow(d, 0.5), "$d");
+      Expect.identical(NaN, pow(d, -0.5), "$d");
+      Expect.identical(NaN, pow(d, 1.5), "$d");
+      Expect.identical(NaN, pow(d, -1.5), "$d");
+    }
+  }
+
+  for (var d in samples) {
+    if (d < 0) {
+      // if `x` is Infinity and `y` is strictly negative, the result is 0.0.
+      Expect.identical(0.0, pow(Infinity, d), "$d");
+    }
+    if (d > 0) {
+      // if `x` is Infinity and `y` is strictly positive, the result is Infinity.
+      Expect.identical(Infinity, pow(Infinity, d), "$d");
+    }
+  }
+
+  for (var d in samples) {
+    if (d < 0) {
+      // if `x` is 0.0 and `y` is strictly negative, the result is Infinity.
+      Expect.identical(Infinity, pow(0.0, d), "$d");
+    }
+    if (d > 0) {
+      // if `x` is 0.0 and `y` is strictly positive, the result is 0.0.
+      Expect.identical(0.0, pow(0.0, d), "$d");
+    }
+  }
+
+  for (var d in samples) {
+    if (!d.isInfinite && !d.isNaN) {
+      var dint = d.toInt();
+      if (d == dint && dint.isOdd) {
+        // if `x` is -Infinity or -0.0 and `y` is an odd integer, then the
+        // result is`-pow(-x ,y)`.
+        Expect.identical(-pow(Infinity, d), pow(-Infinity, d));
+        Expect.identical(-pow(0.0, d), pow(-0.0, d));
+        continue;
+      }
+    }
+    // if `x` is -Infinity or -0.0 and `y` is not an odd integer, then the
+    // result is the same as `pow(-x , y)`.
+    Expect.identical(pow(Infinity, d), pow(-Infinity, d));
+    Expect.identical(pow(0.0, d), pow(-0.0, d));
+  }
+
+  for (var d in samples) {
+
+    if (d.abs() < 1) {
+      // if `y` is Infinity and the absolute value of `x` is less than 1, the
+      // result is 0.0.
+      Expect.identical(0.0, pow(d, Infinity));
+    } else if (d.abs() > 1) {
+      // if `y` is Infinity and the absolute value of `x` is greater than 1,
+      // the result is Infinity.
+      Expect.identical(Infinity, pow(d, Infinity));
+    } else if (d == -1) {
+      // if `y` is Infinity and `x` is -1, the result is 1.0.
+      Expect.identical(1.0, pow(d, Infinity));
+    }
+    // if `y` is -Infinity, the result is `1/pow(x, Infinity)`.
+    Expect.identical(1/pow(d, Infinity), pow(d, -Infinity));
+  }
+
+  // Some non-exceptional values.
+  checkVeryClose(16.0, pow(4.0, 2.0));
+  checkVeryClose(SQRT2, pow(2.0, 0.5));
+  checkVeryClose(SQRT1_2, pow(0.5, 0.5));
+  // Denormal result.
+  Expect.identical(5e-324, pow(2.0, -1074.0));
+  // Overflow.
+  Expect.identical(Infinity, pow(10.0, 309.0));
+  // Underflow.
+  Expect.identical(0.0, pow(10.0, -325.0));
+
+  // Conversion to double.
+
+  // The second argument is an odd integer as int, but not when converted
+  // to double.
+  Expect.identical(Infinity, pow(-0.0, -9223372036854775809));
+}
+
diff --git a/tests/lib/math/math_test.dart b/tests/lib/math/math_test.dart
index 04a5022..b911e0a 100644
--- a/tests/lib/math/math_test.dart
+++ b/tests/lib/math/math_test.dart
@@ -146,12 +146,6 @@
     checkVeryClose(LN2, log(2.0));
   }
 
-  static void testPow() {
-    checkVeryClose(16.0, pow(4.0, 2.0));
-    checkVeryClose(SQRT2, pow(2.0, 0.5));
-    checkVeryClose(SQRT1_2, pow(0.5, 0.5));
-  }
-
   static bool parseIntThrowsFormatException(str) {
     try {
       int.parse(str);
@@ -251,7 +245,6 @@
     testSqrt();
     testLog();
     testExp();
-    testPow();
     testParseInt();
   }
 }
diff --git a/tests/lib/mirrors/reflected_type_test.dart b/tests/lib/mirrors/reflected_type_test.dart
new file mode 100644
index 0000000..df4e578
--- /dev/null
+++ b/tests/lib/mirrors/reflected_type_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 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 test.reflected_type_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+class A<T> {}
+class B extends A {}            // Same as class B extends A<dynamic>.
+class C extends A<num, int> {}  // Same as class C extends A<dynamic>.
+class D extends A<int> {}
+class E<S> extends A<S> {}
+class F<R> extends A<int> {}
+class G {}
+class H<A,B,C> {}
+
+expectReflectedType(classMirror, expectedType) {
+  if (expectedType == null) {
+    Expect.isFalse(classMirror.hasReflectedType);
+    Expect.throws(() => classMirror.reflectedType,
+                  (e) => e is UnsupportedError,
+                  "Should not have a reflected type");
+  } else {
+    Expect.isTrue(classMirror.hasReflectedType);
+    Expect.equals(expectedType, classMirror.reflectedType);
+  }
+}
+
+main() {
+  // Declarations.
+  expectReflectedType(reflectClass(A), null);
+  expectReflectedType(reflectClass(B), B);
+  expectReflectedType(reflectClass(C), C);
+  expectReflectedType(reflectClass(D), D);
+  expectReflectedType(reflectClass(E), null);
+  expectReflectedType(reflectClass(F), null);
+  expectReflectedType(reflectClass(G), G);
+  expectReflectedType(reflectClass(H), null);
+
+   // Instantiations.
+  expectReflectedType(reflect(new A()).type, new A().runtimeType);
+  expectReflectedType(reflect(new B()).type, new B().runtimeType);
+  expectReflectedType(reflect(new C()).type, new C().runtimeType);
+  expectReflectedType(reflect(new D()).type, new D().runtimeType);
+  expectReflectedType(reflect(new E()).type, new E().runtimeType);
+  expectReflectedType(reflect(new F()).type, new F().runtimeType);
+  expectReflectedType(reflect(new G()).type, new G().runtimeType);
+  expectReflectedType(reflect(new H()).type, new H().runtimeType);
+
+  expectReflectedType(reflect(new A<num>()).type, new A<num>().runtimeType);
+  expectReflectedType(reflect(new B<num>()).type.superclass,
+                      new A<dynamic>().runtimeType);
+  expectReflectedType(reflect(new C<num>()).type.superclass,
+                      new A<dynamic>().runtimeType);
+  expectReflectedType(reflect(new D<num>()).type.superclass,
+                      new A<int>().runtimeType);
+  expectReflectedType(reflect(new E<num>()).type, new E<num>().runtimeType);
+  // TODO(rmacnak): This requires some work to compute.
+  // expectReflectedType(reflect(new E<num>()).type.superclass,
+  //                     new A<num>().runtimeType);
+  expectReflectedType(reflect(new F<num>()).type.superclass,
+                      new A<int>().runtimeType);
+  expectReflectedType(reflect(new F<num>()).type, new F<num>().runtimeType);
+  expectReflectedType(reflect(new H<num, num, num>()).type,
+                      new H<num, num, num>().runtimeType);
+}
diff --git a/tests/lib/typed_data/float32x4_sign_mask_test.dart b/tests/lib/typed_data/float32x4_sign_mask_test.dart
new file mode 100644
index 0000000..95825d4
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_sign_mask_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10
+
+// Library tag to be able to run in html test framework.
+library float32x4_sign_mask;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+void testImmediates() {
+  var f = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var m = f.signMask;
+  Expect.equals(0x0, m);
+  f = new Float32x4(-1.0, -2.0, -3.0, -0.0);
+  m = f.signMask;
+  Expect.equals(0xf, m);
+  f = new Float32x4(-1.0, 2.0, 3.0, 4.0);
+  m = f.signMask;
+  Expect.equals(0x1, m);
+  f = new Float32x4(1.0, -2.0, 3.0, 4.0);
+  m = f.signMask;
+  Expect.equals(0x2, m);
+  f = new Float32x4(1.0, 2.0, -3.0, 4.0);
+  m = f.signMask;
+  Expect.equals(0x4, m);
+  f = new Float32x4(1.0, 2.0, 3.0, -4.0);
+  m = f.signMask;
+  Expect.equals(0x8, m);
+}
+
+void testZero() {
+  var f = new Float32x4(0.0, 0.0, 0.0, 0.0);
+  var m = f.signMask;
+  Expect.equals(0x0, m);
+  f = new Float32x4(-0.0, -0.0, -0.0, -0.0);
+  m = f.signMask;
+  Expect.equals(0xf, m);
+}
+
+void testArithmetic() {
+  var a = new Float32x4(1.0, 1.0, 1.0, 1.0);
+  var b = new Float32x4(2.0, 2.0, 2.0, 2.0);
+  var c = new Float32x4(-1.0, -1.0, -1.0, -1.0);
+  var m1 = (a - b).signMask;
+  Expect.equals(0xf, m1);
+  var m2 = (b - a).signMask;
+  Expect.equals(0x0, m2);
+  var m3 = (c * c).signMask;
+  Expect.equals(0x0, m3);
+  var m4 = (a * c).signMask;
+  Expect.equals(0xf, m4);
+}
+
+main() {
+  for (int i = 0; i < 2000; i++) {
+    testImmediates();
+    testZero();
+    testArithmetic();
+  }
+}
diff --git a/tests/lib/typed_data/uint32x4_arithmetic_test.dart b/tests/lib/typed_data/uint32x4_arithmetic_test.dart
new file mode 100644
index 0000000..a702082
--- /dev/null
+++ b/tests/lib/typed_data/uint32x4_arithmetic_test.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--deoptimization_counter_threshold=1000 --optimization-counter-threshold=10
+
+// Library tag to be able to run in html test framework.
+library uint32x4_arithmetic_test;
+
+import "package:expect/expect.dart";
+import 'dart:typed_data';
+
+testAdd() {
+  var m = new Uint32x4(0, 0, 0, 0);
+  var n = new Uint32x4(-1, -1, -1, -1);
+  var o = m + n;
+  Expect.equals(4294967295, o.x);
+  Expect.equals(4294967295, o.y);
+  Expect.equals(4294967295, o.z);
+  Expect.equals(4294967295, o.w);
+
+  m = new Uint32x4(0, 0, 0, 0);
+  n = new Uint32x4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+  o = m + n;
+  Expect.equals(4294967295, o.x);
+  Expect.equals(4294967295, o.y);
+  Expect.equals(4294967295, o.z);
+  Expect.equals(4294967295, o.w);
+
+  n = new Uint32x4(1, 1, 1, 1);
+  m = new Uint32x4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+  o = m + n;
+  Expect.equals(0, o.x);
+  Expect.equals(0, o.y);
+  Expect.equals(0, o.z);
+  Expect.equals(0, o.w);
+
+  n = new Uint32x4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+  m = new Uint32x4(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+  o = m + n;
+  Expect.equals(4294967294, o.x);
+  Expect.equals(4294967294, o.y);
+  Expect.equals(4294967294, o.z);
+  Expect.equals(4294967294, o.w);
+
+  n = new Uint32x4(1, 0, 0, 0);
+  m = new Uint32x4(2, 0, 0, 0);
+  o = n + m;
+  Expect.equals(3, o.x);
+  Expect.equals(0, o.y);
+  Expect.equals(0, o.z);
+  Expect.equals(0, o.w);
+
+  n = new Uint32x4(1, 3, 0, 0);
+  m = new Uint32x4(2, 4, 0, 0);
+  o = n + m;
+  Expect.equals(3, o.x);
+  Expect.equals(7, o.y);
+  Expect.equals(0, o.z);
+  Expect.equals(0, o.w);
+
+  n = new Uint32x4(1, 3, 5, 0);
+  m = new Uint32x4(2, 4, 6, 0);
+  o = n + m;
+  Expect.equals(3, o.x);
+  Expect.equals(7, o.y);
+  Expect.equals(11, o.z);
+  Expect.equals(0, o.w);
+
+  n = new Uint32x4(1, 3, 5, 7);
+  m = new Uint32x4(2, 4, 6, 8);
+  o = n + m;
+  Expect.equals(3, o.x);
+  Expect.equals(7, o.y);
+  Expect.equals(11, o.z);
+  Expect.equals(15, o.w);
+}
+
+testSub() {
+  var m = new Uint32x4(0, 0, 0, 0);
+  var n = new Uint32x4(1, 1, 1, 1);
+  var o = m - n;
+  Expect.equals(4294967295, o.x);
+  Expect.equals(4294967295, o.y);
+  Expect.equals(4294967295, o.z);
+  Expect.equals(4294967295, o.w);
+
+  o = n - m;
+  Expect.equals(1, o.x);
+  Expect.equals(1, o.y);
+  Expect.equals(1, o.z);
+  Expect.equals(1, o.w);
+}
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    testAdd();
+    testSub();
+  }
+}
diff --git a/tests/lib/typed_data/uint32x4_sign_mask_test.dart b/tests/lib/typed_data/uint32x4_sign_mask_test.dart
new file mode 100644
index 0000000..052d0bf
--- /dev/null
+++ b/tests/lib/typed_data/uint32x4_sign_mask_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10
+
+// Library tag to be able to run in html test framework.
+library uint32x4_sign_mask;
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+void testImmediates() {
+  var f = new Uint32x4(1, 2, 3, 4);
+  var m = f.signMask;
+  Expect.equals(0x0, m);
+  f = new Uint32x4(-1, -2, -3, -4);
+  m = f.signMask;
+  Expect.equals(0xf, m);
+  f = new Uint32x4.bool(true, false, false, false);
+  m = f.signMask;
+  Expect.equals(0x1, m);
+  f = new Uint32x4.bool(false, true, false, false);
+  m = f.signMask;
+  Expect.equals(0x2, m);
+  f = new Uint32x4.bool(false, false, true, false);
+  m = f.signMask;
+  Expect.equals(0x4, m);
+  f = new Uint32x4.bool(false, false, false, true);
+  m = f.signMask;
+  Expect.equals(0x8, m);
+}
+
+void testZero() {
+  var f = new Uint32x4(0, 0, 0, 0);
+  var m = f.signMask;
+  Expect.equals(0x0, m);
+  f = new Uint32x4(-0, -0, -0, -0);
+  m = f.signMask;
+  Expect.equals(0x0, m);
+}
+
+void testLogic() {
+  var a = new Uint32x4(0x80000000, 0x80000000, 0x80000000, 0x80000000);
+  var b = new Uint32x4(0x70000000, 0x70000000, 0x70000000, 0x70000000);
+  var c = new Uint32x4(0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000);
+  var m1 = (a & c).signMask;
+  Expect.equals(0xf, m1);
+  var m2 = (a & b).signMask;
+  Expect.equals(0x0, m2);
+  var m3 = (b ^ a).signMask;
+  Expect.equals(0xf, m3);
+  var m4 = (b | c).signMask;
+  Expect.equals(0xf, m4);
+}
+
+main() {
+  for (int i = 0; i < 2000; i++) {
+    testImmediates();
+    testZero();
+    testLogic();
+  }
+}
diff --git a/tests/standalone/coverage_test.dart b/tests/standalone/coverage_test.dart
index ef5e42d..ecf92ea 100644
--- a/tests/standalone/coverage_test.dart
+++ b/tests/standalone/coverage_test.dart
@@ -7,8 +7,10 @@
 // This test is mainly here to ensure that the coverage tool compiles and
 // runs.
 
-import "dart:io";
 import "dart:async";
+import "dart:convert";
+import "dart:io";
+
 import "package:path/path.dart";
 
 // Coverage tool script relative to the path of this test.
@@ -64,11 +66,11 @@
     coverageToolProcess.stdin.close();
     var stdoutStringStream = coverageToolProcess.stdout
         .transform(new StringDecoder())
-        .transform(new LineTransformer());
+        .transform(new LineSplitter());
 
     var stderrStringStream = coverageToolProcess.stderr
         .transform(new StringDecoder())
-        .transform(new LineTransformer());
+        .transform(new LineSplitter());
 
     // Wait for 3 future events: stdout and stderr streams of the coverage
     // tool process closed, and coverage tool process terminated.
diff --git a/tests/standalone/debugger/debug_lib.dart b/tests/standalone/debugger/debug_lib.dart
index 79161c7..7be6854 100644
--- a/tests/standalone/debugger/debug_lib.dart
+++ b/tests/standalone/debugger/debug_lib.dart
@@ -7,6 +7,7 @@
 library DartDebugger;
 
 import "dart:async";
+import "dart:convert";
 import "dart:io";
 import "dart:math";
 import "dart:utf";
@@ -393,7 +394,7 @@
   Debugger(this.targetProcess, this.script) {
     var stdoutStringStream = targetProcess.stdout
         .transform(new StringDecoder())
-        .transform(new LineTransformer());
+        .transform(new LineSplitter());
     stdoutStringStream.listen((line) {
       print("TARG: $line");
       if (line.startsWith("Debugger listening")) {
@@ -406,7 +407,7 @@
 
     var stderrStringStream = targetProcess.stderr
         .transform(new StringDecoder())
-        .transform(new LineTransformer());
+        .transform(new LineSplitter());
     stderrStringStream.listen((line) {
       print("TARG: $line");
     });
diff --git a/tests/standalone/io/file_input_stream_test.dart b/tests/standalone/io/file_input_stream_test.dart
index d57c014..021e19e 100644
--- a/tests/standalone/io/file_input_stream_test.dart
+++ b/tests/standalone/io/file_input_stream_test.dart
@@ -3,23 +3,25 @@
 // BSD-style license that can be found in the LICENSE file.
 // Testing file input stream, VM-only, standalone test.
 
-import "package:expect/expect.dart";
+import "dart:convert";
 import "dart:io";
 import "dart:isolate";
 
+import "package:expect/expect.dart";
+
 // Helper method to be able to run the test from the runtime
 // directory, or the top directory.
 String getFilename(String path) =>
     new File(path).existsSync() ? path : '../$path';
 
-void testStringLineTransformer() {
+void testStringLineSplitter() {
   String fileName = getFilename("tests/standalone/io/readuntil_test.dat");
   // File contains "Hello Dart\nwassup!\n"
   File file = new File(fileName);
   int linesRead = 0;
   var lineStream = file.openRead()
     .transform(new StringDecoder())
-    .transform(new LineTransformer());
+    .transform(new LineSplitter());
   lineStream.listen((line) {
     linesRead++;
     if (linesRead == 1) {
@@ -224,14 +226,14 @@
 }
 
 
-void testStringLineTransformerEnding(String name, int length) {
+void testStringLineSplitterEnding(String name, int length) {
   String fileName = getFilename("tests/standalone/io/$name");
   // File contains 10 lines.
   File file = new File(fileName);
   Expect.equals(length, file.openSync().lengthSync());
   var lineStream = file.openRead()
     .transform(new StringDecoder())
-    .transform(new LineTransformer());
+    .transform(new LineSplitter());
   int lineCount = 0;
   lineStream.listen(
       (line) {
@@ -248,7 +250,7 @@
 
 
 main() {
-  testStringLineTransformer();
+  testStringLineSplitter();
   testOpenStreamAsync();
   testInputStreamTruncate();
   testInputStreamDelete();
@@ -258,6 +260,6 @@
   // Check the length of these files as both are text files where one
   // is without a terminating line separator which can easily be added
   // back if accidentally opened in a text editor.
-  testStringLineTransformerEnding("readline_test1.dat", 111);
-  testStringLineTransformerEnding("readline_test2.dat", 114);
+  testStringLineSplitterEnding("readline_test1.dat", 111);
+  testStringLineSplitterEnding("readline_test2.dat", 114);
 }
diff --git a/tests/standalone/io/http_server_idle_timeout_test.dart b/tests/standalone/io/http_server_idle_timeout_test.dart
new file mode 100644
index 0000000..5673bfc
--- /dev/null
+++ b/tests/standalone/io/http_server_idle_timeout_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// VMOptions=
+// VMOptions=--short_socket_read
+// VMOptions=--short_socket_write
+// VMOptions=--short_socket_read --short_socket_write
+
+import "dart:async";
+import "dart:io";
+import "dart:isolate";
+
+
+void testTimeoutAfterRequest() {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
+    server.idleTimeout = null;
+
+    server.listen((request) {
+      server.idleTimeout = const Duration(milliseconds: 100);
+      request.response.close();
+    });
+
+    Socket.connect("127.0.0.1", server.port).then((socket) {
+      var data = "GET / HTTP/1.1\r\nContent-Length: 0\r\n\r\n";
+      socket.write(data);
+      socket.listen(
+          null,
+          onDone: () {
+            socket.close();
+            server.close();
+          });
+    });
+  });
+}
+
+void testTimeoutBeforeRequest() {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
+    server.idleTimeout = const Duration(milliseconds: 100);
+
+    server.listen((request) => request.response.close());
+
+    Socket.connect("127.0.0.1", server.port).then((socket) {
+      socket.listen(
+          null,
+          onDone: () {
+            socket.close();
+            server.close();
+          });
+    });
+  });
+}
+
+void main() {
+  testTimeoutAfterRequest();
+  testTimeoutBeforeRequest();
+}
diff --git a/tests/standalone/io/platform_test.dart b/tests/standalone/io/platform_test.dart
index 1677e67a..1fdad2b 100644
--- a/tests/standalone/io/platform_test.dart
+++ b/tests/standalone/io/platform_test.dart
@@ -25,6 +25,11 @@
   Expect.isTrue(Platform.executable.contains('dart'));
   Expect.isTrue(Platform.script.replaceAll('\\', '/').
                 endsWith('tests/standalone/io/platform_test.dart'));
+  Directory packageRoot = new Directory(Platform.packageRoot);
+  Expect.isTrue(packageRoot.existsSync());
+  Expect.isTrue(new Directory("${packageRoot.path}/expect").existsSync());
+  Expect.isTrue(Platform.executableArguments.any(
+      (arg) => arg.contains(Platform.packageRoot)));
 }
 
 void f() {
@@ -35,6 +40,12 @@
     if (msg == "Platform.script") {
       reply.send(Platform.script);
     }
+    if (msg == "Platform.packageRoot") {
+      reply.send(Platform.packageRoot);
+    }
+    if (msg == "Platform.executableArguments") {
+      reply.send(Platform.executableArguments);
+    }
     if (msg == "new Options().executable") {
       reply.send(new Options().executable);
     }
@@ -53,15 +64,19 @@
   var sendPort = spawnFunction(f);
   Future.wait([sendPort.call("Platform.executable"),
                sendPort.call("Platform.script"),
+               sendPort.call("Platform.packageRoot"),
+               sendPort.call("Platform.executableArguments"),
                sendPort.call("new Options().executable"),
                sendPort.call("new Options().script")])
   .then((results) {
     Expect.equals(Platform.executable, results[0]);
-    Expect.equals(Platform.executable, results[2]);
+    Expect.equals(Platform.executable, results[4]);
     Uri uri = Uri.parse(results[1]);
-    Expect.equals(uri, Uri.parse(results[3]));
+    Expect.equals(uri, Uri.parse(results[5]));
     Expect.equals("file", uri.scheme);
     Expect.isTrue(uri.path.endsWith('tests/standalone/io/platform_test.dart'));
+    Expect.equals(Platform.packageRoot, results[2]);
+    Expect.listEquals(Platform.executableArguments, results[3]);
     sendPort.call("close").then((_) => port.close());
   });
 }
diff --git a/tests/standalone/io/process_stdin_transform_unsubscribe_script.dart b/tests/standalone/io/process_stdin_transform_unsubscribe_script.dart
index 0711124..06b42d8 100644
--- a/tests/standalone/io/process_stdin_transform_unsubscribe_script.dart
+++ b/tests/standalone/io/process_stdin_transform_unsubscribe_script.dart
@@ -4,13 +4,14 @@
 //
 // Utility script to echo stdin to stdout or stderr or both.
 
+import "dart:convert";
 import "dart:io";
 
 main() {
   var subscription;
   subscription = stdin
       .transform(new StringDecoder())
-      .transform(new LineTransformer())
+      .transform(new LineSplitter())
       .listen((String line) {
           // Unsubscribe after the first line.
           subscription.cancel();
diff --git a/tests/standalone/io/secure_socket_renegotiate_client.dart b/tests/standalone/io/secure_socket_renegotiate_client.dart
index 9ac2192..49d9c99 100644
--- a/tests/standalone/io/secure_socket_renegotiate_client.dart
+++ b/tests/standalone/io/secure_socket_renegotiate_client.dart
@@ -8,6 +8,7 @@
 // a client certificate to be sent.
 
 import "dart:async";
+import "dart:convert";
 import "dart:io";
 
 const HOST_NAME = "localhost";
@@ -44,7 +45,7 @@
       expectEquals('CN=myauthority', certificate.issuer);
       StreamIterator<String> input = new StreamIterator(socket
           .transform(new StringDecoder())
-          .transform(new LineTransformer()));
+          .transform(new LineSplitter()));
       socket.writeln('first');
       input.moveNext()
         .then((success) {
diff --git a/tests/standalone/io/secure_socket_renegotiate_test.dart b/tests/standalone/io/secure_socket_renegotiate_test.dart
index b938244..54736a8 100644
--- a/tests/standalone/io/secure_socket_renegotiate_test.dart
+++ b/tests/standalone/io/secure_socket_renegotiate_test.dart
@@ -6,10 +6,12 @@
 // are in separate processes, and that connection renegotiation works, and
 // can request a client certificate to be sent.
 
+import "dart:async";
+import "dart:convert";
+import "dart:io";
+
 import "package:expect/expect.dart";
 import "package:path/path.dart";
-import "dart:async";
-import "dart:io";
 
 const HOST_NAME = "localhost";
 const CERTIFICATE = "localhost_cert";
@@ -29,7 +31,7 @@
 
         StreamIterator<String> input =
             new StreamIterator(socket.transform(new StringDecoder())
-                                     .transform(new LineTransformer()));
+                                     .transform(new LineSplitter()));
         input.moveNext().then((success) {
           Expect.isTrue(success);
           Expect.equals('first', input.current);
diff --git a/tests/standalone/io/stdin_sync_test.dart b/tests/standalone/io/stdin_sync_test.dart
index f687837..0ac4e9d 100644
--- a/tests/standalone/io/stdin_sync_test.dart
+++ b/tests/standalone/io/stdin_sync_test.dart
@@ -2,10 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import "package:path/path.dart";
+import "dart:convert";
 import "dart:io";
 import "dart:json";
 
+import "package:path/path.dart";
+
 void testReadByte() {
   void test(String line, List<String> expected) {
     var script = join(dirname(Platform.script), "stdin_sync_script.dart");
@@ -16,14 +18,14 @@
       process.stdin.close();
       process.stderr
           .transform(new StringDecoder())
-          .transform(new LineTransformer())
+          .transform(new LineSplitter())
           .fold(new StringBuffer(), (b, d) => b..write(d))
           .then((data) {
             if (data.toString() != '') throw "Bad output: '$data'";
           });
       process.stdout
           .transform(new StringDecoder())
-          .transform(new LineTransformer())
+          .transform(new LineSplitter())
           .fold(new StringBuffer(), (b, d) => b..write(d))
           .then((data) {
             if (data.toString() != 'true') throw "Bad output: '$data'";
diff --git a/tests/standalone/io/string_transformer_test.dart b/tests/standalone/io/string_transformer_test.dart
index 054f973..eb6d168 100644
--- a/tests/standalone/io/string_transformer_test.dart
+++ b/tests/standalone/io/string_transformer_test.dart
@@ -2,12 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import "package:expect/expect.dart";
 import "dart:async";
+import "dart:convert";
 import "dart:io";
 import "dart:isolate";
 import "dart:utf";
 
+import "package:expect/expect.dart";
+
 void main() {
   testUtf8();
   testLatin1();
@@ -101,7 +103,7 @@
   var controller = new StreamController(sync: true);
   var stream = controller.stream
       .transform(new StringDecoder())
-      .transform(new LineTransformer());
+      .transform(new LineSplitter());
 
   var stage = 0;
 
@@ -130,7 +132,7 @@
 
   var stream = controller.stream
     .transform(new StringDecoder())
-    .transform(new LineTransformer());
+    .transform(new LineSplitter());
 
   var expectedLines = ['Line1', 'Line2','Line3', 'Line4',
                        '', '', '', '', '', '',
@@ -161,7 +163,7 @@
   var errors = 0;
   var stream = controller.stream
     .transform(new StringDecoder())
-    .transform(new LineTransformer());
+    .transform(new LineSplitter());
   stream.listen(
       (_) {},
       onDone: () {
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index e15eaf5..b50b03f 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -7,9 +7,11 @@
 # listed in tests/lib/analyzer/analyze_tests.status without the "standalone"
 # prefix.
 
-# The testing infrastructure is using the dart:io Path class.
+# The testing infrastructure is using the dart:io Path and LineTransformer
+# classes.
 io/skipping_dart2js_compilations_test: Skip # http/dartbug.com/12449
 io/dependency_graph_test: Skip # http/dartbug.com/12449
+io/status_file_parser_test: Skip # http/dartbug.com/12449
 
 package/invalid_uri_test: Fail, OK # Fails intentionally
 
@@ -29,11 +31,6 @@
 io/directory_fuzz_test: Skip
 
 [ $runtime == vm && $system == macos ]
-# These tests fail intermittently on MacOS due to an https request that
-# fails not completing the future it returns: Issue 12451
-io/https_unauthorized_test: Pass, Fail
-io/https_bad_certificate_test: Pass, Fail
-
 # This test fails with "Too many open files" on the Mac OS buildbot.
 # This is expected as MacOS by default runs with a very low number
 # of allowed open files ('ulimit -n' says something like 256).
@@ -130,7 +127,6 @@
 
 [ $compiler == dart2js && $jscl ]
 assert_test: Fail, OK # Assumes unspecified fields on the AssertionError.
-byte_array_test: Fail, OK # ByteArray
 deoptimization_test: Fail, OK # Requires bigint.
 out_of_memory_test: Fail, OK # d8 handles much larger arrays than Dart VM.
 io/options_test: Fail, OK # Cannot pass options to d8.
diff --git a/tests/standalone/vmservice/test_helper.dart b/tests/standalone/vmservice/test_helper.dart
index e3f51c5..d199d05 100644
--- a/tests/standalone/vmservice/test_helper.dart
+++ b/tests/standalone/vmservice/test_helper.dart
@@ -5,6 +5,7 @@
 library vmservice_test_helper;
 
 import 'dart:async';
+import 'dart:convert';
 import 'dart:io';
 import 'dart:json' as JSON;
 import 'dart:utf' as UTF;
@@ -97,7 +98,7 @@
       var blank;
       var first = true;
       process.stdout.transform(new StringDecoder())
-                    .transform(new LineTransformer()).listen((line) {
+                    .transform(new LineSplitter()).listen((line) {
         if (line.startsWith('VmService listening on port ')) {
           RegExp portExp = new RegExp(r"\d+");
           var port = portExp.stringMatch(line);
@@ -116,7 +117,7 @@
         print(line);
       });
       process.stderr.transform(new StringDecoder())
-                    .transform(new LineTransformer()).listen((line) {
+                    .transform(new LineSplitter()).listen((line) {
         print(line);
       });
       process.exitCode.then((code) {
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index 6fdf0e2..7bc1414 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -11,9 +11,6 @@
 dart2js_test: Skip # Uses dart:io.
 txt_layout_test: Skip # Might just go away.
 
-[ $compiler == none && $runtime == drt && $mode == debug ]
-recursive_import_test: Fail # 12501
-
 [ $compiler == dart2js && $browser ]
 *: Skip
 
diff --git a/tools/VERSION b/tools/VERSION
index 01d318f..e7ae0f4 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 6
-BUILD 19
+BUILD 20
 PATCH 0
diff --git a/tools/bots/bot.py b/tools/bots/bot.py
index 993ff4f..f9fcd0d 100644
--- a/tools/bots/bot.py
+++ b/tools/bots/bot.py
@@ -36,11 +36,13 @@
   - total_shards: The total number of shards, None when not specified.
   - is_buildbot: True if we are on a buildbot (or emulating it).
   - test_set: Specification of a non standard test set or None.
+  - csp: This is using csp when running
+  - arch: The architecture to build on.
   """
   def __init__(self, compiler, runtime, mode, system, checked=False,
                host_checked=False, minified=False, shard_index=None,
                total_shards=None, is_buildbot=False, test_set=None,
-               csp=None):
+               csp=None, arch=None):
     self.compiler = compiler
     self.runtime = runtime
     self.mode = mode
@@ -53,6 +55,10 @@
     self.is_buildbot = is_buildbot
     self.test_set = test_set
     self.csp = csp
+    if (arch == None):
+      self.arch = 'ia32'
+    else:
+      self.arch = arch
 
   def PrintBuildInfo(self):
     shard_description = ""
@@ -60,10 +66,11 @@
       shard_description = " shard %s of %s" % (self.shard_index,
                                                self.total_shards)
     print ("compiler: %s, runtime: %s mode: %s, system: %s,"
-           " checked: %s, host-checked: %s, minified: %s, test-set: %s%s"
+           " checked: %s, host-checked: %s, minified: %s, test-set: %s"
+           " arch: %s%s"
            ) % (self.compiler, self.runtime, self.mode, self.system,
                 self.checked, self.host_checked, self.minified, self.test_set,
-                shard_description)
+                self.arch, shard_description)
 
 
 class BuildStep(object):
@@ -102,7 +109,7 @@
   """
   with BuildStep('Build SDK'):
     args = [sys.executable, './tools/build.py', '--mode=' + build_info.mode,
-            'create_sdk']
+            '--arch=' + build_info.arch, 'create_sdk']
     print 'Building SDK: %s' % (' '.join(args))
     RunProcess(args)
 
@@ -205,6 +212,7 @@
       '--mode=' + build_info.mode,
       '--compiler=' + build_info.compiler,
       '--runtime=' + build_info.runtime,
+      '--arch=' + build_info.arch,
       '--progress=buildbot',
       '-v', '--time', '--use-sdk', '--report'
     ]
diff --git a/tools/bots/compiler.py b/tools/bots/compiler.py
index 79e538c..e469d6a 100644
--- a/tools/bots/compiler.py
+++ b/tools/bots/compiler.py
@@ -21,7 +21,7 @@
 import bot
 
 DART2JS_BUILDER = (
-    r'dart2js-(linux|mac|windows)(-(jsshell))?-(debug|release)(-(checked|host-checked))?(-(host-checked))?(-(minified))?-?(\d*)-?(\d*)')
+    r'dart2js-(linux|mac|windows)(-(jsshell))?-(debug|release)(-(checked|host-checked))?(-(host-checked))?(-(minified))?(-(x64))?-?(\d*)-?(\d*)')
 WEB_BUILDER = (
     r'dart2js-(ie9|ie10|ff|safari|chrome|chromeOnAndroid|opera|drt)-(win7|win8|mac10\.8|mac10\.7|linux)(-(all|html))?(-(csp))?(-(\d+)-(\d+))?')
 
@@ -41,6 +41,7 @@
   total_shards = None
   test_set = None
   csp = None
+  arch = None
 
   dart2js_pattern = re.match(DART2JS_BUILDER, builder_name)
   web_pattern = re.match(WEB_BUILDER, builder_name)
@@ -59,6 +60,7 @@
     compiler = 'dart2js'
     system = dart2js_pattern.group(1)
     runtime = 'd8'
+    arch = 'ia32'
     if dart2js_pattern.group(3) == 'jsshell':
       runtime = 'jsshell'
     mode = dart2js_pattern.group(4)
@@ -75,8 +77,10 @@
       host_checked = True
     if dart2js_pattern.group(10) == 'minified':
       minified = True
-    shard_index = dart2js_pattern.group(11)
-    total_shards = dart2js_pattern.group(12)
+    if dart2js_pattern.group(12) == 'x64':
+      arch = 'x64'
+    shard_index = dart2js_pattern.group(13)
+    total_shards = dart2js_pattern.group(14)
   else :
     return None
 
@@ -96,7 +100,7 @@
     return None
   return bot.BuildInfo(compiler, runtime, mode, system, checked, host_checked,
                        minified, shard_index, total_shards, is_buildbot,
-                       test_set, csp)
+                       test_set, csp, arch)
 
 
 def NeedsXterm(compiler, runtime):
@@ -135,7 +139,7 @@
 
 
 IsFirstTestStepCall = True
-def TestStep(name, mode, system, compiler, runtime, targets, flags):
+def TestStep(name, mode, system, compiler, runtime, targets, flags, arch):
   step_name = TestStepName(name, flags)
   with bot.BuildStep(step_name, swallow_error=True):
     sys.stdout.flush()
@@ -152,6 +156,7 @@
                 '--mode=' + mode,
                 '--compiler=' + compiler,
                 '--runtime=' + runtime,
+                '--arch=' + arch,
                 '--time',
                 '--use-sdk',
                 '--report',
@@ -181,7 +186,7 @@
     bot.RunProcess(cmd)
 
 
-def TestCompiler(runtime, mode, system, flags, is_buildbot, test_set):
+def TestCompiler(runtime, mode, system, flags, is_buildbot, test_set, arch):
   """ test the compiler.
    Args:
      - runtime: either 'd8', 'jsshell', or one of the browsers, see GetBuildInfo
@@ -191,6 +196,7 @@
      - is_buildbot: true if we are running on a real buildbot instead of
        emulating one.
      - test_set: Specification of a non standard test set, default None
+     - arch: The architecture to run on.
   """
 
   def GetPath(runtime):
@@ -239,13 +245,13 @@
     # Run the unit tests in checked mode (the VM's checked mode).
     unit_test_flags.append('--checked')
     TestStep("dart2js_unit", mode, system, 'none', 'vm', ['dart2js'],
-             unit_test_flags)
+             unit_test_flags, arch)
 
   if system == 'windows' and runtime == 'ie10':
-    TestStep("dart2js", mode, system, 'dart2js', runtime, ['html'], flags)
+    TestStep("dart2js", mode, system, 'dart2js', runtime, ['html'], flags, arch)
   else:
     # Run the default set of test suites.
-    TestStep("dart2js", mode, system, 'dart2js', runtime, [], flags)
+    TestStep("dart2js", mode, system, 'dart2js', runtime, [], flags, arch)
 
     # TODO(kasperl): Consider running peg and css tests too.
     extras = ['dart2js_extra', 'dart2js_native', 'dart2js_foreign']
@@ -257,7 +263,7 @@
       # Other systems have less resources and tend to time out.
       extras_flags = extras_flags + ['--host-checked']
     TestStep("dart2js_extra", mode, system, 'dart2js', runtime, extras,
-             extras_flags)
+             extras_flags, arch)
 
 
 def _DeleteTempWebdriverProfiles(directory):
@@ -356,13 +362,14 @@
     AddAndroidToolsToPath()
 
   TestCompiler(build_info.runtime, build_info.mode, build_info.system,
-               list(test_flags), build_info.is_buildbot, build_info.test_set)
+               list(test_flags), build_info.is_buildbot, build_info.test_set,
+               build_info.arch)
 
   # See comment in GetHasHardCodedCheckedMode, this is a hack.
   if (GetHasHardCodedCheckedMode(build_info)):
     TestCompiler(build_info.runtime, build_info.mode, build_info.system,
                  test_flags + ['--checked'], build_info.is_buildbot,
-                 build_info.test_set)
+                 build_info.test_set, build_info.arch)
 
   if build_info.runtime != 'd8':
     CleanUpTemporaryFiles(build_info.system, build_info.runtime)
@@ -377,7 +384,7 @@
   """
   with bot.BuildStep('Build SDK and d8'):
     args = [sys.executable, './tools/build.py', '--mode=' + build_info.mode,
-            'dart2js_bot']
+            '--arch=' + build_info.arch, 'dart2js_bot']
     print 'Build SDK and d8: %s' % (' '.join(args))
     bot.RunProcess(args)
 
diff --git a/tools/coverage.dart b/tools/coverage.dart
index 20811d1..350019d 100644
--- a/tools/coverage.dart
+++ b/tools/coverage.dart
@@ -13,6 +13,7 @@
 //   --verbose   see the stdout and stderr output of the debug
 //               target process.
 
+import "dart:convert";
 import "dart:io";
 import "dart:utf";
 import "dart:json" as JSON;
@@ -214,7 +215,7 @@
   Debugger(this.targetProcess) {
     var stdoutStringStream = targetProcess.stdout
         .transform(new StringDecoder())
-        .transform(new LineTransformer());
+        .transform(new LineSplitter());
     stdoutStringStream.listen((line) {
       if (showDebuggeeOutput) {
         print("TARG: $line");
@@ -231,7 +232,7 @@
 
     var stderrStringStream = targetProcess.stderr
         .transform(new StringDecoder())
-        .transform(new LineTransformer());
+        .transform(new LineSplitter());
     stderrStringStream.listen((line) {
       if (showDebuggeeOutput) {
         print("TARG: $line");
diff --git a/tools/ddbg.dart b/tools/ddbg.dart
index f1079e0..18673a6 100644
--- a/tools/ddbg.dart
+++ b/tools/ddbg.dart
@@ -38,6 +38,7 @@
   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
   pl <id> <idx> [<len>] Print list element/slice
   pc <id> Print class info for given id
   ll  List loaded libraries
@@ -126,6 +127,14 @@
                 "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(" ");
+    var cmd = { "id": seqNum,
+                "command": "evaluateExpr",
+                "params": { "isolateId": isolate_id,
+                            "objectId": int.parse(args[1]),
+                            "expression": expr } };
+    sendCmd(cmd).then((result) => handleEvalResponse(result));
   } else if (command == "po" && args.length == 2) {
     var cmd = { "id": seqNum,
                 "command": "getObjectProperties",
@@ -368,6 +377,12 @@
 }
 
 
+void handleEvalResponse(response) {
+  Map result = response["result"];
+  print(remoteObject(result));
+}
+
+
 void handleSetBpResponse(response) {
   Map result = response["result"];
   var id = result["breakpointId"];
diff --git a/tools/dom/dom.json b/tools/dom/dom.json
index d56916c..d9a9dec 100644
--- a/tools/dom/dom.json
+++ b/tools/dom/dom.json
@@ -675,8 +675,14 @@
         "comment": "http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#path-objects",
         "support_level": "experimental"
       },
+      "drawCustomFocusRing": {
+        "support_level": "untriaged"
+      },
       "drawImage": {},
       "drawImageFromRect": {},
+      "drawSystemFocusRing": {
+        "support_level": "untriaged"
+      },
       "fill": {},
       "fillRect": {},
       "fillStyle": {},
@@ -690,6 +696,9 @@
       "getLineDash": {},
       "globalAlpha": {},
       "globalCompositeOperation": {},
+      "imageSmoothingEnabled": {
+        "support_level": "untriaged"
+      },
       "isPointInPath": {},
       "isPointInStroke": {},
       "lineCap": {},
@@ -1897,6 +1906,9 @@
       },
       "getBoundingClientRect": {},
       "getClientRects": {},
+      "getDestinationInsertionPoints": {
+        "support_level": "untriaged"
+      },
       "getElementsByClassName": {},
       "getElementsByTagName": {},
       "getElementsByTagNameNS": {
@@ -1924,6 +1936,9 @@
         "dart_action": "stable",
         "support_level": "nonstandard"
       },
+      "inputMethodContext": {
+        "support_level": "untriaged"
+      },
       "isContentEditable": {
         "comment": "http://www.whatwg.org/specs/web-apps/2007-10-26/multipage/section-elements.html#htmlelement",
         "dart_action": "stable",
@@ -2252,6 +2267,12 @@
     "comment": "http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#errorevent",
     "dart_action": "unstable",
     "members": {
+      "colno": {
+        "support_level": "untriaged"
+      },
+      "error": {
+        "support_level": "untriaged"
+      },
       "filename": {},
       "lineno": {},
       "message": {}
@@ -3142,6 +3163,9 @@
         "dart_action": "suppress",
         "support_level": "nonstandard"
       },
+      "inputMethodContext": {
+        "support_level": "untriaged"
+      },
       "insertAdjacentElement": {
         "support_level": "nonstandard"
       },
@@ -4961,12 +4985,27 @@
   "KeyboardEvent": {
     "comment": "http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent",
     "members": {
+      "DOM_KEY_LOCATION_LEFT": {
+        "support_level": "untriaged"
+      },
+      "DOM_KEY_LOCATION_NUMPAD": {
+        "support_level": "untriaged"
+      },
+      "DOM_KEY_LOCATION_RIGHT": {
+        "support_level": "untriaged"
+      },
+      "DOM_KEY_LOCATION_STANDARD": {
+        "support_level": "untriaged"
+      },
       "altGraphKey": {
         "dart_action": "experimental",
         "support_level": "nonstandard"
       },
       "altKey": {},
       "ctrlKey": {},
+      "getModifierState": {
+        "support_level": "untriaged"
+      },
       "initKeyboardEvent": {},
       "keyIdentifier": {
         "dart_action": "experimental",
@@ -4976,6 +5015,9 @@
         "dart_action": "experimental",
         "support_level": "nonstandard"
       },
+      "location": {
+        "support_level": "untriaged"
+      },
       "metaKey": {},
       "shiftKey": {}
     },
@@ -6133,6 +6175,9 @@
   "Performance": {
     "comment": "http://www.w3.org/TR/navigation-timing/#performance",
     "members": {
+      "addEventListener": {
+        "support_level": "untriaged"
+      },
       "clearMarks": {
         "comment": "https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/UserTiming/Overview.html#extensions-performance-interface",
         "support_level": "experimental"
@@ -6141,6 +6186,9 @@
         "comment": "https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/UserTiming/Overview.html#extensions-performance-interface",
         "support_level": "experimental"
       },
+      "dispatchEvent": {
+        "support_level": "untriaged"
+      },
       "getEntries": {
         "comment": "http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute",
         "support_level": "experimental"
@@ -6173,6 +6221,9 @@
         "comment": "http://www.w3c-test.org/webperf/specs/ResourceTiming/#performanceresourcetiming-methods",
         "support_level": "experimental"
       },
+      "removeEventListener": {
+        "support_level": "untriaged"
+      },
       "timing": {},
       "webkitClearResourceTimings": {
         "comment": "http://www.w3c-test.org/webperf/specs/ResourceTiming/#extensions-performance-interface",
@@ -6443,11 +6494,29 @@
       "bufferedAmount": {},
       "close": {},
       "dispatchEvent": {},
+      "id": {
+        "support_level": "untriaged"
+      },
       "label": {},
+      "maxRetransmitTime": {
+        "support_level": "untriaged"
+      },
+      "maxRetransmits": {
+        "support_level": "untriaged"
+      },
+      "negotiated": {
+        "support_level": "untriaged"
+      },
       "onclose": {},
       "onerror": {},
       "onmessage": {},
       "onopen": {},
+      "ordered": {
+        "support_level": "untriaged"
+      },
+      "protocol": {
+        "support_level": "untriaged"
+      },
       "readyState": {},
       "reliable": {},
       "removeEventListener": {},
@@ -6691,6 +6760,25 @@
     },
     "support_level": "experimental"
   },
+  "RsaKeyGenParams": {
+    "members": {
+      "modulusLength": {
+        "support_level": "untriaged"
+      },
+      "publicExponent": {
+        "support_level": "untriaged"
+      }
+    },
+    "support_level": "untriaged"
+  },
+  "RsaSsaParams": {
+    "members": {
+      "hash": {
+        "support_level": "untriaged"
+      }
+    },
+    "support_level": "untriaged"
+  },
   "SQLError": {
     "comment": "http://www.w3.org/TR/webdatabase/#sqlerror",
     "dart_action": "experimental",
@@ -7301,8 +7389,17 @@
     "comment": "http://www.w3.org/TR/SVG/types.html#InterfaceSVGElement",
     "dart_action": "unstable",
     "members": {
+      "className": {
+        "support_level": "untriaged"
+      },
+      "getPresentationAttribute": {
+        "support_level": "untriaged"
+      },
       "id": {},
       "ownerSVGElement": {},
+      "style": {
+        "support_level": "untriaged"
+      },
       "viewportElement": {},
       "xmlbase": {},
       "xmllang": {
@@ -10055,10 +10152,19 @@
       "appendBufferView": {
         "support_level": "untriaged"
       },
+      "appendWindowEnd": {
+        "support_level": "untriaged"
+      },
+      "appendWindowStart": {
+        "support_level": "untriaged"
+      },
       "buffered": {},
       "dispatchEvent": {
         "support_level": "untriaged"
       },
+      "remove": {
+        "support_level": "untriaged"
+      },
       "removeEventListener": {
         "support_level": "untriaged"
       },
@@ -10400,6 +10506,9 @@
       "encrypt": {
         "support_level": "untriaged"
       },
+      "generateKey": {
+        "support_level": "untriaged"
+      },
       "importKey": {
         "support_level": "untriaged"
       },
@@ -10416,6 +10525,9 @@
     "comment": "http://dom.spec.whatwg.org/#interface-text",
     "members": {
       "Text": {},
+      "getDestinationInsertionPoints": {
+        "support_level": "untriaged"
+      },
       "replaceWholeText": {
         "comment": "http://dom.spec.whatwg.org/#dom-text-replacewholetext",
         "dart_action": "suppress",
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index e7be42c..7b1639a 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -67,6 +67,8 @@
 [Supplemental]
 interface CanvasRenderingContext2D {
   [DartName=createImageDataFromImageData] ImageData createImageData(ImageData imagedata);
+
+  [Suppressed] attribute boolean webkitImageSmoothingEnabled;
 };
 
 [Supplemental]
@@ -334,6 +336,26 @@
   [CustomSetter] attribute DOMString hash;
 };
 
+// TODO(jacobr): reenable these new Blink features.
+[Suppressed]
+interface ImageBitmapFactories {};
+
+// See https://chromiumcodereview.appspot.com/15901002 for the V8 implementation of
+// TextEncoder/TextDecoder
+[Suppressed]
+interface TextEncoder {};
+
+[Suppressed]
+interface TextDecoder {};
+
+// TODO(jacobr): renable these as part of fixing dartbug.com/12537
+// We need to apply changes analogous to https://chromiumcodereview.appspot.com/21274004
+// to the Dart bindings so that we can reenable NodeIterator and TreeWalker
+[Suppressed]
+interface NodeIterator {};
+
+[Suppressed]
+interface TreeWalker {};
 
 [Supplemental]
 interface Window : EventTarget {};
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
index ecbc261..40b9713 100644
--- a/tools/dom/scripts/dartmetadata.py
+++ b/tools/dom/scripts/dartmetadata.py
@@ -83,6 +83,10 @@
       "@Creates('Null')",
     ],
 
+    "ErrorEvent.error": [
+      "@Creates('Null')", # Only returns values created elsewhere.
+    ],
+
     # To be in callback with the browser-created Event, we had to have called
     # addEventListener on the target, so we avoid
     'Event.currentTarget': [
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 396b7b3..5889566 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -18,6 +18,7 @@
     'DOMStringMap',
     'ChildNode',
     'EventListener',
+    'EventHandler',
     'MediaQueryListListener',
     'MutationCallback',
     'ParentNode',
@@ -783,6 +784,12 @@
     super(CallbackIDLTypeInfo, self).__init__(idl_type, data)
 
 
+def array_type(data_type):
+  matched = re.match(r'([\w\d_\s]+)\[\]', data_type)
+  if not matched:
+      return None
+  return matched.group(1)
+
 class SequenceIDLTypeInfo(IDLTypeInfo):
   def __init__(self, idl_type, data, item_info):
     super(SequenceIDLTypeInfo, self).__init__(idl_type, data)
@@ -807,7 +814,11 @@
     return '%s', 'Vector< RefPtr<%s> >' % item_native_type, 'DartUtilities', 'toNativeVector< RefPtr<%s> >' % item_native_type
 
   def parameter_type(self):
-    return self.native_type()
+    native_type = self.native_type()
+    if array_type(native_type):
+      return 'const Vector<RefPtr<%s> > &' % array_type(native_type)
+
+    return native_type
 
   def pass_native_by_ref(self): return True
 
@@ -1030,6 +1041,7 @@
     'Element': TypeData(clazz='Interface', merged_interface='HTMLElement',
         custom_to_dart=True),
     'EventListener': TypeData(clazz='Interface', custom_to_native=True),
+    'EventHandler': TypeData(clazz='Interface', custom_to_native=True),
     'EventTarget': TypeData(clazz='Interface', custom_to_native=True),
     'HTMLElement': TypeData(clazz='Interface', merged_into='Element',
         custom_to_dart=True),
@@ -1142,7 +1154,7 @@
       item_info = self.TypeInfo(match.group(1) or match.group(2))
       # TODO(vsm): Generalize this code.
       if 'SourceInfo' in type_name:
-        type_data.native_type = 'Vector<RefPtr<SourceInfo> >'
+        type_data.native_type = 'const Vector<RefPtr<SourceInfo> >& '
       return SequenceIDLTypeInfo(type_name, type_data, item_info)
 
     if not type_name in _idl_type_registry:
@@ -1179,8 +1191,7 @@
           type_name, type_data, dart_interface_name, self)
 
     if type_data.clazz == 'TypedList':
-      dart_interface_name = self._renamer.RenameInterface(
-          self._database.GetInterface(type_name))
+      dart_interface_name = self._renamer.RenameInterfaceId(type_name)
       return TypedListIDLTypeInfo(
           type_name, type_data, dart_interface_name, self)
 
@@ -1188,8 +1199,7 @@
       if type_name == 'ArrayBuffer':
         dart_interface_name = 'ByteBuffer'
       else:
-        dart_interface_name = self._renamer.RenameInterface(
-            self._database.GetInterface(type_name))
+        dart_interface_name = self._renamer.RenameInterfaceId(type_name)
       return BasicTypedListIDLTypeInfo(
           type_name, type_data, dart_interface_name, self)
 
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 0692740..34911cf 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -72,7 +72,7 @@
       self.AddConstant(const)
 
     for attr in sorted(interface.attributes, ConstantOutputOrder):
-      if attr.type.id != 'EventListener':
+      if attr.type.id != 'EventHandler' and attr.type.id != 'EventListener':
         self.AddAttribute(attr, declare_only)
 
     # The implementation should define an indexer if the interface directly
@@ -117,7 +117,7 @@
         continue
       for attr in sorted(parent_interface.attributes, ConstantOutputOrder):
         if not FindMatchingAttribute(interface, attr):
-          if attr.type.id != 'EventListener':
+          if attr.type.id != 'EventHandler':
             self.SecondaryContext(parent_interface)
             self.AddAttribute(attr)
 
diff --git a/tools/dom/scripts/htmleventgenerator.py b/tools/dom/scripts/htmleventgenerator.py
index eee08c6..4f38941 100644
--- a/tools/dom/scripts/htmleventgenerator.py
+++ b/tools/dom/scripts/htmleventgenerator.py
@@ -328,7 +328,8 @@
     for super_interface in all_interfaces:
       events = events.union(
         set([attr.id for attr in super_interface.attributes
-             if attr.type.id == 'EventListener']))
+             if (attr.type.id == 'EventHandler'
+              or attr.type.id == 'EventListener')]))
     return events
 
   def _GetEvents(self, interface, custom_events):
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index c58b21b..ceee9ba 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -375,6 +375,18 @@
       'transactionList',
   'IDBDatabase.transaction(DOMString storeName, DOMString mode)':
       'transactionStore',
+  'ImageBitmapFactories.createImageBitmap(HTMLImageElement image)' : 'createImageBitmap0',
+  'ImageBitmapFactories.createImageBitmap(HTMLImageElement image, long sx, long sy, long sw, long sh)' : 'createImageBitmap1',
+  'ImageBitmapFactories.createImageBitmap(HTMLVideoElement video)' : 'createImageBitmap2',
+  'ImageBitmapFactories.createImageBitmap(HTMLVideoElement video, long sx, long sy, long sw, long sh)' : 'createImageBitmap3',
+  'ImageBitmapFactories.createImageBitmap(CanvasRenderingContext2D context)' : 'createImageBitmap4',
+  'ImageBitmapFactories.createImageBitmap(CanvasRenderingContext2D context, long sx, long sy, long sw, long sh)' : 'createImageBitmap5',
+  'ImageBitmapFactories.createImageBitmap(HTMLCanvasElement canvas)' : 'createImageBitmap6',
+  'ImageBitmapFactories.createImageBitmap(HTMLCanvasElement canvas, long sx, long sy, long sw, long sh)' : 'createImageBitmap7',
+  'ImageBitmapFactories.createImageBitmap(ImageData data)' : 'createImageBitmap8',
+  'ImageBitmapFactories.createImageBitmap(ImageData data, long sx, long sy, long sw, long sh)' : 'createImageBitmap9',
+  'ImageBitmapFactories.createImageBitmap(ImageBitmap bitmap)' : 'createImageBitmap10',
+  'ImageBitmapFactories.createImageBitmap(ImageBitmap bitmap, long sx, long sy, long sw, long sh)' : 'createImageBitmap11',
   'RTCDataChannel.send(ArrayBuffer data)': 'sendByteBuffer',
   'RTCDataChannel.send(ArrayBufferView data)': 'sendTypedData',
   'RTCDataChannel.send(Blob data)': 'sendBlob',
@@ -713,6 +725,7 @@
     'Performance.webkitMark',
     'Performance.webkitMeasure',
     'ShadowRoot.getElementsByTagNameNS',
+    'SVGElement.getPresentationAttribute',
     'SVGStyledElement.getPresentationAttribute',
     'WheelEvent.wheelDelta',
     'WorkerGlobalScope.webkitIndexedDB',
@@ -738,14 +751,20 @@
       if interface.id in _removed_html_interfaces:
         return None
 
-    if interface.id in html_interface_renames:
-      return html_interface_renames[interface.id]
-    elif interface.id.startswith('HTML'):
+    candidate = self.RenameInterfaceId(interface.id)
+    if candidate:
+      return candidate
+
+    if interface.id.startswith('HTML'):
       if any(interface.id in ['Element', 'Document']
              for interface in self._database.Hierarchy(interface)):
         return interface.id[len('HTML'):]
     return self._DartifyName(interface.javascript_binding_name)
 
+  def RenameInterfaceId(self, interface_id):
+    if interface_id in html_interface_renames:
+      return html_interface_renames[interface_id]
+    return None;
 
 
   def RenameMember(self, interface_name, member_node, member, member_prefix='',
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 5133ef6..9770a59 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -49,6 +49,7 @@
     'WebKitCSSKeyframesRule.insertRule',
     'CSSStyleDeclaration.setProperty',
     'Element.createShadowRoot',
+    'Element.innerHTML',
     'Element.insertAdjacentElement',
     'Element.insertAdjacentHTML',
     'Element.insertAdjacentText',
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index f9809eb..9a6436e 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -93,6 +93,12 @@
   else:
     return set([])
 
+def array_type(data_type):
+    matched = re.match(r'([\w\d_\s]+)\[\]', data_type)
+    if not matched:
+        return None
+    return matched.group(1)
+
 def _GetCPPTypeName(interface_name, callback_name, cpp_name):
   # TODO(vsm): We need to track the original IDL file name in order to recover
   # the proper CPP name.
@@ -714,6 +720,9 @@
 
     requires_script_execution_context = (ext_attrs.get('CallWith') == 'ScriptExecutionContext' or
                                          ext_attrs.get('ConstructorCallWith') == 'ScriptExecutionContext')
+
+    requires_document = ext_attrs.get('ConstructorCallWith') == 'Document'
+
     if requires_script_execution_context:
       raises_exceptions = True
       cpp_arguments = ['context']
@@ -725,7 +734,7 @@
       cpp_arguments = ['&state']
 
     requires_dom_window = 'NamedConstructor' in ext_attrs
-    if requires_dom_window:
+    if requires_dom_window or requires_document:
       raises_exceptions = True
       cpp_arguments = ['document']
 
@@ -810,7 +819,7 @@
           '        }\n'
           '        ScriptState& state = *currentState;\n\n')
 
-    if requires_dom_window:
+    if requires_dom_window or requires_document:
       self._cpp_impl_includes.add('"DOMWindow.h"')
       body_emitter.Emit(
           '        DOMWindow* domWindow = DartUtilities::domWindowForCurrentIsolate();\n'
@@ -967,7 +976,7 @@
       # Generate to Dart conversion of C++ value.
       if return_type_info.dart_type() == 'bool':
         set_return_value = 'Dart_SetBooleanReturnValue(args, %s)' % (value_expression)
-      elif return_type_info.dart_type() == 'int':
+      elif return_type_info.dart_type() == 'int' and return_type_info.native_type() == 'int':
         set_return_value = 'Dart_SetIntegerReturnValue(args, %s)' % (value_expression)
       elif return_type_info.dart_type() == 'double':
         set_return_value = 'Dart_SetDoubleReturnValue(args, %s)' % (value_expression)
diff --git a/tools/dom/src/dart2js_CustomElementSupport.dart b/tools/dom/src/dart2js_CustomElementSupport.dart
index a40e81c..e601ef0 100644
--- a/tools/dom/src/dart2js_CustomElementSupport.dart
+++ b/tools/dom/src/dart2js_CustomElementSupport.dart
@@ -45,9 +45,6 @@
   if (baseClassName == 'Element') baseClassName = 'HTMLElement';
 
   var baseConstructor = JS('=Object', '#[#]', context, baseClassName);
-  if (JS('bool', "typeof(#) != 'function'", baseConstructor)) {
-    throw new ArgumentError(type);
-  }
 
   var properties = JS('=Object', '{}');
 
diff --git a/tools/dom/src/dart2js_Platform.dart b/tools/dom/src/dart2js_Platform.dart
index 5988011..ea50a6a 100644
--- a/tools/dom/src/dart2js_Platform.dart
+++ b/tools/dom/src/dart2js_Platform.dart
@@ -18,4 +18,17 @@
    * error.
    */
   static final supportsSimd = false;
+
+  /**
+   * 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.
+   */
+  static void upgradeCustomElements(Node node) {
+    if (JS('bool', '(#.CustomElements && #.CustomElements.upgradeAll)',
+        window, window)) {
+      JS('', '#.CustomElements.upgradeAll(#)', window, node);
+    }
+  }
 }
diff --git a/tools/dom/src/dartium_Platform.dart b/tools/dom/src/dartium_Platform.dart
index a851cca..48f3238 100644
--- a/tools/dom/src/dartium_Platform.dart
+++ b/tools/dom/src/dartium_Platform.dart
@@ -18,4 +18,14 @@
    * 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.
+  }
 }
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index a7c0e97..80676b0 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -195,15 +195,20 @@
   // DOM node rather than just a class that extends Node.
   static bool isNode(obj) => obj is Node;
 
+  static bool _isBuiltinType(ClassMirror cls) {
+    // TODO(vsm): Find a less hackish way to do this.
+    LibraryMirror lib = cls.owner;
+    String libName = lib.uri.toString();
+    return libName.startsWith('dart:');
+  }
+
   static void register(String tag, Type type) {
     // TODO(vsm): Move these checks into native code.
     if (type == null) {
       throw new UnsupportedError("Invalid null type.");
     }
     ClassMirror cls = reflectClass(type);
-    LibraryMirror lib = cls.owner;
-    String libName = lib.uri.toString();
-    if (libName.startsWith('dart:')) {
+    if (_isBuiltinType(cls)) {
       throw new UnsupportedError("Invalid custom element from $libName.");
     }
     ClassMirror superClass = cls.superclass;
@@ -216,17 +221,21 @@
     bool isElement(ClassMirror cls) =>
       cls != null && cls.qualifiedName == elementName;
 
+    ClassMirror nativeClass = _isBuiltinType(superClass) ? superClass : null;
     while(!isRoot(superClass) && !isElement(superClass)) {
       superClass = superClass.superclass;
+      if (nativeClass == null && _isBuiltinType(superClass)) {
+        nativeClass = superClass;
+      }
     }
 
     if (isRoot(superClass)) {
       throw new UnsupportedError("Invalid custom element doesn't inherit from HtmlElement.");
     }
-    _register(tag, type);
+    _register(tag, type, nativeClass.reflectedType);
   }
 
-  static void _register(String tag, Type type) native "Utils_register";
+  static void _register(String tag, Type customType, Type nativeType) native "Utils_register";
 }
 
 class _NPObject extends NativeFieldWrapperClass1 {
diff --git a/tools/dom/templates/html/impl/impl_Document.darttemplate b/tools/dom/templates/html/impl/impl_Document.darttemplate
index f0fdc7b..e095026 100644
--- a/tools/dom/templates/html/impl/impl_Document.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Document.darttemplate
@@ -35,4 +35,13 @@
   ElementList queryAll(String selectors) {
     return new _FrozenElementList._wrap($dom_querySelectorAll(selectors));
   }
+
+  /// Checks if [register] is supported on the current platform.
+  bool get supportsRegister {
+$if DART2JS
+    return JS('bool', '("register" in #)', this);
+$else
+    return true;
+$endif
+  }
 }
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index cbea8c1..acf6abb 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -244,7 +244,7 @@
    */
   @Experimental()
   CssRect get marginEdge;
-$!STREAM_GETTER_SIGNATURES 
+$!STREAM_GETTER_SIGNATURES
 }
 
 // TODO(jacobr): this is an inefficient implementation but it is hard to see
@@ -1170,6 +1170,20 @@
     Point p = Element._offsetToHelper(parentOffset, parent);
     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);
+
+  void set innerHtml(String value) {
+    JS('', '#.innerHTML = #', this, value);
+    // Polyfill relies on mutation observers for upgrading, but we want it
+    // immediate.
+    Platform.upgradeCustomElements(this);
+  }
+$endif
+
 $!MEMBERS
 }
 
diff --git a/tools/test.dart b/tools/test.dart
index e0a1617..154d0ee 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -9,7 +9,7 @@
  *
  *     1. the dart vm
  *     2. the dart2js compiler
- *     3. the dartc static analyzer
+ *     3. the static analyzer
  *     4. the dart core library
  *     5. other standard dart libraries (DOM bindings, ui libraries,
  *            io libraries etc.)
@@ -37,7 +37,6 @@
 import "testing/dart/utils.dart";
 
 import "../runtime/tests/vm/test_config.dart";
-import "../samples/tests/dartc/test_config.dart";
 import "../tests/co19/test_config.dart";
 import "../tests/lib/analyzer/test_config.dart";
 
diff --git a/tools/testing/dart/multitest.dart b/tools/testing/dart/multitest.dart
index 1159a8a..da61f9d 100644
--- a/tools/testing/dart/multitest.dart
+++ b/tools/testing/dart/multitest.dart
@@ -14,9 +14,9 @@
 //
 // For each key in the file, a new test file is made containing all
 // the normal lines of the file, and all of the multitest lines containing
-// that key, in the same order as in the source file.  The new test
-// is expected to fail if there is a non-empty error type listed, of
-// type 'compile-time error', 'runtime error', 'static type warning', or
+// that key, in the same order as in the source file.  The new test is expected
+// to pass if the error type listed is 'ok', or to fail if there is an error
+// type of type 'compile-time error', 'runtime error', 'static type warning', or
 // 'dynamic type error'.  The type error tests fail only in checked mode.
 // There is also a test created from only the untagged lines of the file,
 // with key "none", which is expected to pass.  This library extracts these
@@ -29,29 +29,35 @@
 //   bbb /// 02: runtime error
 //   ccc /// 02: continued
 //   ddd /// 07: static type warning
-//   eee
+//   eee /// 10: ok
+//   fff
 //
-// should create three tests:
+// should create four tests:
 // I_am_a_multitest_none.dart
 //   aaa
-//   eee
+//   fff
 //
 // I_am_a_multitest_02.dart
 //   aaa
 //   bbb /// 02: runtime error
 //   ccc /// 02: continued
-//   eee
+//   fff
 //
-// and I_am_a_multitest_07.dart
+// I_am_a_multitest_07.dart
 //   aaa
 //   ddd /// 07: static type warning
-//   eee
+//   fff
+//
+// and I_am_a_multitest_10.dart
+//   aaa
+//   eee /// 10: ok
+//   fff
 //
 // Note that it is possible to indicate more than one acceptable outcome
 // in the case of dynamic and static type warnings
 //   aaa
 //   ddd /// 07: static type warning, dynamic type error
-//   eee
+//   fff
 
 void ExtractTestsFromMultitest(Path filePath,
                                Map<String, String> tests,
@@ -71,7 +77,7 @@
   bytes = null;
   contents = null;
   Set<String> validMultitestOutcomes = new Set<String>.from(
-      ['compile-time error', 'runtime error',
+      ['ok', 'compile-time error', 'runtime error',
        'static type warning', 'dynamic type error']);
 
   List<String> testTemplate = new List<String>();
diff --git a/tools/testing/dart/status_file_parser.dart b/tools/testing/dart/status_file_parser.dart
index dc3d5fe..36dd839 100644
--- a/tools/testing/dart/status_file_parser.dart
+++ b/tools/testing/dart/status_file_parser.dart
@@ -24,9 +24,11 @@
  */
 const SLOW = "slow";
 
-final RegExp StripComment = new RegExp("^[^#]*");
+final RegExp SplitComment = new RegExp("^([^#]*)(#.*)?\$");
 final RegExp HeaderPattern = new RegExp(r"^\[([^\]]+)\]");
 final RegExp RulePattern = new RegExp(r"\s*([^: ]*)\s*:(.*)");
+final RegExp IssueNumberPattern =
+    new RegExp("Issue ([0-9]+)|dartbug.com/([0-9]+)", caseSensitive: false);
 
 // TODO(whesse): Implement configuration_info library that contains data
 // structures for test configuration, including Section.
@@ -39,6 +41,10 @@
 
   bool isEnabled(environment) =>
       condition == null || condition.evaluate(environment);
+
+  String toString() {
+    return "Section: $condition";
+  }
 }
 
 void ReadTestExpectationsInto(TestExpectations expectations,
@@ -75,11 +81,14 @@
   sections.add(current);
 
   lines.listen((String line) {
-    Match match = StripComment.firstMatch(line);
-    line = (match == null) ? "" : match[0];
+    Match match = SplitComment.firstMatch(line);
+    line = (match == null) ? "" : match[1];
     line = line.trim();
     if (line.isEmpty) return;
 
+    // Extract the comment to get the issue number if needed.
+    String comment = (match == null || match[2] == null) ? "" : match[2];
+
     match = HeaderPattern.firstMatch(line);
     if (match != null) {
       String condition_string = match[1].trim();
@@ -98,7 +107,16 @@
       List<String> tokens = new Tokenizer(expression_string).tokenize();
       SetExpression expression =
           new ExpressionParser(new Scanner(tokens)).parseSetExpression();
-      current.testRules.add(new TestRule(name, expression));
+
+      // Look for issue number in comment.
+      String issueString = null;
+      match = IssueNumberPattern.firstMatch(comment);
+      if (match != null) {
+        issueString = match[1];
+        if (issueString == null) issueString = match[2];
+      }
+      int issue = issueString != null ? int.parse(issueString) : null;
+      current.testRules.add(new TestRule(name, expression, issue));
       return;
     }
 
@@ -111,10 +129,13 @@
 class TestRule {
   String name;
   SetExpression expression;
+  int issue;
 
-  TestRule(this.name, this.expression);
+  TestRule(this.name, this.expression, this.issue);
 
-  String toString() => 'TestRule($name, $expression)';
+  bool get hasIssue => issue != null;
+
+  String toString() => 'TestRule($name, $expression, $issue)';
 }