Version 0.8.0.0

svn merge -r 27984:28200 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@28224 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer_experimental/bin/formatter.dart b/pkg/analyzer_experimental/bin/formatter.dart
index 02dc8f1..a8ea0fe 100755
--- a/pkg/analyzer_experimental/bin/formatter.dart
+++ b/pkg/analyzer_experimental/bin/formatter.dart
@@ -159,7 +159,11 @@
 _toJson(formatResult) => 
     // Actual JSON format TBD
     JSON.encode({'source': formatResult.source,
-                 'selection': formatResult.selection.toString()});
+                 'selection': {
+                     'offset': formatResult.selection.offset,
+                     'length': formatResult.selection.length
+                  }
+    });
 
 /// Log the given [msg].
 _log(String msg) {
diff --git a/pkg/analyzer_experimental/lib/options.dart b/pkg/analyzer_experimental/lib/options.dart
index efa3b5f..9b3ffac 100644
--- a/pkg/analyzer_experimental/lib/options.dart
+++ b/pkg/analyzer_experimental/lib/options.dart
@@ -26,6 +26,9 @@
   /** Whether to display version information */
   final bool displayVersion;
 
+  /** Whether to report hints */
+  final bool disableHints;
+
   /** Whether to ignore unrecognized flags */
   final bool ignoreUnrecognizedFlags;
 
@@ -57,6 +60,7 @@
     : shouldBatch = args['batch'],
       machineFormat = args['machine'],
       displayVersion = args['version'],
+      disableHints = args['no-hints'],
       ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'],
       perf = args['perf'],
       showPackageWarnings = args['show-package-warnings'],
@@ -102,6 +106,8 @@
           defaultsTo: false, negatable: false)
       ..addFlag('version', help: 'Print the analyzer version',
           defaultsTo: false, negatable: false)
+      ..addFlag('no-hints', help: 'Do not show hint results',
+          defaultsTo: false, negatable: false)
       ..addFlag('ignore-unrecognized-flags',
           help: 'Ignore unrecognized command line flags',
           defaultsTo: false, negatable: false)
diff --git a/pkg/analyzer_experimental/lib/src/analyzer_impl.dart b/pkg/analyzer_experimental/lib/src/analyzer_impl.dart
index 40b436c..2104617 100644
--- a/pkg/analyzer_experimental/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_experimental/lib/src/analyzer_impl.dart
@@ -86,6 +86,11 @@
     sourceFactory = new SourceFactory.con1(contentCache, resolvers);
     context = AnalysisEngine.instance.createAnalysisContext();
     context.sourceFactory = sourceFactory;
+
+    // set options for context
+    AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl();
+    contextOptions.hint = !options.disableHints;
+    context.analysisOptions = contextOptions;
   }
 
   /// Fills [sources].
@@ -139,6 +144,7 @@
   /// Fills [errorInfos].
   void prepareErrors() {
     for (Source source in sources) {
+      context.computeErrors(source);
       var sourceErrors = context.getErrors(source);
       errorInfos.add(sourceErrors);
     }
diff --git a/pkg/analyzer_experimental/lib/src/error_formatter.dart b/pkg/analyzer_experimental/lib/src/error_formatter.dart
index 47d718d..c26aaa4 100644
--- a/pkg/analyzer_experimental/lib/src/error_formatter.dart
+++ b/pkg/analyzer_experimental/lib/src/error_formatter.dart
@@ -46,41 +46,62 @@
     // format errors
     int errorCount = 0;
     int warnCount = 0;
+    int hintCount = 0;
     for (AnalysisError error in errors) {
-      if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) {
+      var severity = error.errorCode.errorSeverity;
+      if (severity == ErrorSeverity.ERROR) {
         errorCount++;
-      } else if (error.errorCode.errorSeverity == ErrorSeverity.WARNING) {
+      } else if (severity == ErrorSeverity.WARNING) {
         if (options.warningsAreFatal) {
           errorCount++;
         } else {
-          warnCount++;
+          if (error.errorCode.type == ErrorType.HINT) {
+            hintCount++;
+          } else {
+            warnCount++;
+          }
         }
       }
       formatError(errorToLine, error);
     }
     // print statistics
     if (!options.machineFormat) {
-      if (errorCount != 0 && warnCount != 0) {
+      var hasErrors = errorCount != 0;
+      var hasWarns = warnCount != 0;
+      var hasHints = hintCount != 0;
+      bool hasContent = false;
+      if (hasErrors) {
         out.write(errorCount);
         out.write(' ');
         out.write(pluralize("error", errorCount));
-        out.write(' and ');
+        hasContent = true;
+      }
+      if (hasWarns) {
+        if (hasContent) {
+          if (!hasHints) {
+            out.write(' and ');
+          } else {
+            out.write(", ");
+          }
+        }
         out.write(warnCount);
         out.write(' ');
         out.write(pluralize("warning", warnCount));
-        out.writeln(' found.');
-      } else if (errorCount != 0) {
-        out.write(errorCount);
+        hasContent = true;
+      }
+      if (hasHints) {
+        if (hasContent) {
+          out.write(" and ");
+        }
+        out.write(hintCount);
         out.write(' ');
-        out.write(pluralize("error", errorCount));
-        out.writeln(' found.');
-      } else if (warnCount != 0) {
-        out.write(warnCount);
-        out.write(' ');
-        out.write(pluralize("warning", warnCount));
-        out.writeln(' found.');
+        out.write(pluralize("hint", hintCount));
+        hasContent = true;
+      }
+      if (hasContent) {
+        out.writeln(" found.");
       } else {
-        out.writeln("No issues found.");
+        out.writeln("No issues found");
       }
     }
   }
@@ -110,8 +131,12 @@
       out.write('|');
       out.write(escapePipe(error.message));
     } else {
+      String errorType = error.errorCode.errorSeverity.displayName;
+      if (error.errorCode.type == ErrorType.HINT) {
+        errorType = error.errorCode.type.displayName;
+      }
       // [warning] 'foo' is not a... (/Users/.../tmp/foo.dart, line 1, col 2)
-      out.write('[${severity.displayName}] ${error.message} ');
+      out.write('[$errorType] ${error.message} ');
       out.write('(${source.fullName}');
       out.write(', line ${location.lineNumber}, col ${location.columnNumber})');
     }
diff --git a/pkg/analyzer_experimental/lib/src/generated/ast.dart b/pkg/analyzer_experimental/lib/src/generated/ast.dart
index dea447d..3acc231 100644
--- a/pkg/analyzer_experimental/lib/src/generated/ast.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/ast.dart
@@ -116,7 +116,7 @@
     if (beginToken == null) {
       return -1;
     }
-    return beginToken.offset;
+    return this.beginToken.offset;
   }
 
   /**
@@ -484,8 +484,8 @@
    *
    * @param comment the documentation comment to be associated with this node
    */
-  void set documentationComment(Comment comment2) {
-    this._comment = becomeParentOf(comment2);
+  void set documentationComment(Comment comment) {
+    this._comment = becomeParentOf(comment);
   }
 
   /**
@@ -493,9 +493,9 @@
    *
    * @param metadata the metadata to be associated with this node
    */
-  void set metadata(List<Annotation> metadata2) {
+  void set metadata(List<Annotation> metadata) {
     this._metadata.clear();
-    this._metadata.addAll(metadata2);
+    this._metadata.addAll(metadata);
   }
   void visitChildren(ASTVisitor visitor) {
     if (commentIsBeforeAnnotations()) {
@@ -686,8 +686,8 @@
    *
    * @param arguments the arguments to the constructor being invoked
    */
-  void set arguments(ArgumentList arguments2) {
-    this._arguments = becomeParentOf(arguments2);
+  void set arguments(ArgumentList arguments) {
+    this._arguments = becomeParentOf(arguments);
   }
 
   /**
@@ -695,8 +695,8 @@
    *
    * @param constructorName the name of the constructor being invoked
    */
-  void set constructorName(SimpleIdentifier constructorName2) {
-    this._constructorName = becomeParentOf(constructorName2);
+  void set constructorName(SimpleIdentifier constructorName) {
+    this._constructorName = becomeParentOf(constructorName);
   }
 
   /**
@@ -704,8 +704,8 @@
    *
    * @param element the element to be associated with this identifier
    */
-  void set element(Element element2) {
-    this._element = element2;
+  void set element(Element element) {
+    this._element = element;
   }
 
   /**
@@ -714,8 +714,8 @@
    *
    * @param name the name of the constructor being invoked or the name of the field being referenced
    */
-  void set name(Identifier name2) {
-    this._name = becomeParentOf(name2);
+  void set name(Identifier name) {
+    this._name = becomeParentOf(name);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_name, visitor);
@@ -779,8 +779,8 @@
    *
    * @param identifier the identifier representing the argument being tested
    */
-  void set identifier(SimpleIdentifier identifier2) {
-    this._identifier = becomeParentOf(identifier2);
+  void set identifier(SimpleIdentifier identifier) {
+    this._identifier = becomeParentOf(identifier);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_identifier, visitor);
@@ -1046,8 +1046,8 @@
    *
    * @param expression the expression used to compute the value being cast
    */
-  void set expression(Expression expression2) {
-    this._expression = becomeParentOf(expression2);
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
   }
 
   /**
@@ -1143,8 +1143,8 @@
    *
    * @param the condition that is being asserted to be `true`
    */
-  void set condition(Expression condition2) {
-    this._condition = becomeParentOf(condition2);
+  void set condition(Expression condition) {
+    this._condition = becomeParentOf(condition);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_condition, visitor);
@@ -1655,8 +1655,8 @@
    *
    * @param block the block representing the body of the function
    */
-  void set block(Block block2) {
-    this._block = becomeParentOf(block2);
+  void set block(Block block) {
+    this._block = becomeParentOf(block);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_block, visitor);
@@ -1847,8 +1847,8 @@
    *
    * @param target the target of the cascade sections
    */
-  void set target(Expression target2) {
-    this._target = becomeParentOf(target2);
+  void set target(Expression target) {
+    this._target = becomeParentOf(target);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_target, visitor);
@@ -2214,8 +2214,8 @@
    *
    * @param extendsClause the extends clause for this class
    */
-  void set extendsClause(ExtendsClause extendsClause2) {
-    this._extendsClause = becomeParentOf(extendsClause2);
+  void set extendsClause(ExtendsClause extendsClause) {
+    this._extendsClause = becomeParentOf(extendsClause);
   }
 
   /**
@@ -2223,8 +2223,8 @@
    *
    * @param implementsClause the implements clause for the class
    */
-  void set implementsClause(ImplementsClause implementsClause2) {
-    this._implementsClause = becomeParentOf(implementsClause2);
+  void set implementsClause(ImplementsClause implementsClause) {
+    this._implementsClause = becomeParentOf(implementsClause);
   }
 
   /**
@@ -2241,8 +2241,8 @@
    *
    * @param withClause the with clause for the class
    */
-  void set withClause(WithClause withClause2) {
-    this._withClause = becomeParentOf(withClause2);
+  void set withClause(WithClause withClause) {
+    this._withClause = becomeParentOf(withClause);
   }
   void visitChildren(ASTVisitor visitor) {
     super.visitChildren(visitor);
@@ -2422,8 +2422,8 @@
    *
    * @param implementsClause the implements clause for this class
    */
-  void set implementsClause(ImplementsClause implementsClause2) {
-    this._implementsClause = becomeParentOf(implementsClause2);
+  void set implementsClause(ImplementsClause implementsClause) {
+    this._implementsClause = becomeParentOf(implementsClause);
   }
 
   /**
@@ -2431,8 +2431,8 @@
    *
    * @param name the name of the class being declared
    */
-  void set name(SimpleIdentifier name2) {
-    this._name = becomeParentOf(name2);
+  void set name(SimpleIdentifier name) {
+    this._name = becomeParentOf(name);
   }
 
   /**
@@ -2440,8 +2440,8 @@
    *
    * @param superclass the name of the superclass of the class being declared
    */
-  void set superclass(TypeName superclass2) {
-    this._superclass = becomeParentOf(superclass2);
+  void set superclass(TypeName superclass) {
+    this._superclass = becomeParentOf(superclass);
   }
 
   /**
@@ -2449,8 +2449,8 @@
    *
    * @param typeParameters the type parameters for the class
    */
-  void set typeParameters(TypeParameterList typeParameters2) {
-    this._typeParameters = becomeParentOf(typeParameters2);
+  void set typeParameters(TypeParameterList typeParameters) {
+    this._typeParameters = becomeParentOf(typeParameters);
   }
 
   /**
@@ -2458,8 +2458,8 @@
    *
    * @param withClause the with clause for this class
    */
-  void set withClause(WithClause withClause2) {
-    this._withClause = becomeParentOf(withClause2);
+  void set withClause(WithClause withClause) {
+    this._withClause = becomeParentOf(withClause);
   }
   void visitChildren(ASTVisitor visitor) {
     super.visitChildren(visitor);
@@ -2711,8 +2711,8 @@
    *
    * @param identifier the identifier being referenced
    */
-  void set identifier(Identifier identifier2) {
-    identifier2 = becomeParentOf(identifier2);
+  void set identifier(Identifier identifier) {
+    identifier = becomeParentOf(identifier);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_identifier, visitor);
@@ -2928,8 +2928,8 @@
    *
    * @param scriptTag the script tag at the beginning of the compilation unit
    */
-  void set scriptTag(ScriptTag scriptTag2) {
-    this._scriptTag = becomeParentOf(scriptTag2);
+  void set scriptTag(ScriptTag scriptTag) {
+    this._scriptTag = becomeParentOf(scriptTag);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_scriptTag, visitor);
@@ -3345,8 +3345,8 @@
    *
    * @param element the element associated with this constructor
    */
-  void set element(ConstructorElement element2) {
-    this._element = element2;
+  void set element(ConstructorElement element) {
+    this._element = element;
   }
 
   /**
@@ -3363,8 +3363,8 @@
    *
    * @param parameters the parameters associated with the constructor
    */
-  void set parameters(FormalParameterList parameters2) {
-    this._parameters = becomeParentOf(parameters2);
+  void set parameters(FormalParameterList parameters) {
+    this._parameters = becomeParentOf(parameters);
   }
 
   /**
@@ -3374,8 +3374,8 @@
    * @param redirectedConstructor the name of the constructor to which this constructor will be
    *          redirected
    */
-  void set redirectedConstructor(ConstructorName redirectedConstructor2) {
-    this._redirectedConstructor = becomeParentOf(redirectedConstructor2);
+  void set redirectedConstructor(ConstructorName redirectedConstructor) {
+    this._redirectedConstructor = becomeParentOf(redirectedConstructor);
   }
 
   /**
@@ -3396,9 +3396,9 @@
     safelyVisitChild(_body, visitor);
   }
   Token get firstTokenAfterCommentAndMetadata {
-    Token leftMost2 = leftMost([externalKeyword, constKeyword, factoryKeyword]);
-    if (leftMost2 != null) {
-      return leftMost2;
+    Token leftMost = this.leftMost([externalKeyword, constKeyword, factoryKeyword]);
+    if (leftMost != null) {
+      return leftMost;
     }
     return _returnType.beginToken;
   }
@@ -3518,8 +3518,8 @@
    *
    * @param expression the expression computing the value to which the field will be initialized
    */
-  void set expression(Expression expression2) {
-    this._expression = becomeParentOf(expression2);
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
   }
 
   /**
@@ -3644,8 +3644,8 @@
    *
    * @param name the name of the constructor
    */
-  void set name(SimpleIdentifier name2) {
-    this._name = becomeParentOf(name2);
+  void set name(SimpleIdentifier name) {
+    this._name = becomeParentOf(name);
   }
 
   /**
@@ -3663,8 +3663,8 @@
    *
    * @param type the name of the type defining the constructor
    */
-  void set type(TypeName type2) {
-    this._type = becomeParentOf(type2);
+  void set type(TypeName type) {
+    this._type = becomeParentOf(type);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_type, visitor);
@@ -3831,11 +3831,11 @@
   DeclaredIdentifier({Comment comment, List<Annotation> metadata, Token keyword, TypeName type, SimpleIdentifier identifier}) : this.full(comment, metadata, keyword, type, identifier);
   accept(ASTVisitor visitor) => visitor.visitDeclaredIdentifier(this);
   LocalVariableElement get element {
-    SimpleIdentifier identifier2 = identifier;
-    if (identifier2 == null) {
+    SimpleIdentifier identifier = this.identifier;
+    if (identifier == null) {
       return null;
     }
-    return identifier2.staticElement as LocalVariableElement;
+    return identifier.staticElement as LocalVariableElement;
   }
   Token get endToken => identifier.endToken;
 
@@ -3990,8 +3990,8 @@
    *
    * @param kind the kind of this parameter
    */
-  void set kind(ParameterKind kind2) {
-    this._kind = kind2;
+  void set kind(ParameterKind kind) {
+    this._kind = kind;
   }
 
   /**
@@ -4381,9 +4381,9 @@
   ExportDirective({Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, List<Combinator> combinators, Token semicolon}) : this.full(comment, metadata, keyword, libraryUri, combinators, semicolon);
   accept(ASTVisitor visitor) => visitor.visitExportDirective(this);
   LibraryElement get uriElement {
-    Element element2 = element;
-    if (element2 is ExportElement) {
-      return ((element2 as ExportElement)).exportedLibrary;
+    Element element = this.element;
+    if (element is ExportElement) {
+      return ((element as ExportElement)).exportedLibrary;
     }
     return null;
   }
@@ -4605,8 +4605,8 @@
    *
    * @param expression the expression representing the body of the function
    */
-  void set expression(Expression expression2) {
-    this._expression = becomeParentOf(expression2);
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_expression, visitor);
@@ -4675,8 +4675,8 @@
    *
    * @param expression the expression that comprises the statement
    */
-  void set expression(Expression expression2) {
-    this._expression = becomeParentOf(expression2);
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_expression, visitor);
@@ -4946,8 +4946,8 @@
    *
    * @param parameters the parameters of the function-typed parameter
    */
-  void set parameters(FormalParameterList parameters2) {
-    this._parameters = becomeParentOf(parameters2);
+  void set parameters(FormalParameterList parameters) {
+    this._parameters = becomeParentOf(parameters);
   }
 
   /**
@@ -5120,8 +5120,8 @@
    *
    * @param body the body of the loop
    */
-  void set body(Statement body2) {
-    this._body = becomeParentOf(body2);
+  void set body(Statement body) {
+    this._body = becomeParentOf(body);
   }
 
   /**
@@ -5129,8 +5129,8 @@
    *
    * @param identifier the loop variable
    */
-  void set identifier(SimpleIdentifier identifier2) {
-    this._identifier = becomeParentOf(identifier2);
+  void set identifier(SimpleIdentifier identifier) {
+    this._identifier = becomeParentOf(identifier);
   }
 
   /**
@@ -5312,8 +5312,8 @@
    *
    * @param body the body of the loop
    */
-  void set body(Statement body2) {
-    this._body = becomeParentOf(body2);
+  void set body(Statement body) {
+    this._body = becomeParentOf(body);
   }
 
   /**
@@ -5330,8 +5330,8 @@
    *
    * @param initialization the initialization expression
    */
-  void set initialization(Expression initialization2) {
-    this._initialization = becomeParentOf(initialization2);
+  void set initialization(Expression initialization) {
+    this._initialization = becomeParentOf(initialization);
   }
 
   /**
@@ -5722,8 +5722,8 @@
    *
    * @param functionExpression the function expression being wrapped
    */
-  void set functionExpression(FunctionExpression functionExpression2) {
-    functionExpression2 = becomeParentOf(functionExpression2);
+  void set functionExpression(FunctionExpression functionExpression) {
+    functionExpression = becomeParentOf(functionExpression);
   }
 
   /**
@@ -5800,8 +5800,8 @@
    *
    * @param functionDeclaration the function declaration being wrapped
    */
-  void set functionExpression(FunctionDeclaration functionDeclaration2) {
-    this.functionDeclaration = becomeParentOf(functionDeclaration2);
+  void set functionExpression(FunctionDeclaration functionDeclaration) {
+    this.functionDeclaration = becomeParentOf(functionDeclaration);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(functionDeclaration, visitor);
@@ -5899,8 +5899,8 @@
    *
    * @param parameters the parameters associated with the function
    */
-  void set parameters(FormalParameterList parameters2) {
-    this._parameters = becomeParentOf(parameters2);
+  void set parameters(FormalParameterList parameters) {
+    this._parameters = becomeParentOf(parameters);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_parameters, visitor);
@@ -6012,8 +6012,8 @@
    *
    * @param argumentList the list of arguments to the method
    */
-  void set argumentList(ArgumentList argumentList2) {
-    this._argumentList = becomeParentOf(argumentList2);
+  void set argumentList(ArgumentList argumentList) {
+    this._argumentList = becomeParentOf(argumentList);
   }
 
   /**
@@ -6021,8 +6021,8 @@
    *
    * @param function the expression producing the function being invoked
    */
-  void set function(Expression function2) {
-    function2 = becomeParentOf(function2);
+  void set function(Expression function) {
+    function = becomeParentOf(function);
   }
 
   /**
@@ -6146,8 +6146,8 @@
    *
    * @param name the name of the function type being declared
    */
-  void set name(SimpleIdentifier name2) {
-    this._name = becomeParentOf(name2);
+  void set name(SimpleIdentifier name) {
+    this._name = becomeParentOf(name);
   }
 
   /**
@@ -6155,8 +6155,8 @@
    *
    * @param parameters the parameters associated with the function type
    */
-  void set parameters(FormalParameterList parameters2) {
-    this._parameters = becomeParentOf(parameters2);
+  void set parameters(FormalParameterList parameters) {
+    this._parameters = becomeParentOf(parameters);
   }
 
   /**
@@ -6173,8 +6173,8 @@
    *
    * @param typeParameters the type parameters for the function type
    */
-  void set typeParameters(TypeParameterList typeParameters2) {
-    this._typeParameters = becomeParentOf(typeParameters2);
+  void set typeParameters(TypeParameterList typeParameters) {
+    this._typeParameters = becomeParentOf(typeParameters);
   }
   void visitChildren(ASTVisitor visitor) {
     super.visitChildren(visitor);
@@ -6264,8 +6264,8 @@
    *
    * @param parameters the parameters of the function-typed parameter
    */
-  void set parameters(FormalParameterList parameters2) {
-    this._parameters = becomeParentOf(parameters2);
+  void set parameters(FormalParameterList parameters) {
+    this._parameters = becomeParentOf(parameters);
   }
 
   /**
@@ -6273,8 +6273,8 @@
    *
    * @param returnType the return type of the function
    */
-  void set returnType(TypeName returnType2) {
-    this._returnType = becomeParentOf(returnType2);
+  void set returnType(TypeName returnType) {
+    this._returnType = becomeParentOf(returnType);
   }
   void visitChildren(ASTVisitor visitor) {
     super.visitChildren(visitor);
@@ -6724,9 +6724,9 @@
    */
   SimpleIdentifier get prefix => _prefix;
   LibraryElement get uriElement {
-    Element element2 = element;
-    if (element2 is ImportElement) {
-      return ((element2 as ImportElement)).importedLibrary;
+    Element element = this.element;
+    if (element is ImportElement) {
+      return ((element as ImportElement)).importedLibrary;
     }
     return null;
   }
@@ -6736,8 +6736,8 @@
    *
    * @param prefix the prefix to be used with the imported names
    */
-  void set prefix(SimpleIdentifier prefix2) {
-    this._prefix = becomeParentOf(prefix2);
+  void set prefix(SimpleIdentifier prefix) {
+    this._prefix = becomeParentOf(prefix);
   }
   void visitChildren(ASTVisitor visitor) {
     super.visitChildren(visitor);
@@ -7184,8 +7184,8 @@
    *
    * @param argumentList the list of arguments to the constructor
    */
-  void set argumentList(ArgumentList argumentList2) {
-    this._argumentList = becomeParentOf(argumentList2);
+  void set argumentList(ArgumentList argumentList) {
+    this._argumentList = becomeParentOf(argumentList);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(constructorName, visitor);
@@ -7333,8 +7333,8 @@
    *
    * @param expression the expression to be evaluated for the value to be converted into a string
    */
-  void set expression(Expression expression2) {
-    this._expression = becomeParentOf(expression2);
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_expression, visitor);
@@ -7499,8 +7499,8 @@
    *
    * @param expression the expression used to compute the value whose type is being tested
    */
-  void set expression(Expression expression2) {
-    this._expression = becomeParentOf(expression2);
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
   }
 
   /**
@@ -7572,8 +7572,8 @@
    *
    * @param label the label being associated with the statement
    */
-  void set label(SimpleIdentifier label2) {
-    this._label = becomeParentOf(label2);
+  void set label(SimpleIdentifier label) {
+    this._label = becomeParentOf(label);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_label, visitor);
@@ -7642,8 +7642,8 @@
    *
    * @param statement the statement with which the labels are being associated
    */
-  void set statement(Statement statement2) {
-    this._statement = becomeParentOf(statement2);
+  void set statement(Statement statement) {
+    this._statement = becomeParentOf(statement);
   }
   void visitChildren(ASTVisitor visitor) {
     labels.accept(visitor);
@@ -7718,8 +7718,8 @@
    *
    * @param name the name of the library being defined
    */
-  void set name(LibraryIdentifier name2) {
-    this._name = becomeParentOf(name2);
+  void set name(LibraryIdentifier name) {
+    this._name = becomeParentOf(name);
   }
   void visitChildren(ASTVisitor visitor) {
     super.visitChildren(visitor);
@@ -7844,9 +7844,9 @@
     if (token != null) {
       return token;
     }
-    TypeArgumentList typeArguments2 = typeArguments;
-    if (typeArguments2 != null) {
-      return typeArguments2.beginToken;
+    TypeArgumentList typeArguments = this.typeArguments;
+    if (typeArguments != null) {
+      return typeArguments.beginToken;
     }
     return _leftBracket;
   }
@@ -7968,9 +7968,9 @@
     if (token != null) {
       return token;
     }
-    TypeArgumentList typeArguments2 = typeArguments;
-    if (typeArguments2 != null) {
-      return typeArguments2.beginToken;
+    TypeArgumentList typeArguments = this.typeArguments;
+    if (typeArguments != null) {
+      return typeArguments.beginToken;
     }
     return _leftBracket;
   }
@@ -8308,8 +8308,8 @@
    *
    * @param parameters the parameters associated with the method
    */
-  void set parameters(FormalParameterList parameters2) {
-    this._parameters = becomeParentOf(parameters2);
+  void set parameters(FormalParameterList parameters) {
+    this._parameters = becomeParentOf(parameters);
   }
 
   /**
@@ -8474,8 +8474,8 @@
    *
    * @param argumentList the list of arguments to the method
    */
-  void set argumentList(ArgumentList argumentList2) {
-    this._argumentList = becomeParentOf(argumentList2);
+  void set argumentList(ArgumentList argumentList) {
+    this._argumentList = becomeParentOf(argumentList);
   }
 
   /**
@@ -8580,8 +8580,8 @@
    *
    * @param expression the expression with which the name is associated
    */
-  void set expression(Expression expression2) {
-    this._expression = becomeParentOf(expression2);
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
   }
 
   /**
@@ -8849,8 +8849,8 @@
    *
    * @param comment the documentation comment to be associated with this parameter
    */
-  void set documentationComment(Comment comment2) {
-    this._comment = becomeParentOf(comment2);
+  void set documentationComment(Comment comment) {
+    this._comment = becomeParentOf(comment);
   }
 
   /**
@@ -8858,8 +8858,8 @@
    *
    * @param identifier the name of the parameter being declared
    */
-  void set identifier(SimpleIdentifier identifier2) {
-    this._identifier = becomeParentOf(identifier2);
+  void set identifier(SimpleIdentifier identifier) {
+    this._identifier = becomeParentOf(identifier);
   }
   void visitChildren(ASTVisitor visitor) {
     if (commentIsBeforeAnnotations()) {
@@ -9017,8 +9017,8 @@
    *
    * @param expression the expression within the parentheses
    */
-  void set expression(Expression expression2) {
-    this._expression = becomeParentOf(expression2);
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
   }
 
   /**
@@ -9170,8 +9170,8 @@
    *
    * @param libraryName the name of the library that the containing compilation unit is part of
    */
-  void set libraryName(LibraryIdentifier libraryName2) {
-    this._libraryName = becomeParentOf(libraryName2);
+  void set libraryName(LibraryIdentifier libraryName) {
+    this._libraryName = becomeParentOf(libraryName);
   }
   void visitChildren(ASTVisitor visitor) {
     super.visitChildren(visitor);
@@ -9621,8 +9621,8 @@
    *
    * @param identifier the identifier being prefixed
    */
-  void set identifier(SimpleIdentifier identifier2) {
-    this._identifier = becomeParentOf(identifier2);
+  void set identifier(SimpleIdentifier identifier) {
+    this._identifier = becomeParentOf(identifier);
   }
 
   /**
@@ -9863,8 +9863,8 @@
    *
    * @param argumentList the list of arguments to the constructor
    */
-  void set argumentList(ArgumentList argumentList2) {
-    this._argumentList = becomeParentOf(argumentList2);
+  void set argumentList(ArgumentList argumentList) {
+    this._argumentList = becomeParentOf(argumentList);
   }
 
   /**
@@ -9984,8 +9984,8 @@
    *
    * @param expression the expression computing the value to be returned
    */
-  void set expression(Expression expression2) {
-    this._expression = becomeParentOf(expression2);
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_expression, visitor);
@@ -10710,8 +10710,8 @@
    *
    * @param argumentList the list of arguments to the constructor
    */
-  void set argumentList(ArgumentList argumentList2) {
-    this._argumentList = becomeParentOf(argumentList2);
+  void set argumentList(ArgumentList argumentList) {
+    this._argumentList = becomeParentOf(argumentList);
   }
 
   /**
@@ -10819,8 +10819,8 @@
    *
    * @param expression the expression controlling whether the statements will be executed
    */
-  void set expression(Expression expression2) {
-    this._expression = becomeParentOf(expression2);
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor visitor) {
     labels.accept(visitor);
@@ -11036,8 +11036,8 @@
    *
    * @param expression the expression used to determine which of the switch members will be selected
    */
-  void set expression(Expression expression2) {
-    this._expression = becomeParentOf(expression2);
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_expression, visitor);
@@ -11189,8 +11189,8 @@
    *
    * @param expression the expression computing the exception to be thrown
    */
-  void set expression(Expression expression2) {
-    this._expression = becomeParentOf(expression2);
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_expression, visitor);
@@ -11582,8 +11582,8 @@
    *
    * @param typeArguments the type arguments associated with the type
    */
-  void set typeArguments(TypeArgumentList typeArguments2) {
-    this._typeArguments = becomeParentOf(typeArguments2);
+  void set typeArguments(TypeArgumentList typeArguments) {
+    this._typeArguments = becomeParentOf(typeArguments);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_name, visitor);
@@ -11858,8 +11858,8 @@
    *
    * @param uri the URI referenced by this directive
    */
-  void set uri(StringLiteral uri2) {
-    this._uri = becomeParentOf(uri2);
+  void set uri(StringLiteral uri) {
+    this._uri = becomeParentOf(uri);
   }
   void visitChildren(ASTVisitor visitor) {
     super.visitChildren(visitor);
@@ -11990,8 +11990,8 @@
    *
    * @param initializer the expression used to compute the initial value for the variable
    */
-  void set initializer(Expression initializer2) {
-    this._initializer = becomeParentOf(initializer2);
+  void set initializer(Expression initializer) {
+    this._initializer = becomeParentOf(initializer);
   }
 
   /**
@@ -11999,8 +11999,8 @@
    *
    * @param name the name of the variable being declared
    */
-  void set name(SimpleIdentifier name2) {
-    this._name = becomeParentOf(name2);
+  void set name(SimpleIdentifier name) {
+    this._name = becomeParentOf(name);
   }
   void visitChildren(ASTVisitor visitor) {
     super.visitChildren(visitor);
@@ -12174,8 +12174,8 @@
    *
    * @param variableList the variables being declared
    */
-  void set variables(VariableDeclarationList variableList2) {
-    this._variableList = becomeParentOf(variableList2);
+  void set variables(VariableDeclarationList variableList) {
+    this._variableList = becomeParentOf(variableList);
   }
   void visitChildren(ASTVisitor visitor) {
     safelyVisitChild(_variableList, visitor);
@@ -12336,8 +12336,8 @@
    *
    * @param withKeyword the token representing the 'with' keyword
    */
-  void set mixinKeyword(Token withKeyword2) {
-    this.withKeyword = withKeyword2;
+  void set mixinKeyword(Token withKeyword) {
+    this.withKeyword = withKeyword;
   }
   void visitChildren(ASTVisitor visitor) {
     mixinTypes.accept(visitor);
diff --git a/pkg/analyzer_experimental/lib/src/generated/constant.dart b/pkg/analyzer_experimental/lib/src/generated/constant.dart
index ac6bf34..2403231 100644
--- a/pkg/analyzer_experimental/lib/src/generated/constant.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/constant.dart
@@ -1103,16 +1103,16 @@
     return value.toString();
   }
   EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyNum || !leftOperand2.isAnyNum) {
+  EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyNum || !leftOperand.isAnyNum) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
     }
-    if (isSomeInt || leftOperand2.isSomeInt) {
+    if (isSomeInt || leftOperand.isSomeInt) {
       return RESULT_INT;
-    } else if (isSomeNum || leftOperand2.isSomeNum) {
+    } else if (isSomeNum || leftOperand.isSomeNum) {
       return RESULT_NUM;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1137,14 +1137,14 @@
     return error(node);
   }
   EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyInt || !leftOperand2.isAnyInt) {
+  EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyInt || !leftOperand.isAnyInt) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
     }
-    if (isSomeInt || leftOperand2.isSomeInt) {
+    if (isSomeInt || leftOperand.isSomeInt) {
       return RESULT_INT;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1161,14 +1161,14 @@
     return union(error(node.leftOperand), error(node.rightOperand));
   }
   EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyInt || !leftOperand2.isAnyInt) {
+  EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyInt || !leftOperand.isAnyInt) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
     }
-    if (isSomeInt || leftOperand2.isSomeInt) {
+    if (isSomeInt || leftOperand.isSomeInt) {
       return RESULT_INT;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1185,14 +1185,14 @@
     return union(error(node.leftOperand), error(node.rightOperand));
   }
   EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyInt || !leftOperand2.isAnyInt) {
+  EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyInt || !leftOperand.isAnyInt) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
     }
-    if (isSomeInt || leftOperand2.isSomeInt) {
+    if (isSomeInt || leftOperand.isSomeInt) {
       return RESULT_INT;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1217,14 +1217,14 @@
     return error(node);
   }
   EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyNum || !leftOperand2.isAnyNum) {
+  EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyNum || !leftOperand.isAnyNum) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
     }
-    if (isSomeNum || leftOperand2.isSomeNum) {
+    if (isSomeNum || leftOperand.isSomeNum) {
       return RESULT_NUM;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1286,14 +1286,14 @@
   }
   EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyNum || !leftOperand2.isAnyNum) {
+  EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyNum || !leftOperand.isAnyNum) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
     }
-    if (isSomeNum || leftOperand2.isSomeNum) {
+    if (isSomeNum || leftOperand.isSomeNum) {
       return RESULT_BOOL;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1313,14 +1313,14 @@
     }
     return error(node);
   }
-  EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyNum || !leftOperand2.isAnyNum) {
+  EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyNum || !leftOperand.isAnyNum) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
     }
-    if (isSomeNum || leftOperand2.isSomeNum) {
+    if (isSomeNum || leftOperand.isSomeNum) {
       return RESULT_BOOL;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1341,14 +1341,14 @@
     return error(node);
   }
   EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyNum || !leftOperand2.isAnyNum) {
+  EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyNum || !leftOperand.isAnyNum) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
     }
-    if (isSomeNum || leftOperand2.isSomeNum) {
+    if (isSomeNum || leftOperand.isSomeNum) {
       return RESULT_INT;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1376,14 +1376,14 @@
   }
   EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
   EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyNum || !leftOperand2.isAnyNum) {
+  EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyNum || !leftOperand.isAnyNum) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
     }
-    if (isSomeNum || leftOperand2.isSomeNum) {
+    if (isSomeNum || leftOperand.isSomeNum) {
       return RESULT_BOOL;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1403,14 +1403,14 @@
     }
     return error(node);
   }
-  EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyNum || !leftOperand2.isAnyNum) {
+  EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyNum || !leftOperand.isAnyNum) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
     }
-    if (isSomeNum || leftOperand2.isSomeNum) {
+    if (isSomeNum || leftOperand.isSomeNum) {
       return RESULT_BOOL;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1462,16 +1462,16 @@
     return booleanConversion(node.rightOperand, value);
   }
   EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyNum || !leftOperand2.isAnyNum) {
+  EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyNum || !leftOperand.isAnyNum) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
     }
-    if (isSomeInt || leftOperand2.isSomeInt) {
+    if (isSomeInt || leftOperand.isSomeInt) {
       return RESULT_INT;
-    } else if (isSomeNum || leftOperand2.isSomeNum) {
+    } else if (isSomeNum || leftOperand.isSomeNum) {
       return RESULT_NUM;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1527,16 +1527,16 @@
     return RESULT_TRUE;
   }
   EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyNum || !leftOperand2.isAnyNum) {
+  EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyNum || !leftOperand.isAnyNum) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
     }
-    if (isSomeInt || leftOperand2.isSomeInt) {
+    if (isSomeInt || leftOperand.isSomeInt) {
       return RESULT_INT;
-    } else if (isSomeNum || leftOperand2.isSomeNum) {
+    } else if (isSomeNum || leftOperand.isSomeNum) {
       return RESULT_NUM;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1560,14 +1560,14 @@
     return error(node);
   }
   EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyInt || !leftOperand2.isAnyInt) {
+  EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyInt || !leftOperand.isAnyInt) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
     }
-    if (isSomeInt || leftOperand2.isSomeInt) {
+    if (isSomeInt || leftOperand.isSomeInt) {
       return RESULT_INT;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1584,14 +1584,14 @@
     return union(error(node.leftOperand), error(node.rightOperand));
   }
   EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyInt || !leftOperand2.isAnyInt) {
+  EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyInt || !leftOperand.isAnyInt) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
     }
-    if (isSomeInt || leftOperand2.isSomeInt) {
+    if (isSomeInt || leftOperand.isSomeInt) {
       return RESULT_INT;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
@@ -1608,16 +1608,16 @@
     return union(error(node.leftOperand), error(node.rightOperand));
   }
   EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand) => leftOperand;
-  EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand2) {
-    if (!isAnyNum || !leftOperand2.isAnyNum) {
+  EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand) {
+    if (!isAnyNum || !leftOperand.isAnyNum) {
       return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
     }
-    if (isSomeInt || leftOperand2.isSomeInt) {
+    if (isSomeInt || leftOperand.isSomeInt) {
       return RESULT_INT;
-    } else if (isSomeNum || leftOperand2.isSomeNum) {
+    } else if (isSomeNum || leftOperand.isSomeNum) {
       return RESULT_NUM;
     }
-    Object leftValue = leftOperand2.value;
+    Object leftValue = leftOperand.value;
     if (leftValue == null) {
       return error(node.leftOperand);
     } else if (value == null) {
diff --git a/pkg/analyzer_experimental/lib/src/generated/element.dart b/pkg/analyzer_experimental/lib/src/generated/element.dart
index fa3c4be..776fbf2 100644
--- a/pkg/analyzer_experimental/lib/src/generated/element.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/element.dart
@@ -1812,29 +1812,29 @@
     collectAllSupertypes(list);
     return new List.from(list);
   }
-  ElementImpl getChild(String identifier2) {
+  ElementImpl getChild(String identifier) {
     for (PropertyAccessorElement accessor in _accessors) {
-      if (((accessor as PropertyAccessorElementImpl)).identifier == identifier2) {
+      if (((accessor as PropertyAccessorElementImpl)).identifier == identifier) {
         return accessor as PropertyAccessorElementImpl;
       }
     }
     for (ConstructorElement constructor in _constructors) {
-      if (((constructor as ConstructorElementImpl)).identifier == identifier2) {
+      if (((constructor as ConstructorElementImpl)).identifier == identifier) {
         return constructor as ConstructorElementImpl;
       }
     }
     for (FieldElement field in _fields) {
-      if (((field as FieldElementImpl)).identifier == identifier2) {
+      if (((field as FieldElementImpl)).identifier == identifier) {
         return field as FieldElementImpl;
       }
     }
     for (MethodElement method in _methods) {
-      if (((method as MethodElementImpl)).identifier == identifier2) {
+      if (((method as MethodElementImpl)).identifier == identifier) {
         return method as MethodElementImpl;
       }
     }
     for (TypeParameterElement typeParameter in _typeParameters) {
-      if (((typeParameter as TypeParameterElementImpl)).identifier == identifier2) {
+      if (((typeParameter as TypeParameterElementImpl)).identifier == identifier) {
         return typeParameter as TypeParameterElementImpl;
       }
     }
@@ -1849,9 +1849,9 @@
    * @param name some name to lookup a field element with
    * @return the matching field element, or `null` if no such element was found
    */
-  FieldElement getField(String name2) {
+  FieldElement getField(String name) {
     for (FieldElement fieldElement in _fields) {
-      if (name2 == fieldElement.name) {
+      if (name == fieldElement.name) {
         return fieldElement;
       }
     }
@@ -1878,10 +1878,10 @@
   }
   List<MethodElement> get methods => _methods;
   List<InterfaceType> get mixins => _mixins;
-  ConstructorElement getNamedConstructor(String name2) {
+  ConstructorElement getNamedConstructor(String name) {
     for (ConstructorElement element in constructors) {
       String elementName = element.name;
-      if (elementName != null && elementName == name2) {
+      if (elementName != null && elementName == name) {
         return element;
       }
     }
@@ -2034,11 +2034,11 @@
    *
    * @param accessors the accessors contained in this class
    */
-  void set accessors(List<PropertyAccessorElement> accessors2) {
-    for (PropertyAccessorElement accessor in accessors2) {
+  void set accessors(List<PropertyAccessorElement> accessors) {
+    for (PropertyAccessorElement accessor in accessors) {
       ((accessor as PropertyAccessorElementImpl)).enclosingElement = this;
     }
-    this._accessors = accessors2;
+    this._accessors = accessors;
   }
 
   /**
@@ -2046,11 +2046,11 @@
    *
    * @param constructors the constructors contained in this class
    */
-  void set constructors(List<ConstructorElement> constructors2) {
-    for (ConstructorElement constructor in constructors2) {
+  void set constructors(List<ConstructorElement> constructors) {
+    for (ConstructorElement constructor in constructors) {
       ((constructor as ConstructorElementImpl)).enclosingElement = this;
     }
-    this._constructors = constructors2;
+    this._constructors = constructors;
   }
 
   /**
@@ -2058,11 +2058,11 @@
    *
    * @param fields the fields contained in this class
    */
-  void set fields(List<FieldElement> fields2) {
-    for (FieldElement field in fields2) {
+  void set fields(List<FieldElement> fields) {
+    for (FieldElement field in fields) {
       ((field as FieldElementImpl)).enclosingElement = this;
     }
-    this._fields = fields2;
+    this._fields = fields;
   }
 
   /**
@@ -2079,8 +2079,8 @@
    *
    * @param the interfaces that are implemented by this class
    */
-  void set interfaces(List<InterfaceType> interfaces2) {
-    this._interfaces = interfaces2;
+  void set interfaces(List<InterfaceType> interfaces) {
+    this._interfaces = interfaces;
   }
 
   /**
@@ -2088,11 +2088,11 @@
    *
    * @param methods the methods contained in this class
    */
-  void set methods(List<MethodElement> methods2) {
-    for (MethodElement method in methods2) {
+  void set methods(List<MethodElement> methods) {
+    for (MethodElement method in methods) {
       ((method as MethodElementImpl)).enclosingElement = this;
     }
-    this._methods = methods2;
+    this._methods = methods;
   }
 
   /**
@@ -2101,8 +2101,8 @@
    *
    * @param mixins the mixins that are applied to derive the superclass of this class
    */
-  void set mixins(List<InterfaceType> mixins2) {
-    this._mixins = mixins2;
+  void set mixins(List<InterfaceType> mixins) {
+    this._mixins = mixins;
   }
 
   /**
@@ -2110,8 +2110,8 @@
    *
    * @param supertype the superclass of the class
    */
-  void set supertype(InterfaceType supertype2) {
-    this._supertype = supertype2;
+  void set supertype(InterfaceType supertype) {
+    this._supertype = supertype;
   }
 
   /**
@@ -2119,8 +2119,8 @@
    *
    * @param type the type defined by the class
    */
-  void set type(InterfaceType type2) {
-    this._type = type2;
+  void set type(InterfaceType type) {
+    this._type = type;
   }
 
   /**
@@ -2137,11 +2137,11 @@
    *
    * @param typeParameters the type parameters defined for this class
    */
-  void set typeParameters(List<TypeParameterElement> typeParameters2) {
-    for (TypeParameterElement typeParameter in typeParameters2) {
+  void set typeParameters(List<TypeParameterElement> typeParameters) {
+    for (TypeParameterElement typeParameter in typeParameters) {
       ((typeParameter as TypeParameterElementImpl)).enclosingElement = this;
     }
-    this._typeParameters = typeParameters2;
+    this._typeParameters = typeParameters;
   }
 
   /**
@@ -2267,29 +2267,29 @@
   accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this);
   bool operator ==(Object object) => object != null && runtimeType == object.runtimeType && _source == ((object as CompilationUnitElementImpl)).source;
   List<PropertyAccessorElement> get accessors => _accessors;
-  ElementImpl getChild(String identifier2) {
+  ElementImpl getChild(String identifier) {
     for (PropertyAccessorElement accessor in _accessors) {
-      if (((accessor as PropertyAccessorElementImpl)).identifier == identifier2) {
+      if (((accessor as PropertyAccessorElementImpl)).identifier == identifier) {
         return accessor as PropertyAccessorElementImpl;
       }
     }
     for (VariableElement variable in _variables) {
-      if (((variable as VariableElementImpl)).identifier == identifier2) {
+      if (((variable as VariableElementImpl)).identifier == identifier) {
         return variable as VariableElementImpl;
       }
     }
     for (ExecutableElement function in _functions) {
-      if (((function as ExecutableElementImpl)).identifier == identifier2) {
+      if (((function as ExecutableElementImpl)).identifier == identifier) {
         return function as ExecutableElementImpl;
       }
     }
     for (FunctionTypeAliasElement typeAlias in _typeAliases) {
-      if (((typeAlias as FunctionTypeAliasElementImpl)).identifier == identifier2) {
+      if (((typeAlias as FunctionTypeAliasElementImpl)).identifier == identifier) {
         return typeAlias as FunctionTypeAliasElementImpl;
       }
     }
     for (ClassElement type in _types) {
-      if (((type as ClassElementImpl)).identifier == identifier2) {
+      if (((type as ClassElementImpl)).identifier == identifier) {
         return type as ClassElementImpl;
       }
     }
@@ -2320,11 +2320,11 @@
    *
    * @param the top-level accessors (getters and setters) contained in this compilation unit
    */
-  void set accessors(List<PropertyAccessorElement> accessors2) {
-    for (PropertyAccessorElement accessor in accessors2) {
+  void set accessors(List<PropertyAccessorElement> accessors) {
+    for (PropertyAccessorElement accessor in accessors) {
       ((accessor as PropertyAccessorElementImpl)).enclosingElement = this;
     }
-    this._accessors = accessors2;
+    this._accessors = accessors;
   }
 
   /**
@@ -2332,11 +2332,11 @@
    *
    * @param functions the top-level functions contained in this compilation unit
    */
-  void set functions(List<FunctionElement> functions2) {
-    for (FunctionElement function in functions2) {
+  void set functions(List<FunctionElement> functions) {
+    for (FunctionElement function in functions) {
       ((function as FunctionElementImpl)).enclosingElement = this;
     }
-    this._functions = functions2;
+    this._functions = functions;
   }
 
   /**
@@ -2344,8 +2344,8 @@
    *
    * @param source the source that corresponds to this compilation unit
    */
-  void set source(Source source2) {
-    this._source = source2;
+  void set source(Source source) {
+    this._source = source;
   }
 
   /**
@@ -2353,11 +2353,11 @@
    *
    * @param variables the top-level variables contained in this compilation unit
    */
-  void set topLevelVariables(List<TopLevelVariableElement> variables2) {
-    for (TopLevelVariableElement field in variables2) {
+  void set topLevelVariables(List<TopLevelVariableElement> variables) {
+    for (TopLevelVariableElement field in variables) {
       ((field as TopLevelVariableElementImpl)).enclosingElement = this;
     }
-    this._variables = variables2;
+    this._variables = variables;
   }
 
   /**
@@ -2365,11 +2365,11 @@
    *
    * @param typeAliases the function type aliases contained in this compilation unit
    */
-  void set typeAliases(List<FunctionTypeAliasElement> typeAliases2) {
-    for (FunctionTypeAliasElement typeAlias in typeAliases2) {
+  void set typeAliases(List<FunctionTypeAliasElement> typeAliases) {
+    for (FunctionTypeAliasElement typeAlias in typeAliases) {
       ((typeAlias as FunctionTypeAliasElementImpl)).enclosingElement = this;
     }
-    this._typeAliases = typeAliases2;
+    this._typeAliases = typeAliases;
   }
 
   /**
@@ -2377,11 +2377,11 @@
    *
    * @param types types contained in this compilation unit
    */
-  void set types(List<ClassElement> types2) {
-    for (ClassElement type in types2) {
+  void set types(List<ClassElement> types) {
+    for (ClassElement type in types) {
       ((type as ClassElementImpl)).enclosingElement = this;
     }
-    this._types = types2;
+    this._types = types;
   }
 
   /**
@@ -2389,8 +2389,8 @@
    *
    * @param uri the URI that is specified by the "part" directive in the enclosing library.
    */
-  void set uri(String uri2) {
-    this._uri = uri2;
+  void set uri(String uri) {
+    this._uri = uri;
   }
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -2426,8 +2426,8 @@
    */
   ConstFieldElementImpl(Identifier name) : super.con1(name);
   EvaluationResultImpl get evaluationResult => _result;
-  void set evaluationResult(EvaluationResultImpl result2) {
-    this._result = result2;
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
   }
 }
 /**
@@ -2450,8 +2450,8 @@
    */
   ConstLocalVariableElementImpl(Identifier name) : super(name);
   EvaluationResultImpl get evaluationResult => _result;
-  void set evaluationResult(EvaluationResultImpl result2) {
-    this._result = result2;
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
   }
 }
 /**
@@ -2472,8 +2472,8 @@
    */
   ConstTopLevelVariableElementImpl(Identifier name) : super.con1(name);
   EvaluationResultImpl get evaluationResult => _result;
-  void set evaluationResult(EvaluationResultImpl result2) {
-    this._result = result2;
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
   }
 }
 /**
@@ -2542,8 +2542,8 @@
    *
    * @param redirectedConstructor the constructor to which this constructor is redirecting
    */
-  void set redirectedConstructor(ConstructorElement redirectedConstructor2) {
-    this._redirectedConstructor = redirectedConstructor2;
+  void set redirectedConstructor(ConstructorElement redirectedConstructor) {
+    this._redirectedConstructor = redirectedConstructor;
   }
   void appendTo(JavaStringBuilder builder) {
     builder.append(enclosingElement.displayName);
@@ -2575,8 +2575,8 @@
    */
   DefaultFieldFormalParameterElementImpl(Identifier name) : super(name);
   EvaluationResultImpl get evaluationResult => _result;
-  void set evaluationResult(EvaluationResultImpl result2) {
-    this._result = result2;
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
   }
 }
 /**
@@ -2599,8 +2599,8 @@
    */
   DefaultParameterElementImpl(Identifier name) : super.con1(name);
   EvaluationResultImpl get evaluationResult => _result;
-  void set evaluationResult(EvaluationResultImpl result2) {
-    this._result = result2;
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
   }
 }
 /**
@@ -2770,9 +2770,9 @@
     }
     return _cachedHashCode;
   }
-  bool isAccessibleIn(LibraryElement library2) {
+  bool isAccessibleIn(LibraryElement library) {
     if (Identifier.isPrivateName(_name)) {
-      return library2 == library;
+      return library == this.library;
     }
     return true;
   }
@@ -2783,8 +2783,8 @@
    *
    * @param metadata the metadata to be associated with this element
    */
-  void set metadata(List<ElementAnnotation> metadata2) {
-    this._metadata = metadata2;
+  void set metadata(List<ElementAnnotation> metadata) {
+    this._metadata = metadata;
   }
 
   /**
@@ -2794,8 +2794,8 @@
    *
    * @param nameOffset the offset to the beginning of the name
    */
-  void set nameOffset(int nameOffset2) {
-    this._nameOffset = nameOffset2;
+  void set nameOffset(int nameOffset) {
+    this._nameOffset = nameOffset;
   }
 
   /**
@@ -3092,9 +3092,9 @@
    *
    * @param scriptLibrary the library or `null` if none
    */
-  void set scriptLibrary(LibraryElementImpl scriptLibrary2) {
-    scriptLibrary2.enclosingElement = this;
-    this._scriptLibrary = scriptLibrary2;
+  void set scriptLibrary(LibraryElementImpl scriptLibrary) {
+    scriptLibrary.enclosingElement = this;
+    this._scriptLibrary = scriptLibrary;
   }
   void visitChildren(ElementVisitor visitor) {
     safelyVisitChild(_scriptLibrary, visitor);
@@ -3158,24 +3158,24 @@
    *          declaration of this element
    */
   ExecutableElementImpl.con2(String name, int nameOffset) : super.con2(name, nameOffset);
-  ElementImpl getChild(String identifier2) {
+  ElementImpl getChild(String identifier) {
     for (ExecutableElement function in _functions) {
-      if (((function as ExecutableElementImpl)).identifier == identifier2) {
+      if (((function as ExecutableElementImpl)).identifier == identifier) {
         return function as ExecutableElementImpl;
       }
     }
     for (LabelElement label in _labels) {
-      if (((label as LabelElementImpl)).identifier == identifier2) {
+      if (((label as LabelElementImpl)).identifier == identifier) {
         return label as LabelElementImpl;
       }
     }
     for (VariableElement variable in _localVariables) {
-      if (((variable as VariableElementImpl)).identifier == identifier2) {
+      if (((variable as VariableElementImpl)).identifier == identifier) {
         return variable as VariableElementImpl;
       }
     }
     for (ParameterElement parameter in _parameters) {
-      if (((parameter as ParameterElementImpl)).identifier == identifier2) {
+      if (((parameter as ParameterElementImpl)).identifier == identifier) {
         return parameter as ParameterElementImpl;
       }
     }
@@ -3194,11 +3194,11 @@
    *
    * @param functions the functions defined within this executable element
    */
-  void set functions(List<FunctionElement> functions2) {
-    for (FunctionElement function in functions2) {
+  void set functions(List<FunctionElement> functions) {
+    for (FunctionElement function in functions) {
       ((function as FunctionElementImpl)).enclosingElement = this;
     }
-    this._functions = functions2;
+    this._functions = functions;
   }
 
   /**
@@ -3206,11 +3206,11 @@
    *
    * @param labels the labels defined within this executable element
    */
-  void set labels(List<LabelElement> labels2) {
-    for (LabelElement label in labels2) {
+  void set labels(List<LabelElement> labels) {
+    for (LabelElement label in labels) {
       ((label as LabelElementImpl)).enclosingElement = this;
     }
-    this._labels = labels2;
+    this._labels = labels;
   }
 
   /**
@@ -3218,11 +3218,11 @@
    *
    * @param localVariables the local variables defined within this executable element
    */
-  void set localVariables(List<LocalVariableElement> localVariables2) {
-    for (LocalVariableElement variable in localVariables2) {
+  void set localVariables(List<LocalVariableElement> localVariables) {
+    for (LocalVariableElement variable in localVariables) {
       ((variable as LocalVariableElementImpl)).enclosingElement = this;
     }
-    this._localVariables = localVariables2;
+    this._localVariables = localVariables;
   }
 
   /**
@@ -3230,11 +3230,11 @@
    *
    * @param parameters the parameters defined by this executable element
    */
-  void set parameters(List<ParameterElement> parameters2) {
-    for (ParameterElement parameter in parameters2) {
+  void set parameters(List<ParameterElement> parameters) {
+    for (ParameterElement parameter in parameters) {
       ((parameter as ParameterElementImpl)).enclosingElement = this;
     }
-    this._parameters = parameters2;
+    this._parameters = parameters;
   }
 
   /**
@@ -3242,8 +3242,8 @@
    *
    * @param returnType the return type defined by this executable element
    */
-  void set returnType(Type2 returnType2) {
-    this._returnType = returnType2;
+  void set returnType(Type2 returnType) {
+    this._returnType = returnType;
   }
 
   /**
@@ -3251,8 +3251,8 @@
    *
    * @param type the type of function defined by this executable element
    */
-  void set type(FunctionType type2) {
-    this._type = type2;
+  void set type(FunctionType type) {
+    this._type = type;
   }
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -3316,8 +3316,8 @@
    *
    * @param combinators the combinators that were specified as part of the export directive
    */
-  void set combinators(List<NamespaceCombinator> combinators2) {
-    this._combinators = combinators2;
+  void set combinators(List<NamespaceCombinator> combinators) {
+    this._combinators = combinators;
   }
 
   /**
@@ -3326,8 +3326,8 @@
    *
    * @param exportedLibrary the library that is exported from this library
    */
-  void set exportedLibrary(LibraryElement exportedLibrary2) {
-    this._exportedLibrary = exportedLibrary2;
+  void set exportedLibrary(LibraryElement exportedLibrary) {
+    this._exportedLibrary = exportedLibrary;
   }
 
   /**
@@ -3335,8 +3335,8 @@
    *
    * @param uri the URI that is specified by this directive.
    */
-  void set uri(String uri2) {
-    this._uri = uri2;
+  void set uri(String uri) {
+    this._uri = uri;
   }
   void appendTo(JavaStringBuilder builder) {
     builder.append("export ");
@@ -3372,8 +3372,8 @@
    *
    * @param scriptSource the script source or `null` if unspecified
    */
-  void set scriptSource(Source scriptSource2) {
-    this._scriptSource = scriptSource2;
+  void set scriptSource(Source scriptSource) {
+    this._scriptSource = scriptSource;
   }
 }
 /**
@@ -3444,8 +3444,8 @@
    *
    * @param field the new field element
    */
-  void set field(FieldElement field2) {
-    this._field = field2;
+  void set field(FieldElement field) {
+    this._field = field;
   }
 }
 /**
@@ -3564,14 +3564,14 @@
    */
   FunctionTypeAliasElementImpl(Identifier name) : super.con1(name);
   accept(ElementVisitor visitor) => visitor.visitFunctionTypeAliasElement(this);
-  ElementImpl getChild(String identifier2) {
+  ElementImpl getChild(String identifier) {
     for (VariableElement parameter in _parameters) {
-      if (((parameter as VariableElementImpl)).identifier == identifier2) {
+      if (((parameter as VariableElementImpl)).identifier == identifier) {
         return parameter as VariableElementImpl;
       }
     }
     for (TypeParameterElement typeParameter in _typeParameters) {
-      if (((typeParameter as TypeParameterElementImpl)).identifier == identifier2) {
+      if (((typeParameter as TypeParameterElementImpl)).identifier == identifier) {
         return typeParameter as TypeParameterElementImpl;
       }
     }
@@ -3589,13 +3589,13 @@
    *
    * @param parameters the parameters defined by this type alias
    */
-  void set parameters(List<ParameterElement> parameters2) {
-    if (parameters2 != null) {
-      for (ParameterElement parameter in parameters2) {
+  void set parameters(List<ParameterElement> parameters) {
+    if (parameters != null) {
+      for (ParameterElement parameter in parameters) {
         ((parameter as ParameterElementImpl)).enclosingElement = this;
       }
     }
-    this._parameters = parameters2;
+    this._parameters = parameters;
   }
 
   /**
@@ -3603,8 +3603,8 @@
    *
    * @param returnType the return type defined by this type alias
    */
-  void set returnType(Type2 returnType2) {
-    this._returnType = returnType2;
+  void set returnType(Type2 returnType) {
+    this._returnType = returnType;
   }
 
   /**
@@ -3612,8 +3612,8 @@
    *
    * @param type the type of function defined by this type alias
    */
-  void set type(FunctionType type2) {
-    this._type = type2;
+  void set type(FunctionType type) {
+    this._type = type;
   }
 
   /**
@@ -3621,11 +3621,11 @@
    *
    * @param typeParameters the type parameters defined for this type
    */
-  void set typeParameters(List<TypeParameterElement> typeParameters2) {
-    for (TypeParameterElement typeParameter in typeParameters2) {
+  void set typeParameters(List<TypeParameterElement> typeParameters) {
+    for (TypeParameterElement typeParameter in typeParameters) {
       ((typeParameter as TypeParameterElementImpl)).enclosingElement = this;
     }
-    this._typeParameters = typeParameters2;
+    this._typeParameters = typeParameters;
   }
 
   /**
@@ -3635,8 +3635,8 @@
    *
    * @param parameters the parameters defined by this type alias
    */
-  void shareParameters(List<ParameterElement> parameters2) {
-    this._parameters = parameters2;
+  void shareParameters(List<ParameterElement> parameters) {
+    this._parameters = parameters;
   }
 
   /**
@@ -3646,8 +3646,8 @@
    *
    * @param typeParameters the type parameters defined for this type
    */
-  void shareTypeParameters(List<TypeParameterElement> typeParameters2) {
-    this._typeParameters = typeParameters2;
+  void shareTypeParameters(List<TypeParameterElement> typeParameters) {
+    this._typeParameters = typeParameters;
   }
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -3704,8 +3704,8 @@
    *
    * @param hiddenNames the names that are not to be made visible in the importing library
    */
-  void set hiddenNames(List<String> hiddenNames2) {
-    this._hiddenNames = hiddenNames2;
+  void set hiddenNames(List<String> hiddenNames) {
+    this._hiddenNames = hiddenNames;
   }
   String toString() {
     JavaStringBuilder builder = new JavaStringBuilder();
@@ -3769,14 +3769,14 @@
    *
    * @param scripts the scripts
    */
-  void set scripts(List<HtmlScriptElement> scripts2) {
-    if (scripts2.length == 0) {
-      scripts2 = HtmlScriptElementImpl.EMPTY_ARRAY;
+  void set scripts(List<HtmlScriptElement> scripts) {
+    if (scripts.length == 0) {
+      scripts = HtmlScriptElementImpl.EMPTY_ARRAY;
     }
-    for (HtmlScriptElement script in scripts2) {
+    for (HtmlScriptElement script in scripts) {
       ((script as HtmlScriptElementImpl)).enclosingElement = this;
     }
-    this._scripts = scripts2;
+    this._scripts = scripts;
   }
 
   /**
@@ -3784,8 +3784,8 @@
    *
    * @param source the source that corresponds to this HTML file
    */
-  void set source(Source source2) {
-    this._source = source2;
+  void set source(Source source) {
+    this._source = source;
   }
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -3864,8 +3864,8 @@
    *
    * @param combinators the combinators that were specified as part of the import directive
    */
-  void set combinators(List<NamespaceCombinator> combinators2) {
-    this._combinators = combinators2;
+  void set combinators(List<NamespaceCombinator> combinators) {
+    this._combinators = combinators;
   }
 
   /**
@@ -3874,8 +3874,8 @@
    *
    * @param importedLibrary the library that is imported into this library
    */
-  void set importedLibrary(LibraryElement importedLibrary2) {
-    this._importedLibrary = importedLibrary2;
+  void set importedLibrary(LibraryElement importedLibrary) {
+    this._importedLibrary = importedLibrary;
   }
 
   /**
@@ -3883,8 +3883,8 @@
    *
    * @param prefix the prefix that was specified as part of the import directive
    */
-  void set prefix(PrefixElement prefix2) {
-    this._prefix = prefix2;
+  void set prefix(PrefixElement prefix) {
+    this._prefix = prefix;
   }
 
   /**
@@ -3892,8 +3892,8 @@
    *
    * @param uri the URI that is specified by this directive.
    */
-  void set uri(String uri2) {
-    this._uri = uri2;
+  void set uri(String uri) {
+    this._uri = uri;
   }
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -4030,22 +4030,22 @@
   }
   accept(ElementVisitor visitor) => visitor.visitLibraryElement(this);
   bool operator ==(Object object) => object != null && runtimeType == object.runtimeType && _definingCompilationUnit == ((object as LibraryElementImpl)).definingCompilationUnit;
-  ElementImpl getChild(String identifier2) {
-    if (((_definingCompilationUnit as CompilationUnitElementImpl)).identifier == identifier2) {
+  ElementImpl getChild(String identifier) {
+    if (((_definingCompilationUnit as CompilationUnitElementImpl)).identifier == identifier) {
       return _definingCompilationUnit as CompilationUnitElementImpl;
     }
     for (CompilationUnitElement part in _parts) {
-      if (((part as CompilationUnitElementImpl)).identifier == identifier2) {
+      if (((part as CompilationUnitElementImpl)).identifier == identifier) {
         return part as CompilationUnitElementImpl;
       }
     }
     for (ImportElement importElement in _imports) {
-      if (((importElement as ImportElementImpl)).identifier == identifier2) {
+      if (((importElement as ImportElementImpl)).identifier == identifier) {
         return importElement as ImportElementImpl;
       }
     }
     for (ExportElement exportElement in _exports) {
-      if (((exportElement as ExportElementImpl)).identifier == identifier2) {
+      if (((exportElement as ExportElementImpl)).identifier == identifier) {
         return exportElement as ExportElementImpl;
       }
     }
@@ -4123,9 +4123,9 @@
    *
    * @param definingCompilationUnit the compilation unit that defines this library
    */
-  void set definingCompilationUnit(CompilationUnitElement definingCompilationUnit2) {
-    ((definingCompilationUnit2 as CompilationUnitElementImpl)).enclosingElement = this;
-    this._definingCompilationUnit = definingCompilationUnit2;
+  void set definingCompilationUnit(CompilationUnitElement definingCompilationUnit) {
+    ((definingCompilationUnit as CompilationUnitElementImpl)).enclosingElement = this;
+    this._definingCompilationUnit = definingCompilationUnit;
   }
 
   /**
@@ -4133,8 +4133,8 @@
    *
    * @param entryPoint the entry point for this library
    */
-  void set entryPoint(FunctionElement entryPoint2) {
-    this._entryPoint = entryPoint2;
+  void set entryPoint(FunctionElement entryPoint) {
+    this._entryPoint = entryPoint;
   }
 
   /**
@@ -4142,11 +4142,11 @@
    *
    * @param exports the specifications of all of the exports defined in this library
    */
-  void set exports(List<ExportElement> exports2) {
-    for (ExportElement exportElement in exports2) {
+  void set exports(List<ExportElement> exports) {
+    for (ExportElement exportElement in exports) {
       ((exportElement as ExportElementImpl)).enclosingElement = this;
     }
-    this._exports = exports2;
+    this._exports = exports;
   }
 
   /**
@@ -4154,15 +4154,15 @@
    *
    * @param imports the specifications of all of the imports defined in this library
    */
-  void set imports(List<ImportElement> imports2) {
-    for (ImportElement importElement in imports2) {
+  void set imports(List<ImportElement> imports) {
+    for (ImportElement importElement in imports) {
       ((importElement as ImportElementImpl)).enclosingElement = this;
       PrefixElementImpl prefix = importElement.prefix as PrefixElementImpl;
       if (prefix != null) {
         prefix.enclosingElement = this;
       }
     }
-    this._imports = imports2;
+    this._imports = imports;
   }
 
   /**
@@ -4171,11 +4171,11 @@
    * @param parts the compilation units that are included in this library using a `part`
    *          directive
    */
-  void set parts(List<CompilationUnitElement> parts2) {
-    for (CompilationUnitElement compilationUnit in parts2) {
+  void set parts(List<CompilationUnitElement> parts) {
+    for (CompilationUnitElement compilationUnit in parts) {
       ((compilationUnit as CompilationUnitElementImpl)).enclosingElement = this;
     }
-    this._parts = parts2;
+    this._parts = parts;
   }
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -4593,8 +4593,8 @@
    *
    * @param parameterKind the new kind of this parameter
    */
-  void set parameterKind(ParameterKind parameterKind2) {
-    this._parameterKind = parameterKind2;
+  void set parameterKind(ParameterKind parameterKind) {
+    this._parameterKind = parameterKind;
   }
 
   /**
@@ -4602,11 +4602,11 @@
    *
    * @param parameters the parameters defined by this executable element
    */
-  void set parameters(List<ParameterElement> parameters2) {
-    for (ParameterElement parameter in parameters2) {
+  void set parameters(List<ParameterElement> parameters) {
+    for (ParameterElement parameter in parameters) {
       ((parameter as ParameterElementImpl)).enclosingElement = this;
     }
-    this._parameters = parameters2;
+    this._parameters = parameters;
   }
 
   /**
@@ -4678,16 +4678,17 @@
    *
    * @param importedLibraries the libraries that are imported using this prefix
    */
-  void set importedLibraries(List<LibraryElement> importedLibraries2) {
-    for (LibraryElement library in importedLibraries2) {
+  void set importedLibraries(List<LibraryElement> importedLibraries) {
+    for (LibraryElement library in importedLibraries) {
       ((library as LibraryElementImpl)).enclosingElement = this;
     }
-    this._importedLibraries = importedLibraries2;
+    this._importedLibraries = importedLibraries;
   }
   void appendTo(JavaStringBuilder builder) {
     builder.append("as ");
     super.appendTo(builder);
   }
+  String get identifier => "_${super.identifier}";
 }
 /**
  * Instances of the class `PropertyAccessorElementImpl` implement a
@@ -4797,8 +4798,8 @@
    *
    * @param variable the variable associated with this accessor
    */
-  void set variable(PropertyInducingElement variable2) {
-    this._variable = variable2;
+  void set variable(PropertyInducingElement variable) {
+    this._variable = variable;
   }
   void appendTo(JavaStringBuilder builder) {
     builder.append(isGetter ? "get " : "set ");
@@ -4853,8 +4854,8 @@
    *
    * @param getter the getter associated with this element
    */
-  void set getter(PropertyAccessorElement getter2) {
-    this._getter = getter2;
+  void set getter(PropertyAccessorElement getter) {
+    this._getter = getter;
   }
 
   /**
@@ -4862,8 +4863,8 @@
    *
    * @param setter the setter associated with this element
    */
-  void set setter(PropertyAccessorElement setter2) {
-    this._setter = setter2;
+  void set setter(PropertyAccessorElement setter) {
+    this._setter = setter;
   }
 }
 /**
@@ -4887,8 +4888,8 @@
    *
    * @param shownNames the names that are to be made visible in the importing library
    */
-  void set shownNames(List<String> shownNames2) {
-    this._shownNames = shownNames2;
+  void set shownNames(List<String> shownNames) {
+    this._shownNames = shownNames;
   }
   String toString() {
     JavaStringBuilder builder = new JavaStringBuilder();
@@ -4972,8 +4973,8 @@
    *
    * @param bound the type representing the bound associated with this parameter
    */
-  void set bound(Type2 bound2) {
-    this._bound = bound2;
+  void set bound(Type2 bound) {
+    this._bound = bound;
   }
 
   /**
@@ -4981,8 +4982,8 @@
    *
    * @param type the type defined by this type parameter
    */
-  void set type(TypeParameterType type2) {
-    this._type = type2;
+  void set type(TypeParameterType type) {
+    this._type = type;
   }
   void appendTo(JavaStringBuilder builder) {
     builder.append(displayName);
@@ -5077,11 +5078,11 @@
    *
    * @param initializer the function representing this variable's initializer
    */
-  void set initializer(FunctionElement initializer2) {
-    if (initializer2 != null) {
-      ((initializer2 as FunctionElementImpl)).enclosingElement = this;
+  void set initializer(FunctionElement initializer) {
+    if (initializer != null) {
+      ((initializer as FunctionElementImpl)).enclosingElement = this;
     }
-    this._initializer = initializer2;
+    this._initializer = initializer;
   }
 
   /**
@@ -5089,8 +5090,8 @@
    *
    * @param type the declared type of this variable
    */
-  void set type(Type2 type2) {
-    this._type = type2;
+  void set type(Type2 type) {
+    this._type = type;
   }
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -6013,8 +6014,8 @@
    *
    * @param typeArguments the actual types of the type arguments
    */
-  void set typeArguments(List<Type2> typeArguments2) {
-    this._typeArguments = typeArguments2;
+  void set typeArguments(List<Type2> typeArguments) {
+    this._typeArguments = typeArguments;
   }
   FunctionTypeImpl substitute3(List<Type2> argumentTypes) => substitute2(argumentTypes, typeArguments);
   FunctionTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
@@ -6480,24 +6481,24 @@
     return isMoreSpecificThan2(type as InterfaceType, new Set<ClassElement>());
   }
   bool get isObject => element.supertype == null;
-  bool isSubtypeOf(Type2 type2) {
-    if (identical(type2, DynamicTypeImpl.instance)) {
+  bool isSubtypeOf(Type2 type) {
+    if (identical(type, DynamicTypeImpl.instance)) {
       return true;
-    } else if (type2 is TypeParameterType) {
+    } else if (type is TypeParameterType) {
       return true;
-    } else if (type2 is FunctionType) {
+    } else if (type is FunctionType) {
       ClassElement element = this.element;
       MethodElement callMethod = element.lookUpMethod("call", element.library);
       if (callMethod != null) {
-        return callMethod.type.isSubtypeOf(type2);
+        return callMethod.type.isSubtypeOf(type);
       }
       return false;
-    } else if (type2 is! InterfaceType) {
+    } else if (type is! InterfaceType) {
       return false;
-    } else if (this == type2) {
+    } else if (this == type) {
       return true;
     }
-    return isSubtypeOf2(type2 as InterfaceType, new Set<ClassElement>());
+    return isSubtypeOf2(type as InterfaceType, new Set<ClassElement>());
   }
   ConstructorElement lookUpConstructor(String constructorName, LibraryElement library) {
     ConstructorElement constructorElement;
@@ -6619,8 +6620,8 @@
    *
    * @param typeArguments the actual types of the type arguments
    */
-  void set typeArguments(List<Type2> typeArguments2) {
-    this._typeArguments = typeArguments2;
+  void set typeArguments(List<Type2> typeArguments) {
+    this._typeArguments = typeArguments;
   }
   InterfaceTypeImpl substitute4(List<Type2> argumentTypes) => substitute2(argumentTypes, typeArguments);
   InterfaceTypeImpl substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
@@ -6659,7 +6660,7 @@
     if (s.isDirectSupertypeOf(this)) {
       return true;
     }
-    ClassElement tElement = element;
+    ClassElement tElement = this.element;
     ClassElement sElement = s.element;
     if (tElement == sElement) {
       List<Type2> tArguments = typeArguments;
@@ -6695,9 +6696,9 @@
     }
     return false;
   }
-  bool isSubtypeOf2(InterfaceType type2, Set<ClassElement> visitedClasses) {
+  bool isSubtypeOf2(InterfaceType type, Set<ClassElement> visitedClasses) {
     InterfaceType typeT = this;
-    InterfaceType typeS = type2;
+    InterfaceType typeS = type;
     ClassElement elementT = element;
     if (elementT == null || visitedClasses.contains(elementT)) {
       return false;
diff --git a/pkg/analyzer_experimental/lib/src/generated/engine.dart b/pkg/analyzer_experimental/lib/src/generated/engine.dart
index 1d8b5f8..84f6f56 100644
--- a/pkg/analyzer_experimental/lib/src/generated/engine.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/engine.dart
@@ -101,8 +101,8 @@
    * @param logger the logger that should receive information about errors within the analysis
    *          engine
    */
-  void set logger(Logger logger2) {
-    this._logger = logger2 == null ? Logger.NULL : logger2;
+  void set logger(Logger logger) {
+    this._logger = logger == null ? Logger.NULL : logger;
   }
 }
 /**
@@ -1440,10 +1440,10 @@
       return super.getState(descriptor);
     }
   }
-  CacheState getState2(DataDescriptor descriptor, Source librarySource2) {
+  CacheState getState2(DataDescriptor descriptor, Source librarySource) {
     DartEntryImpl_ResolutionState state = _resolutionState;
     while (state != null) {
-      if (librarySource2 == state._librarySource) {
+      if (librarySource == state._librarySource) {
         if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
           return state._resolutionErrorsState;
         } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
@@ -1488,10 +1488,10 @@
     }
     return super.getValue(descriptor);
   }
-  Object getValue2(DataDescriptor descriptor, Source librarySource2) {
+  Object getValue2(DataDescriptor descriptor, Source librarySource) {
     DartEntryImpl_ResolutionState state = _resolutionState;
     while (state != null) {
-      if (librarySource2 == state._librarySource) {
+      if (librarySource == state._librarySource) {
         if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
           return state._resolutionErrors as Object;
         } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
@@ -1676,9 +1676,9 @@
    * @param librarySource the source of the defining compilation unit of the library that used to
    *          contain this part but no longer does
    */
-  void removeResolution(Source librarySource2) {
-    if (librarySource2 != null) {
-      if (librarySource2 == _resolutionState._librarySource) {
+  void removeResolution(Source librarySource) {
+    if (librarySource != null) {
+      if (librarySource == _resolutionState._librarySource) {
         if (_resolutionState._nextState == null) {
           _resolutionState.invalidateAllResolutionInformation();
         } else {
@@ -1688,7 +1688,7 @@
         DartEntryImpl_ResolutionState priorState = _resolutionState;
         DartEntryImpl_ResolutionState state = _resolutionState._nextState;
         while (state != null) {
-          if (librarySource2 == state._librarySource) {
+          if (librarySource == state._librarySource) {
             priorState._nextState = state._nextState;
             break;
           }
@@ -1904,16 +1904,16 @@
    * @param librarySource the library source (not `null`)
    * @return the resolution state (not `null`)
    */
-  DartEntryImpl_ResolutionState getOrCreateResolutionState(Source librarySource2) {
+  DartEntryImpl_ResolutionState getOrCreateResolutionState(Source librarySource) {
     DartEntryImpl_ResolutionState state = _resolutionState;
     if (state._librarySource == null) {
-      state._librarySource = librarySource2;
+      state._librarySource = librarySource;
       return state;
     }
-    while (state._librarySource != librarySource2) {
+    while (state._librarySource != librarySource) {
       if (state._nextState == null) {
         DartEntryImpl_ResolutionState newState = new DartEntryImpl_ResolutionState();
-        newState._librarySource = librarySource2;
+        newState._librarySource = librarySource;
         state._nextState = newState;
         return newState;
       }
@@ -2484,8 +2484,8 @@
    *
    * @param exception the exception that caused one or more values to be uncomputable
    */
-  void set exception(AnalysisException exception2) {
-    this._exception = exception2;
+  void set exception(AnalysisException exception) {
+    this._exception = exception;
   }
 
   /**
@@ -2779,6 +2779,7 @@
     return null;
   }
   List<AnalysisError> computeErrors(Source source) {
+    bool enableHints = analysisOptions.hint;
     SourceEntry sourceEntry = getReadableSourceEntry(source);
     if (sourceEntry is DartEntry) {
       List<AnalysisError> errors = new List<AnalysisError>();
@@ -2787,12 +2788,16 @@
       dartEntry = getReadableDartEntry(source);
       if (identical(dartEntry.getValue(DartEntry.SOURCE_KIND), SourceKind.LIBRARY)) {
         ListUtilities.addAll(errors, getDartResolutionData(source, source, dartEntry, DartEntry.RESOLUTION_ERRORS));
-        ListUtilities.addAll(errors, getDartHintData(source, source, dartEntry, DartEntry.HINTS));
+        if (enableHints) {
+          ListUtilities.addAll(errors, getDartHintData(source, source, dartEntry, DartEntry.HINTS));
+        }
       } else {
         List<Source> libraries = getLibrariesContaining(source);
         for (Source librarySource in libraries) {
           ListUtilities.addAll(errors, getDartResolutionData(source, librarySource, dartEntry, DartEntry.RESOLUTION_ERRORS));
-          ListUtilities.addAll(errors, getDartHintData(source, librarySource, dartEntry, DartEntry.HINTS));
+          if (enableHints) {
+            ListUtilities.addAll(errors, getDartHintData(source, librarySource, dartEntry, DartEntry.HINTS));
+          }
         }
       }
       if (errors.isEmpty) {
@@ -3305,9 +3310,9 @@
   }
   CompilationUnit resolveCompilationUnit2(Source unitSource, Source librarySource) => getDartResolutionData2(unitSource, librarySource, DartEntry.RESOLVED_UNIT, null);
   HtmlUnit resolveHtmlUnit(Source htmlSource) => parseHtmlUnit(htmlSource);
-  void set analysisOptions(AnalysisOptions options2) {
+  void set analysisOptions(AnalysisOptions options) {
     {
-      this._options = options2;
+      this._options = options;
       invalidateAllResolutionInformation();
     }
   }
@@ -3983,11 +3988,11 @@
    * @param kind the kind of sources to be returned
    * @return all of the sources known to this context that have the given kind
    */
-  List<Source> getSources(SourceKind kind2) {
+  List<Source> getSources(SourceKind kind) {
     List<Source> sources = new List<Source>();
     {
       for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
-        if (identical(entry.getValue().kind, kind2)) {
+        if (identical(entry.getValue().kind, kind)) {
           sources.add(entry.getKey());
         }
       }
@@ -4102,7 +4107,7 @@
    */
   DartEntry recordGenerateDartHintsTask(GenerateDartHintsTask task) {
     Source librarySource = task.libraryElement.source;
-    AnalysisException thrownException = task.thrownException;
+    AnalysisException thrownException = task.exception;
     DartEntry libraryEntry = null;
     Map<Source, TimestampedData<List<AnalysisError>>> hintMap = task.hintMap;
     if (hintMap == null) {
@@ -4186,7 +4191,7 @@
    */
   DartEntry recordParseDartTaskResults(ParseDartTask task) {
     Source source = task.source;
-    AnalysisException thrownException = task.thrownException;
+    AnalysisException thrownException = task.exception;
     DartEntry dartEntry = null;
     {
       SourceEntry sourceEntry = _cache.get(source);
@@ -4253,7 +4258,7 @@
    */
   HtmlEntry recordParseHtmlTaskResults(ParseHtmlTask task) {
     Source source = task.source;
-    AnalysisException thrownException = task.thrownException;
+    AnalysisException thrownException = task.exception;
     HtmlEntry htmlEntry = null;
     {
       SourceEntry sourceEntry = _cache.get(source);
@@ -4327,7 +4332,7 @@
    */
   DartEntry recordResolveDartLibraryTaskResults(ResolveDartLibraryTask task) {
     LibraryResolver resolver = task.libraryResolver;
-    AnalysisException thrownException = task.thrownException;
+    AnalysisException thrownException = task.exception;
     DartEntry unitEntry = null;
     Source unitSource = task.unitSource;
     if (resolver != null) {
@@ -4419,7 +4424,7 @@
   SourceEntry recordResolveDartUnitTaskResults(ResolveDartUnitTask task) {
     Source unitSource = task.source;
     Source librarySource = task.librarySource;
-    AnalysisException thrownException = task.thrownException;
+    AnalysisException thrownException = task.exception;
     DartEntry dartEntry = null;
     {
       SourceEntry sourceEntry = _cache.get(unitSource);
@@ -4477,7 +4482,7 @@
    */
   SourceEntry recordResolveHtmlTaskResults(ResolveHtmlTask task) {
     Source source = task.source;
-    AnalysisException thrownException = task.thrownException;
+    AnalysisException thrownException = task.exception;
     HtmlEntry htmlEntry = null;
     {
       SourceEntry sourceEntry = _cache.get(source);
@@ -4700,8 +4705,8 @@
    *
    * @param hint `true` if analysis is to generate hint results
    */
-  void set hint(bool hint2) {
-    this._hint = hint2;
+  void set hint(bool hint) {
+    this._hint = hint;
   }
 
   /**
@@ -4794,8 +4799,8 @@
    *
    * @param compilationUnit the fully resolved AST that changed as a result of the analysis
    */
-  void set compilationUnit(CompilationUnit compilationUnit2) {
-    this._compilationUnit = compilationUnit2;
+  void set compilationUnit(CompilationUnit compilationUnit) {
+    this._compilationUnit = compilationUnit;
   }
 
   /**
@@ -4805,9 +4810,9 @@
    * @param errors the errors that changed as a result of the analysis
    * @param lineInfo the line information associated with the source
    */
-  void setErrors(List<AnalysisError> errors2, LineInfo lineInfo2) {
-    this._errors = errors2;
-    this._lineInfo = lineInfo2;
+  void setErrors(List<AnalysisError> errors, LineInfo lineInfo) {
+    this._errors = errors;
+    this._lineInfo = lineInfo;
   }
 }
 /**
@@ -5927,7 +5932,7 @@
    * The exception that was thrown while performing this task, or `null` if the task completed
    * successfully.
    */
-  AnalysisException thrownException;
+  AnalysisException exception;
 
   /**
    * Initialize a newly created task to perform analysis within the given context.
@@ -5958,7 +5963,7 @@
     try {
       safelyPerform();
     } on AnalysisException catch (exception) {
-      thrownException = exception;
+      this.exception = exception;
       AnalysisEngine.instance.logger.logInformation2("Task failed: ${taskDescription}", exception);
     }
     return accept(visitor);
@@ -6325,14 +6330,14 @@
   RecordingErrorListener errorListener;
   List<Token> token;
   Source_ContentReceiver_9(this.ParseDartTask_this, this.errorListener, this.token);
-  void accept(CharBuffer contents, int modificationTime2) {
-    ParseDartTask_this.modificationTime = modificationTime2;
+  void accept(CharBuffer contents, int modificationTime) {
+    ParseDartTask_this.modificationTime = modificationTime;
     CharBufferScanner scanner = new CharBufferScanner(ParseDartTask_this.source, contents, errorListener);
     token[0] = scanner.tokenize();
     ParseDartTask_this.lineInfo = new LineInfo(scanner.lineStarts);
   }
-  void accept2(String contents, int modificationTime2) {
-    ParseDartTask_this.modificationTime = modificationTime2;
+  void accept2(String contents, int modificationTime) {
+    ParseDartTask_this.modificationTime = modificationTime;
     StringScanner scanner = new StringScanner(ParseDartTask_this.source, contents, errorListener);
     token[0] = scanner.tokenize();
     ParseDartTask_this.lineInfo = new LineInfo(scanner.lineStarts);
diff --git a/pkg/analyzer_experimental/lib/src/generated/error.dart b/pkg/analyzer_experimental/lib/src/generated/error.dart
index b57ab78..7c5d24d 100644
--- a/pkg/analyzer_experimental/lib/src/generated/error.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/error.dart
@@ -206,8 +206,8 @@
    *
    * @param source the source to be used when reporting errors
    */
-  void set source(Source source2) {
-    this._source = source2 == null ? _defaultSource : source2;
+  void set source(Source source) {
+    this._source = source == null ? _defaultSource : source;
   }
 }
 /**
@@ -478,24 +478,68 @@
   static final HintCode TYPE_CHECK_IS_NULL = new HintCode.con1('TYPE_CHECK_IS_NULL', 12, "Tests for null should be done with '== null'");
 
   /**
+   * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_GETTER] or
+   * [StaticWarningCode#UNDEFINED_GETTER] would have been generated, if we used propagated
+   * information for the warnings.
+   *
+   * @param getterName the name of the getter
+   * @param enclosingType the name of the enclosing type where the getter is being looked for
+   * @see StaticTypeWarningCode#UNDEFINED_GETTER
+   * @see StaticWarningCode#UNDEFINED_GETTER
+   */
+  static final HintCode UNDEFINED_GETTER = new HintCode.con1('UNDEFINED_GETTER', 13, StaticTypeWarningCode.UNDEFINED_GETTER.message);
+
+  /**
+   * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_METHOD] would
+   * have been generated, if we used propagated information for the warnings.
+   *
+   * @param methodName the name of the method that is undefined
+   * @param typeName the resolved type name that the method lookup is happening on
+   * @see StaticTypeWarningCode#UNDEFINED_METHOD
+   */
+  static final HintCode UNDEFINED_METHOD = new HintCode.con1('UNDEFINED_METHOD', 14, StaticTypeWarningCode.UNDEFINED_METHOD.message);
+
+  /**
+   * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_OPERATOR]
+   * would have been generated, if we used propagated information for the warnings.
+   *
+   * @param operator the name of the operator
+   * @param enclosingType the name of the enclosing type where the operator is being looked for
+   * @see StaticTypeWarningCode#UNDEFINED_OPERATOR
+   */
+  static final HintCode UNDEFINED_OPERATOR = new HintCode.con1('UNDEFINED_OPERATOR', 15, StaticTypeWarningCode.UNDEFINED_OPERATOR.message);
+
+  /**
+   * This hint is generated anywhere where the [StaticTypeWarningCode#UNDEFINED_SETTER] or
+   * [StaticWarningCode#UNDEFINED_SETTER] would have been generated, if we used propagated
+   * information for the warnings.
+   *
+   * @param setterName the name of the setter
+   * @param enclosingType the name of the enclosing type where the setter is being looked for
+   * @see StaticTypeWarningCode#UNDEFINED_SETTER
+   * @see StaticWarningCode#UNDEFINED_SETTER
+   */
+  static final HintCode UNDEFINED_SETTER = new HintCode.con1('UNDEFINED_SETTER', 16, StaticTypeWarningCode.UNDEFINED_SETTER.message);
+
+  /**
    * Unnecessary cast.
    */
-  static final HintCode UNNECESSARY_CAST = new HintCode.con1('UNNECESSARY_CAST', 13, "Unnecessary cast");
+  static final HintCode UNNECESSARY_CAST = new HintCode.con1('UNNECESSARY_CAST', 17, "Unnecessary cast");
 
   /**
    * Unnecessary type checks, the result is always true.
    */
-  static final HintCode UNNECESSARY_TYPE_CHECK_FALSE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_FALSE', 14, "Unnecessary type check, the result is always false");
+  static final HintCode UNNECESSARY_TYPE_CHECK_FALSE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_FALSE', 18, "Unnecessary type check, the result is always false");
 
   /**
    * Unnecessary type checks, the result is always false.
    */
-  static final HintCode UNNECESSARY_TYPE_CHECK_TRUE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_TRUE', 15, "Unnecessary type check, the result is always true");
+  static final HintCode UNNECESSARY_TYPE_CHECK_TRUE = new HintCode.con1('UNNECESSARY_TYPE_CHECK_TRUE', 19, "Unnecessary type check, the result is always true");
 
   /**
    * Unused imports are imports which are never not used.
    */
-  static final HintCode UNUSED_IMPORT = new HintCode.con1('UNUSED_IMPORT', 16, "Unused import");
+  static final HintCode UNUSED_IMPORT = new HintCode.con1('UNUSED_IMPORT', 20, "Unused import");
   static final List<HintCode> values = [
       DEAD_CODE,
       DEAD_CODE_CATCH_FOLLOWING_CATCH,
@@ -510,6 +554,10 @@
       OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
       TYPE_CHECK_IS_NOT_NULL,
       TYPE_CHECK_IS_NULL,
+      UNDEFINED_GETTER,
+      UNDEFINED_METHOD,
+      UNDEFINED_OPERATOR,
+      UNDEFINED_SETTER,
       UNNECESSARY_CAST,
       UNNECESSARY_TYPE_CHECK_FALSE,
       UNNECESSARY_TYPE_CHECK_TRUE,
@@ -2793,6 +2841,8 @@
    * <i>id</i> occurs inside a top level or static function (be it function, method, getter, or
    * setter) or variable initializer and there is no declaration <i>d</i> with name <i>id</i> in the
    * lexical scope enclosing the expression.
+   *
+   * @param name the name of the identifier
    */
   static final StaticWarningCode UNDEFINED_IDENTIFIER = new StaticWarningCode.con1('UNDEFINED_IDENTIFIER', 72, "Undefined name '%s'");
 
diff --git a/pkg/analyzer_experimental/lib/src/generated/html.dart b/pkg/analyzer_experimental/lib/src/generated/html.dart
index a6c4a4e..f5286bc 100644
--- a/pkg/analyzer_experimental/lib/src/generated/html.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/html.dart
@@ -210,7 +210,7 @@
     if (beginToken == null) {
       return -1;
     }
-    return beginToken.offset;
+    return this.beginToken.offset;
   }
 
   /**
@@ -397,8 +397,8 @@
   /**
    * Set array of element tags for which the content between tags should be consider a single token.
    */
-  void set passThroughElements(List<String> passThroughElements2) {
-    this._passThroughElements = passThroughElements2 != null ? passThroughElements2 : _NO_PASS_THROUGH_ELEMENTS;
+  void set passThroughElements(List<String> passThroughElements) {
+    this._passThroughElements = passThroughElements != null ? passThroughElements : _NO_PASS_THROUGH_ELEMENTS;
   }
 
   /**
@@ -694,8 +694,8 @@
     this._charOffset = -1;
   }
   int get offset => _charOffset;
-  void set offset(int offset2) {
-    _charOffset = offset2;
+  void set offset(int offset) {
+    _charOffset = offset;
   }
   int advance() {
     if (++_charOffset < _stringLength) {
@@ -999,14 +999,14 @@
   HtmlScanner(Source source) {
     this._source = source;
   }
-  void accept(CharBuffer contents, int modificationTime2) {
-    this._modificationTime = modificationTime2;
+  void accept(CharBuffer contents, int modificationTime) {
+    this._modificationTime = modificationTime;
     _scanner = new CharBufferScanner(_source, contents);
     _scanner.passThroughElements = _SCRIPT_TAG;
     _token = _scanner.tokenize();
   }
-  void accept2(String contents, int modificationTime2) {
-    this._modificationTime = modificationTime2;
+  void accept2(String contents, int modificationTime) {
+    this._modificationTime = modificationTime;
     _scanner = new StringScanner(_source, contents);
     _scanner.passThroughElements = _SCRIPT_TAG;
     _token = _scanner.tokenize();
@@ -1354,9 +1354,9 @@
    * @param name the attribute name
    * @return the attribute or `null` if no matching attribute is found
    */
-  XmlAttributeNode getAttribute(String name2) {
+  XmlAttributeNode getAttribute(String name) {
     for (XmlAttributeNode attribute in attributes) {
-      if (attribute.name.lexeme == name2) {
+      if (attribute.name.lexeme == name) {
         return attribute;
       }
     }
diff --git a/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart b/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
index 8af2198..32f7498 100644
--- a/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
@@ -85,8 +85,8 @@
    *
    * @param logger the logger that should receive instrumentation information
    */
-  static void set logger(InstrumentationLogger logger2) {
-    _CURRENT_LOGGER = logger2 == null ? _NULL_LOGGER : logger2;
+  static void set logger(InstrumentationLogger logger) {
+    _CURRENT_LOGGER = logger == null ? _NULL_LOGGER : logger;
   }
 }
 class InstrumentationBuilder_15 implements InstrumentationBuilder {
diff --git a/pkg/analyzer_experimental/lib/src/generated/parser.dart b/pkg/analyzer_experimental/lib/src/generated/parser.dart
index 2264972..a7cb7de 100644
--- a/pkg/analyzer_experimental/lib/src/generated/parser.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/parser.dart
@@ -259,8 +259,8 @@
       instrumentation.log();
     }
   }
-  void set currentToken(Token currentToken2) {
-    this._currentToken = currentToken2;
+  void set currentToken(Token currentToken) {
+    this._currentToken = currentToken;
   }
 
   /**
@@ -818,7 +818,7 @@
    * @param keyword the keyword that is being tested for
    * @return `true` if the given token matches the given keyword
    */
-  bool matches3(Token token, Keyword keyword2) => identical(token.type, TokenType.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword2);
+  bool matches3(Token token, Keyword keyword) => identical(token.type, TokenType.KEYWORD) && identical(((token as KeywordToken)).keyword, keyword);
 
   /**
    * Return `true` if the given token has the given type.
@@ -827,7 +827,7 @@
    * @param type the type of token that is being tested for
    * @return `true` if the given token has the given type
    */
-  bool matches4(Token token, TokenType type2) => identical(token.type, type2);
+  bool matches4(Token token, TokenType type) => identical(token.type, type);
 
   /**
    * Return `true` if the current token has the given type. Note that this method, unlike
@@ -838,10 +838,10 @@
    * @param type the type of token that can optionally appear in the current location
    * @return `true` if the current token has the given type
    */
-  bool matches5(TokenType type2) {
+  bool matches5(TokenType type) {
     TokenType currentType = _currentToken.type;
-    if (currentType != type2) {
-      if (identical(type2, TokenType.GT)) {
+    if (currentType != type) {
+      if (identical(type, TokenType.GT)) {
         if (identical(currentType, TokenType.GT_GT)) {
           int offset = _currentToken.offset;
           Token first = new Token(TokenType.GT, offset);
@@ -4861,8 +4861,7 @@
     if (matcher.find()) {
       int offset = commentToken.offset + matcher.start() + matcher.group(1).length;
       int length = matcher.group(2).length;
-      // TODO(scheglov) analyzer_experimental users don't expect it
-//      _errorListener.onError(new AnalysisError.con2(_source, offset, length, TodoCode.TODO, [matcher.group(2)]));
+      // _errorListener.onError(new AnalysisError.con2(_source, offset, length, TodoCode.TODO, [matcher.group(2)]));
     }
   }
 
diff --git a/pkg/analyzer_experimental/lib/src/generated/resolver.dart b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
index 3860b21..535ce2e 100644
--- a/pkg/analyzer_experimental/lib/src/generated/resolver.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/resolver.dart
@@ -33,7 +33,7 @@
    * @return the compilation unit element that was built
    * @throws AnalysisException if the analysis could not be performed
    */
-  CompilationUnitElementImpl buildCompilationUnit(Source source2, CompilationUnit unit) {
+  CompilationUnitElementImpl buildCompilationUnit(Source source, CompilationUnit unit) {
     TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.start();
     if (unit == null) {
       return null;
@@ -41,10 +41,10 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     unit.accept(builder);
-    CompilationUnitElementImpl element = new CompilationUnitElementImpl(source2.shortName);
+    CompilationUnitElementImpl element = new CompilationUnitElementImpl(source.shortName);
     element.accessors = holder.accessors;
     element.functions = holder.functions;
-    element.source = source2;
+    element.source = source;
     element.typeAliases = holder.typeAliases;
     element.types = holder.types;
     element.topLevelVariables = holder.topLevelVariables;
@@ -693,7 +693,7 @@
    * @param keyword the keyword being tested for
    * @return `true` if the given token is a token for the given keyword
    */
-  bool matches(sc.Token token, sc.Keyword keyword2) => token != null && identical(token.type, sc.TokenType.KEYWORD) && identical(((token as sc.KeywordToken)).keyword, keyword2);
+  bool matches(sc.Token token, sc.Keyword keyword) => token != null && identical(token.type, sc.TokenType.KEYWORD) && identical(((token as sc.KeywordToken)).keyword, keyword);
 
   /**
    * Sets the visible source range for formal parameter.
@@ -1117,11 +1117,11 @@
    * @param unit the AST structure representing the HTML
    * @throws AnalysisException if the analysis could not be performed
    */
-  HtmlElementImpl buildHtmlElement2(Source source2, int modificationStamp2, ht.HtmlUnit unit) {
-    this._modificationStamp = modificationStamp2;
-    _lineInfo = _context.computeLineInfo(source2);
-    HtmlElementImpl result = new HtmlElementImpl(_context, source2.shortName);
-    result.source = source2;
+  HtmlElementImpl buildHtmlElement2(Source source, int modificationStamp, ht.HtmlUnit unit) {
+    this._modificationStamp = modificationStamp;
+    _lineInfo = _context.computeLineInfo(source);
+    HtmlElementImpl result = new HtmlElementImpl(_context, source.shortName);
+    result.source = source;
     _htmlElement = result;
     unit.accept(this);
     _htmlElement = null;
@@ -1296,7 +1296,6 @@
   static String _HASHCODE_GETTER_NAME = "hashCode";
   static String _METHOD = "method";
   static String _NULL_TYPE_NAME = "Null";
-  static String _OBJECT_TYPE_NAME = "Object";
   static String _SETTER = "setter";
   static String _TO_INT_METHOD_NAME = "toInt";
 
@@ -1394,7 +1393,7 @@
     Element rhsElement = rhsType.element;
     LibraryElement libraryElement = rhsElement != null ? rhsElement.library : null;
     if (libraryElement != null && libraryElement.isDartCore) {
-      if ((rhsType.isObject && rhsNameStr == _OBJECT_TYPE_NAME) || (expression is NullLiteral && rhsNameStr == _NULL_TYPE_NAME)) {
+      if (rhsType.isObject || (expression is NullLiteral && rhsNameStr == _NULL_TYPE_NAME)) {
         if (node.notOperator == null) {
           _errorReporter.reportError2(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node, []);
         } else {
@@ -2055,9 +2054,18 @@
     }
     return super.visitCompilationUnit(node);
   }
-  Object visitExportDirective(ExportDirective node) => null;
-  Object visitImportDirective(ImportDirective node) => null;
-  Object visitLibraryDirective(LibraryDirective node) => null;
+  Object visitExportDirective(ExportDirective node) {
+    visitMetadata(node.metadata);
+    return null;
+  }
+  Object visitImportDirective(ImportDirective node) {
+    visitMetadata(node.metadata);
+    return null;
+  }
+  Object visitLibraryDirective(LibraryDirective node) {
+    visitMetadata(node.metadata);
+    return null;
+  }
   Object visitPrefixedIdentifier(PrefixedIdentifier node) {
     SimpleIdentifier prefixIdentifier = node.prefix;
     Element element = prefixIdentifier.staticElement;
@@ -2068,8 +2076,8 @@
     return visitIdentifier(element, prefixIdentifier.name);
   }
   Object visitSimpleIdentifier(SimpleIdentifier node) => visitIdentifier(node.staticElement, node.name);
-  void set inDefiningCompilationUnit(bool inDefiningCompilationUnit2) {
-    this._inDefiningCompilationUnit = inDefiningCompilationUnit2;
+  void set inDefiningCompilationUnit(bool inDefiningCompilationUnit) {
+    this._inDefiningCompilationUnit = inDefiningCompilationUnit;
   }
 
   /**
@@ -2159,6 +2167,20 @@
     }
     return null;
   }
+
+  /**
+   * Given some [NodeList] of [Annotation]s, ensure that the identifiers are visited by
+   * this visitor. Specifically, this covers the cases where AST nodes don't have their identifiers
+   * visited by this visitor, but still need their annotations visited.
+   *
+   * @param annotations the list of annotations to visit
+   */
+  void visitMetadata(NodeList<Annotation> annotations) {
+    for (Annotation annotation in annotations) {
+      Identifier name = annotation.name;
+      visitIdentifier(name.staticElement, name.name);
+    }
+  }
 }
 /**
  * Instances of the class `PubVerifier` traverse an AST structure looking for deviations from
@@ -2354,9 +2376,9 @@
    * @param unit the compilation unit to be resolved
    * @param element the root of the element model used to resolve the AST nodes
    */
-  void resolve(CompilationUnit unit, CompilationUnitElement element2) {
-    _enclosingUnit = element2;
-    unit.element = element2;
+  void resolve(CompilationUnit unit, CompilationUnitElement element) {
+    _enclosingUnit = element;
+    unit.element = element;
     unit.accept(this);
   }
   Object visitCatchClause(CatchClause node) {
@@ -2714,9 +2736,9 @@
    *          for
    * @return the export element whose library has the given source
    */
-  ExportElement find5(List<ExportElement> exports, Source source2) {
+  ExportElement find5(List<ExportElement> exports, Source source) {
     for (ExportElement export in exports) {
-      if (export.exportedLibrary.source == source2) {
+      if (export.exportedLibrary.source == source) {
         return export;
       }
     }
@@ -2733,16 +2755,16 @@
    * @param prefix the prefix with which the library was imported
    * @return the import element whose library has the given source and prefix
    */
-  ImportElement find6(List<ImportElement> imports, Source source2, SimpleIdentifier prefix2) {
+  ImportElement find6(List<ImportElement> imports, Source source, SimpleIdentifier prefix) {
     for (ImportElement element in imports) {
-      if (element.importedLibrary.source == source2) {
+      if (element.importedLibrary.source == source) {
         PrefixElement prefixElement = element.prefix;
-        if (prefix2 == null) {
+        if (prefix == null) {
           if (prefixElement == null) {
             return element;
           }
         } else {
-          if (prefixElement != null && prefix2.name == prefixElement.displayName) {
+          if (prefixElement != null && prefix.name == prefixElement.displayName) {
             return element;
           }
         }
@@ -2919,6 +2941,11 @@
   bool _strictMode = false;
 
   /**
+   * A flag indicating whether we should generate hints.
+   */
+  bool _enableHints = false;
+
+  /**
    * The type representing the type 'dynamic'.
    */
   Type2 _dynamicType;
@@ -2947,7 +2974,9 @@
    */
   ElementResolver(ResolverVisitor resolver) {
     this._resolver = resolver;
-    _strictMode = resolver.definingLibrary.context.analysisOptions.strictMode;
+    AnalysisOptions options = resolver.definingLibrary.context.analysisOptions;
+    _strictMode = options.strictMode;
+    _enableHints = options.hint;
     _dynamicType = resolver.typeProvider.dynamicType;
     _typeType = resolver.typeProvider.typeType;
   }
@@ -2965,8 +2994,13 @@
         Type2 propagatedType = getPropagatedType(leftHandSide);
         MethodElement propagatedMethod = lookUpMethod(leftHandSide, propagatedType, methodName);
         node.propagatedElement = propagatedMethod;
-        if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
-          _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_METHOD, operator, [methodName, staticType.displayName]);
+        bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod) && (_strictMode || shouldReportMissingMember(propagatedType, propagatedMethod));
+        bool shouldReportMissingMember_propagated = _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+        if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
+          ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_METHOD : HintCode.UNDEFINED_METHOD) as ErrorCode;
+          _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, errorCode, operator, [
+              methodName,
+              shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
         }
       }
     }
@@ -2984,8 +3018,13 @@
         Type2 propagatedType = getPropagatedType(leftOperand);
         MethodElement propagatedMethod = lookUpMethod(leftOperand, propagatedType, methodName);
         node.propagatedElement = propagatedMethod;
-        if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
-          _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displayName]);
+        bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod) && (_strictMode || shouldReportMissingMember(propagatedType, propagatedMethod));
+        bool shouldReportMissingMember_propagated = _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+        if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
+          ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
+          _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, errorCode, operator, [
+              methodName,
+              shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
         }
       }
     }
@@ -3311,7 +3350,15 @@
         argumentList.correspondingPropagatedParameters = parameters;
       }
     }
-    ErrorCode errorCode = checkForInvocationError(target, staticElement);
+    ErrorCode errorCode = checkForInvocationError(target, true, staticElement);
+    bool generatedWithTypePropagation = false;
+    if (_enableHints && errorCode == null && staticElement == null) {
+      errorCode = checkForInvocationError(target, false, propagatedElement);
+      generatedWithTypePropagation = true;
+    }
+    if (errorCode == null) {
+      return null;
+    }
     if (identical(errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION)) {
       _resolver.reportError5(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName, [methodName.name]);
     } else if (identical(errorCode, CompileTimeErrorCode.UNDEFINED_FUNCTION)) {
@@ -3321,20 +3368,27 @@
       if (target == null) {
         ClassElement enclosingClass = _resolver.enclosingClass;
         targetTypeName = enclosingClass.displayName;
-        _resolver.reportErrorProxyConditionalAnalysisError(_resolver.enclosingClass, StaticTypeWarningCode.UNDEFINED_METHOD, methodName, [methodName.name, targetTypeName]);
+        ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDEFINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode;
+        _resolver.reportErrorProxyConditionalAnalysisError(_resolver.enclosingClass, proxyErrorCode, methodName, [methodName.name, targetTypeName]);
       } else {
-        Type2 targetType = getStaticType(target);
+        Type2 targetType = null;
+        if (!generatedWithTypePropagation) {
+          targetType = getStaticType(target);
+        } else {
+          targetType = getPropagatedType(target);
+          if (targetType == null) {
+            targetType = getStaticType(target);
+          }
+        }
         if (targetType != null && targetType.isDartCoreFunction && methodName.name == CALL_METHOD_NAME) {
           return null;
         }
         targetTypeName = targetType == null ? null : targetType.displayName;
-        _resolver.reportErrorProxyConditionalAnalysisError(targetType.element, StaticTypeWarningCode.UNDEFINED_METHOD, methodName, [methodName.name, targetTypeName]);
+        ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDEFINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode;
+        _resolver.reportErrorProxyConditionalAnalysisError(targetType.element, proxyErrorCode, methodName, [methodName.name, targetTypeName]);
       }
     } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) {
-      Type2 targetType = getPropagatedType(target);
-      if (targetType == null) {
-        targetType = getStaticType(target);
-      }
+      Type2 targetType = getStaticType(target);
       String targetTypeName = targetType == null ? null : targetType.name;
       _resolver.reportError5(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, methodName, [methodName.name, targetTypeName]);
     }
@@ -3357,8 +3411,13 @@
     Type2 propagatedType = getPropagatedType(operand);
     MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, methodName);
     node.propagatedElement = propagatedMethod;
-    if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
-      _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, node.operator, [methodName, staticType.displayName]);
+    bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod) && (_strictMode || shouldReportMissingMember(propagatedType, propagatedMethod));
+    bool shouldReportMissingMember_propagated = _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+    if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
+      ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
+      _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, errorCode, node.operator, [
+          methodName,
+          shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
     }
     return null;
   }
@@ -3415,8 +3474,13 @@
       Type2 propagatedType = getPropagatedType(operand);
       MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, methodName);
       node.propagatedElement = propagatedMethod;
-      if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
-        _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displayName]);
+      bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod) && (_strictMode || shouldReportMissingMember(propagatedType, propagatedMethod));
+      bool shouldReportMissingMember_propagated = _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+      if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
+        ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
+        _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, errorCode, operator, [
+            methodName,
+            shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
       }
     }
     return null;
@@ -3573,10 +3637,11 @@
    * reported, or `null` if no error should be reported.
    *
    * @param target the target of the invocation, or `null` if there was no target
+   * @param useStaticContext
    * @param element the element to be invoked
    * @return the error code that should be reported
    */
-  ErrorCode checkForInvocationError(Expression target, Element element) {
+  ErrorCode checkForInvocationError(Expression target, bool useStaticContext, Element element) {
     if (element is PrefixElement) {
       element = null;
     }
@@ -3618,7 +3683,15 @@
             return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
           }
         } else {
-          Type2 targetType = getStaticType(target);
+          Type2 targetType;
+          if (useStaticContext) {
+            targetType = getStaticType(target);
+          } else {
+            targetType = getPropagatedType(target);
+            if (targetType == null) {
+              targetType = getStaticType(target);
+            }
+          }
           if (targetType == null) {
             return CompileTimeErrorCode.UNDEFINED_FUNCTION;
           } else if (!targetType.isDynamic) {
@@ -3641,15 +3714,22 @@
    * @return `true` if and only if an error code is generated on the passed node
    */
   bool checkForUndefinedIndexOperator(IndexExpression node, Expression target, String methodName, MethodElement staticMethod, MethodElement propagatedMethod, Type2 staticType, Type2 propagatedType) {
-    if (shouldReportMissingMember(staticType, staticMethod) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
+    bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticMethod) && (_strictMode || shouldReportMissingMember(propagatedType, propagatedMethod));
+    bool shouldReportMissingMember_propagated = _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false;
+    if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
       sc.Token leftBracket = node.leftBracket;
       sc.Token rightBracket = node.rightBracket;
+      ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
       if (leftBracket == null || rightBracket == null) {
-        _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, node, [methodName, staticType.displayName]);
+        _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, node, [
+            methodName,
+            shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
       } else {
         int offset = leftBracket.offset;
         int length = rightBracket.offset - offset + 1;
-        _resolver.reportErrorProxyConditionalAnalysisError2(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, offset, length, [methodName, staticType.displayName]);
+        _resolver.reportErrorProxyConditionalAnalysisError2(staticType.element, errorCode, offset, length, [
+            methodName,
+            shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
       }
       return true;
     }
@@ -3665,9 +3745,9 @@
    * @param executableElement the element that will be invoked with the arguments
    * @return the parameters that correspond to the arguments
    */
-  List<ParameterElement> computeCorrespondingParameters(ArgumentList argumentList, Element element2) {
-    if (element2 is PropertyAccessorElement) {
-      FunctionType getterType = ((element2 as PropertyAccessorElement)).type;
+  List<ParameterElement> computeCorrespondingParameters(ArgumentList argumentList, Element element) {
+    if (element is PropertyAccessorElement) {
+      FunctionType getterType = ((element as PropertyAccessorElement)).type;
       if (getterType != null) {
         Type2 getterReturnType = getterType.returnType;
         if (getterReturnType is InterfaceType) {
@@ -3682,10 +3762,10 @@
           }
         }
       }
-    } else if (element2 is ExecutableElement) {
-      return resolveArgumentsToParameters(false, argumentList, element2 as ExecutableElement);
-    } else if (element2 is VariableElement) {
-      VariableElement variable = element2 as VariableElement;
+    } else if (element is ExecutableElement) {
+      return resolveArgumentsToParameters(false, argumentList, element as ExecutableElement);
+    } else if (element is VariableElement) {
+      VariableElement variable = element as VariableElement;
       Type2 type = variable.type;
       if (type is FunctionType) {
         FunctionType functionType = type as FunctionType;
@@ -4262,9 +4342,9 @@
    * @param nameNode the name of the invoked constructor, may be `null` if unnamed constructor
    *          or not a constructor invocation
    */
-  void resolveAnnotationElement(Annotation annotation, Element element2, SimpleIdentifier nameNode) {
-    if (element2 is PropertyAccessorElement) {
-      PropertyAccessorElement accessorElement = element2 as PropertyAccessorElement;
+  void resolveAnnotationElement(Annotation annotation, Element element, SimpleIdentifier nameNode) {
+    if (element is PropertyAccessorElement) {
+      PropertyAccessorElement accessorElement = element as PropertyAccessorElement;
       if (!accessorElement.isSynthetic) {
         _resolver.reportError5(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
         return;
@@ -4275,14 +4355,14 @@
       }
       return;
     }
-    if (element2 is ClassElement) {
+    if (element is ClassElement) {
       if (nameNode == null) {
         nameNode = annotation.constructorName;
       }
       String name = nameNode != null ? nameNode.name : null;
       ConstructorElement constructor;
       {
-        InterfaceType interfaceType = new InterfaceTypeImpl.con1(element2 as ClassElement);
+        InterfaceType interfaceType = new InterfaceTypeImpl.con1(element as ClassElement);
         LibraryElement definingLibrary = _resolver.definingLibrary;
         constructor = interfaceType.lookUpConstructor(name, definingLibrary);
       }
@@ -4297,7 +4377,7 @@
       resolveAnnotationConstructorInvocationArguments(annotation, constructor);
       return;
     }
-    if (element2 != null) {
+    if (element != null) {
       _resolver.reportError5(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
     }
   }
@@ -4507,20 +4587,34 @@
     Type2 propagatedType = getPropagatedType(target);
     ExecutableElement propagatedElement = resolveProperty(target, propagatedType, propertyName);
     propertyName.propagatedElement = propagatedElement;
-    if (shouldReportMissingMember(staticType, staticElement) && (_strictMode || propagatedType == null || shouldReportMissingMember(propagatedType, propagatedElement))) {
+    bool shouldReportMissingMember_static = shouldReportMissingMember(staticType, staticElement) && (_strictMode || shouldReportMissingMember(propagatedType, propagatedElement));
+    bool shouldReportMissingMember_propagated = _enableHints ? shouldReportMissingMember(propagatedType, propagatedElement) : false;
+    if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
       Element selectedElement = select(staticElement, propagatedElement);
       bool isStaticProperty = isStatic(selectedElement);
       if (propertyName.inSetterContext()) {
         if (isStaticProperty) {
-          _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticWarningCode.UNDEFINED_SETTER, propertyName, [propertyName.name, staticType.displayName]);
+          ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode;
+          _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, propertyName, [
+              propertyName.name,
+              shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
         } else {
-          _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticTypeWarningCode.UNDEFINED_SETTER, propertyName, [propertyName.name, staticType.displayName]);
+          ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode;
+          _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, propertyName, [
+              propertyName.name,
+              shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
         }
       } else if (propertyName.inGetterContext()) {
         if (isStaticProperty) {
-          _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticWarningCode.UNDEFINED_GETTER, propertyName, [propertyName.name, staticType.displayName]);
+          ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode;
+          _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, propertyName, [
+              propertyName.name,
+              shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
         } else {
-          _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticTypeWarningCode.UNDEFINED_GETTER, propertyName, [propertyName.name, staticType.displayName]);
+          ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode;
+          _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, propertyName, [
+              propertyName.name,
+              shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
         }
       } else {
         _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, [propertyName.name]);
@@ -4811,8 +4905,8 @@
    *
    * @param library the new library element
    */
-  void set libraryElement(LibraryElement library2) {
-    this._library = library2;
+  void set libraryElement(LibraryElement library) {
+    this._library = library;
   }
 
   /**
@@ -5353,7 +5447,7 @@
       try {
         _libraryElement = _analysisContext.computeLibraryElement(librarySource) as LibraryElementImpl;
       } on AnalysisException catch (exception) {
-        AnalysisEngine.instance.logger.logError2("Could not compute ilbrary element for ${librarySource.fullName}", exception);
+        AnalysisEngine.instance.logger.logError2("Could not compute library element for ${librarySource.fullName}", exception);
       }
     }
     return _libraryElement;
@@ -5439,8 +5533,8 @@
    *
    * @param exportedLibraries the libraries that are exported by this library
    */
-  void set exportedLibraries(List<Library> exportedLibraries2) {
-    this.exports = exportedLibraries2;
+  void set exportedLibraries(List<Library> exportedLibraries) {
+    this.exports = exportedLibraries;
   }
 
   /**
@@ -5448,8 +5542,8 @@
    *
    * @param importedLibraries the libraries that are imported into this library
    */
-  void set importedLibraries(List<Library> importedLibraries2) {
-    this.imports = importedLibraries2;
+  void set importedLibraries(List<Library> importedLibraries) {
+    this.imports = importedLibraries;
   }
 
   /**
@@ -5457,10 +5551,10 @@
    *
    * @param libraryElement the library element representing this library
    */
-  void set libraryElement(LibraryElementImpl libraryElement2) {
-    this._libraryElement = libraryElement2;
+  void set libraryElement(LibraryElementImpl libraryElement) {
+    this._libraryElement = libraryElement;
     if (_inheritanceManager != null) {
-      _inheritanceManager.libraryElement = libraryElement2;
+      _inheritanceManager.libraryElement = libraryElement;
     }
   }
   String toString() => librarySource.shortName;
@@ -6349,9 +6443,9 @@
    * @param element the class being tested
    * @return `true` if the given element represents a class that has the proxy annotation
    */
-  static bool classHasProxyAnnotation(Element element2) {
-    if (element2 is ClassElement) {
-      ClassElement classElement = element2 as ClassElement;
+  static bool classHasProxyAnnotation(Element element) {
+    if (element is ClassElement) {
+      ClassElement classElement = element as ClassElement;
       List<ElementAnnotation> annotations = classElement.metadata;
       for (ElementAnnotation annotation in annotations) {
         Element elementAnnotation = annotation.element;
@@ -7112,11 +7206,11 @@
    * @param expression the expression being tested
    * @return `true` if the given expression terminates abruptly
    */
-  bool isAbruptTermination(Expression expression2) {
-    while (expression2 is ParenthesizedExpression) {
-      expression2 = ((expression2 as ParenthesizedExpression)).expression;
+  bool isAbruptTermination(Expression expression) {
+    while (expression is ParenthesizedExpression) {
+      expression = ((expression as ParenthesizedExpression)).expression;
     }
-    return expression2 is ThrowExpression || expression2 is RethrowExpression;
+    return expression is ThrowExpression || expression is RethrowExpression;
   }
 
   /**
@@ -7404,6 +7498,16 @@
     }
     return null;
   }
+  Object visitFormalParameterList(FormalParameterList node) {
+    super.visitFormalParameterList(node);
+    if (nameScope is FunctionScope) {
+      ((nameScope as FunctionScope)).defineParameters();
+    }
+    if (nameScope is FunctionTypeScope) {
+      ((nameScope as FunctionTypeScope)).defineParameters();
+    }
+    return null;
+  }
   Object visitForStatement(ForStatement node) {
     Scope outerNameScope = nameScope;
     LabelScope outerLabelScope = labelScope;
@@ -7813,8 +7917,8 @@
    *
    * @param thisType the type representing the class containing the nodes being analyzed
    */
-  void set thisType(InterfaceType thisType2) {
-    this._thisType = thisType2;
+  void set thisType(InterfaceType thisType) {
+    this._thisType = thisType;
   }
 
   /**
@@ -9943,12 +10047,12 @@
     TypeArgumentList argumentList = node.typeArguments;
     Element element = nameScope.lookup(typeName, definingLibrary);
     if (element == null) {
-      if (typeName.name == _dynamicType.name) {
-        setElement(typeName, _dynamicType.element);
+      if (typeName.name == this._dynamicType.name) {
+        setElement(typeName, this._dynamicType.element);
         if (argumentList != null) {
         }
-        typeName.staticType = _dynamicType;
-        node.type = _dynamicType;
+        typeName.staticType = this._dynamicType;
+        node.type = this._dynamicType;
         return null;
       }
       VoidTypeImpl voidType = VoidTypeImpl.instance;
@@ -10024,10 +10128,10 @@
       if (element is MultiplyDefinedElement) {
         setElement(typeName, element);
       } else {
-        setElement(typeName, _dynamicType.element);
+        setElement(typeName, this._dynamicType.element);
       }
-      typeName.staticType = _dynamicType;
-      node.type = _dynamicType;
+      typeName.staticType = this._dynamicType;
+      node.type = this._dynamicType;
       return null;
     }
     Type2 type = null;
@@ -10069,9 +10173,9 @@
           reportError5(StaticWarningCode.NOT_A_TYPE, typeName, [typeName.name]);
         }
       }
-      setElement(typeName, _dynamicType.element);
-      typeName.staticType = _dynamicType;
-      node.type = _dynamicType;
+      setElement(typeName, this._dynamicType.element);
+      typeName.staticType = this._dynamicType;
+      node.type = this._dynamicType;
       return null;
     }
     if (argumentList != null) {
@@ -10093,7 +10197,7 @@
       argumentCount = typeArguments.length;
       if (argumentCount < parameterCount) {
         for (int i = argumentCount; i < parameterCount; i++) {
-          typeArguments.add(_dynamicType);
+          typeArguments.add(this._dynamicType);
         }
       }
       if (type is InterfaceTypeImpl) {
@@ -10513,12 +10617,12 @@
    * @param returnType the (possibly `null`) return type of the function
    * @param parameterList the list of parameters to the function
    */
-  void setFunctionTypedParameterType(ParameterElementImpl element, TypeName returnType2, FormalParameterList parameterList) {
+  void setFunctionTypedParameterType(ParameterElementImpl element, TypeName returnType, FormalParameterList parameterList) {
     List<ParameterElement> parameters = getElements(parameterList);
     FunctionTypeAliasElementImpl aliasElement = new FunctionTypeAliasElementImpl(null);
     aliasElement.synthetic = true;
     aliasElement.shareParameters(parameters);
-    aliasElement.returnType = computeReturnType(returnType2);
+    aliasElement.returnType = computeReturnType(returnType);
     FunctionTypeImpl type = new FunctionTypeImpl.con2(aliasElement);
     ClassElement definingClass = element.getAncestor(ClassElement);
     if (definingClass != null) {
@@ -10655,6 +10759,8 @@
  * @coverage dart.engine.resolver
  */
 class FunctionScope extends EnclosedScope {
+  ExecutableElement _functionElement;
+  bool _parametersDefined = false;
 
   /**
    * Initialize a newly created scope enclosed within another scope.
@@ -10663,23 +10769,25 @@
    * @param functionElement the element representing the type represented by this scope
    */
   FunctionScope(Scope enclosingScope, ExecutableElement functionElement) : super(new EnclosedScope(enclosingScope)) {
-    defineParameters(functionElement);
+    this._functionElement = functionElement;
   }
 
   /**
    * Define the parameters for the given function in the scope that encloses this function.
-   *
-   * @param functionElement the element representing the function represented by this scope
    */
-  void defineParameters(ExecutableElement functionElement) {
+  void defineParameters() {
+    if (_parametersDefined) {
+      return;
+    }
+    _parametersDefined = true;
     Scope parameterScope = enclosingScope;
-    if (functionElement.enclosingElement is ExecutableElement) {
-      String name = functionElement.name;
+    if (_functionElement.enclosingElement is ExecutableElement) {
+      String name = _functionElement.name;
       if (name != null && !name.isEmpty) {
-        parameterScope.define(functionElement);
+        parameterScope.define(_functionElement);
       }
     }
-    for (ParameterElement parameter in functionElement.parameters) {
+    for (ParameterElement parameter in _functionElement.parameters) {
       if (!parameter.isInitializingFormal) {
         parameterScope.define(parameter);
       }
@@ -10693,6 +10801,8 @@
  * @coverage dart.engine.resolver
  */
 class FunctionTypeScope extends EnclosedScope {
+  FunctionTypeAliasElement _typeElement;
+  bool _parametersDefined = false;
 
   /**
    * Initialize a newly created scope enclosed within another scope.
@@ -10701,8 +10811,8 @@
    * @param typeElement the element representing the type alias represented by this scope
    */
   FunctionTypeScope(Scope enclosingScope, FunctionTypeAliasElement typeElement) : super(new EnclosedScope(enclosingScope)) {
-    defineTypeParameters(typeElement);
-    defineParameters(typeElement);
+    this._typeElement = typeElement;
+    defineTypeParameters();
   }
 
   /**
@@ -10710,8 +10820,12 @@
    *
    * @param typeElement the element representing the type represented by this scope
    */
-  void defineParameters(FunctionTypeAliasElement typeElement) {
-    for (ParameterElement parameter in typeElement.parameters) {
+  void defineParameters() {
+    if (_parametersDefined) {
+      return;
+    }
+    _parametersDefined = true;
+    for (ParameterElement parameter in _typeElement.parameters) {
       define(parameter);
     }
   }
@@ -10721,9 +10835,9 @@
    *
    * @param typeElement the element representing the type represented by this scope
    */
-  void defineTypeParameters(FunctionTypeAliasElement typeElement) {
+  void defineTypeParameters() {
     Scope typeParameterScope = enclosingScope;
-    for (TypeParameterElement typeParameter in typeElement.typeParameters) {
+    for (TypeParameterElement typeParameter in _typeElement.typeParameters) {
       typeParameterScope.define(typeParameter);
     }
   }
@@ -10884,7 +10998,7 @@
       if (enclosingLibrary != null) {
         libName2 = enclosingLibrary.definingCompilationUnit.displayName;
       }
-      _errorListener.onError(new AnalysisError.con2(source2, identifier.offset, identifier.length, StaticWarningCode.AMBIGUOUS_IMPORT, [foundEltName, libName1, libName2]));
+      _errorListener.onError(new AnalysisError.con2(source, identifier.offset, identifier.length, StaticWarningCode.AMBIGUOUS_IMPORT, [foundEltName, libName1, libName2]));
       return foundElement;
     }
     if (foundElement != null) {
@@ -10927,6 +11041,9 @@
       return foundElement;
     } else if (to == 1) {
       return conflictingMembers[0];
+    } else if (to == 0) {
+      AnalysisEngine.instance.logger.logInformation("Multiply defined SDK element: ${foundElement}");
+      return foundElement;
     }
     List<Element> remaining = new List<Element>(to);
     JavaSystem.arraycopy(conflictingMembers, 0, remaining, 0, to);
@@ -10959,7 +11076,7 @@
           offset = accessor.variable.nameOffset;
         }
       }
-      return new AnalysisError.con2(source2, offset, duplicate.displayName.length, CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, [existing.displayName]);
+      return new AnalysisError.con2(source, offset, duplicate.displayName.length, CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, [existing.displayName]);
     }
     return super.getErrorForDuplicate(existing, duplicate);
   }
@@ -11129,9 +11246,9 @@
    * @param definedNames the mapping table to which the names in the given namespace are to be added
    * @param namespace the namespace containing the names to be added to this namespace
    */
-  void addAll2(Map<String, Element> definedNames2, Namespace namespace) {
+  void addAll2(Map<String, Element> definedNames, Namespace namespace) {
     if (namespace != null) {
-      addAll(definedNames2, namespace.definedNames);
+      addAll(definedNames, namespace.definedNames);
     }
   }
 
@@ -11379,7 +11496,7 @@
   AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
     Source source = duplicate.source;
     if (source == null) {
-      source = source2;
+      source = this.source;
     }
     return new AnalysisError.con2(source, duplicate.nameOffset, duplicate.displayName.length, CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.displayName]);
   }
@@ -11397,7 +11514,7 @@
    *
    * @return the source object with which errors should be associated
    */
-  Source get source2 => definingLibrary.definingCompilationUnit.source;
+  Source get source => definingLibrary.definingCompilationUnit.source;
 
   /**
    * Return the element with which the given name is associated, or `null` if the name is not
@@ -11602,14 +11719,14 @@
    * @param result the result containing any errors that need to be reported
    * @param errorCode the error code to be used if the result represents an error
    */
-  void reportErrors(EvaluationResultImpl result, ErrorCode errorCode2) {
+  void reportErrors(EvaluationResultImpl result, ErrorCode errorCode) {
     if (result is ErrorResult) {
       for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) {
         ErrorCode dataErrorCode = data.errorCode;
         if (identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_INT) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM)) {
           _errorReporter.reportError2(dataErrorCode, data.node, []);
         } else {
-          _errorReporter.reportError2(errorCode2, data.node, []);
+          _errorReporter.reportError2(errorCode, data.node, []);
         }
       }
     }
@@ -11666,11 +11783,11 @@
    *
    * @param parameters the list of parameters to be validated
    */
-  void validateDefaultValues(FormalParameterList parameters2) {
-    if (parameters2 == null) {
+  void validateDefaultValues(FormalParameterList parameters) {
+    if (parameters == null) {
       return;
     }
-    for (FormalParameter parameter in parameters2.parameters) {
+    for (FormalParameter parameter in parameters.parameters) {
       if (parameter is DefaultFormalParameter) {
         DefaultFormalParameter defaultParameter = parameter as DefaultFormalParameter;
         Expression defaultValue = defaultParameter.defaultValue;
@@ -12555,7 +12672,7 @@
    * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE
    * @see StaticWarningCode#INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
    */
-  bool checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement, List<ParameterElement> parameters2, List<ASTNode> parameterLocations, SimpleIdentifier errorNameTarget) {
+  bool checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement, List<ParameterElement> parameters, List<ASTNode> parameterLocations, SimpleIdentifier errorNameTarget) {
     String executableElementName = executableElement.name;
     ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritance(_enclosingClass, executableElementName);
     bool isGetter = false;
@@ -12675,8 +12792,8 @@
       if (!overriddenNamedPTEntry.getValue().isAssignableTo(overridingType)) {
         ParameterElement parameterToSelect = null;
         ASTNode parameterLocationToSelect = null;
-        for (int i = 0; i < parameters2.length; i++) {
-          ParameterElement parameter = parameters2[i];
+        for (int i = 0; i < parameters.length; i++) {
+          ParameterElement parameter = parameters[i];
           if (identical(parameter.parameterKind, ParameterKind.NAMED) && overriddenNamedPTEntry.getKey() == parameter.name) {
             parameterToSelect = parameter;
             parameterLocationToSelect = parameterLocations[i];
@@ -12697,8 +12814,8 @@
     List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>();
     List<ParameterElementImpl> overriddenParameterElts = new List<ParameterElementImpl>();
     List<ParameterElement> overriddenPEs = overriddenExecutable.parameters;
-    for (int i = 0; i < parameters2.length; i++) {
-      ParameterElement parameter = parameters2[i];
+    for (int i = 0; i < parameters.length; i++) {
+      ParameterElement parameter = parameters[i];
       if (parameter.parameterKind.isOptional) {
         formalParameters.add(parameterLocations[i]);
         parameterElts.add(parameter as ParameterElementImpl);
@@ -13250,11 +13367,11 @@
    * @return `true` if and only if an error code is generated on the passed node
    * @see CompileTimeErrorCode#CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
    */
-  bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node, Type2 type2) {
-    if (type2 == null || type2 == _typeProvider.intType || type2 == _typeProvider.stringType) {
+  bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node, Type2 type) {
+    if (type == null || type == _typeProvider.intType || type == _typeProvider.stringType) {
       return false;
     }
-    Element element = type2.element;
+    Element element = type.element;
     if (element is! ClassElement) {
       return false;
     }
@@ -14258,14 +14375,14 @@
    * @return `true` if and only if an error code is generated on the passed node
    * @see StaticTypeWarningCode#INSTANCE_ACCESS_TO_STATIC_MEMBER
    */
-  bool checkForInstanceAccessToStaticMember(Expression target, SimpleIdentifier name2) {
+  bool checkForInstanceAccessToStaticMember(Expression target, SimpleIdentifier name) {
     if (target == null) {
       return false;
     }
     if (_isInComment) {
       return false;
     }
-    Element element = name2.staticElement;
+    Element element = name.staticElement;
     if (element is! ExecutableElement) {
       return false;
     }
@@ -14279,7 +14396,7 @@
     if (isTypeReference(target)) {
       return false;
     }
-    _errorReporter.reportError2(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name2, [name2.name]);
+    _errorReporter.reportError2(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name, [name.name]);
     return true;
   }
 
@@ -15274,8 +15391,8 @@
    * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER
    */
-  bool checkForStaticAccessToInstanceMember(Expression target, SimpleIdentifier name2) {
-    Element element = name2.staticElement;
+  bool checkForStaticAccessToInstanceMember(Expression target, SimpleIdentifier name) {
+    Element element = name.staticElement;
     if (element is! ExecutableElement) {
       return false;
     }
@@ -15286,7 +15403,7 @@
     if (!isTypeReference(target)) {
       return false;
     }
-    _errorReporter.reportError2(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name2, [name2.name]);
+    _errorReporter.reportError2(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]);
     return true;
   }
 
@@ -15475,8 +15592,8 @@
    * @return `true` if and only if an error code is generated on the passed node
    * @see StaticTypeWarningCode#UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER
    */
-  bool checkForUnqualifiedReferenceToNonLocalStaticMember(SimpleIdentifier name2) {
-    Element element = name2.staticElement;
+  bool checkForUnqualifiedReferenceToNonLocalStaticMember(SimpleIdentifier name) {
+    Element element = name.staticElement;
     if (element == null || element is TypeParameterElement) {
       return false;
     }
@@ -15490,7 +15607,7 @@
     if (identical(enclosingElement, _enclosingClass)) {
       return false;
     }
-    _errorReporter.reportError2(StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, name2, [name2.name]);
+    _errorReporter.reportError2(StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, name, [name.name]);
     return true;
   }
 
diff --git a/pkg/analyzer_experimental/lib/src/generated/scanner.dart b/pkg/analyzer_experimental/lib/src/generated/scanner.dart
index 67ffec0..7ee43be 100644
--- a/pkg/analyzer_experimental/lib/src/generated/scanner.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/scanner.dart
@@ -38,13 +38,13 @@
    * @param length the number of strings in the array that pass through the state being built
    * @return the state that was created
    */
-  static KeywordState computeKeywordStateTable(int start, List<String> strings, int offset, int length2) {
+  static KeywordState computeKeywordStateTable(int start, List<String> strings, int offset, int length) {
     List<KeywordState> result = new List<KeywordState>(26);
-    assert(length2 != 0);
+    assert(length != 0);
     int chunk = 0x0;
     int chunkStart = -1;
     bool isLeaf = false;
-    for (int i = offset; i < offset + length2; i++) {
+    for (int i = offset; i < offset + length; i++) {
       if (strings[i].length == start) {
         isLeaf = true;
       }
@@ -61,9 +61,9 @@
     }
     if (chunkStart != -1) {
       assert(result[chunk - 0x61] == null);
-      result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, offset + length2 - chunkStart);
+      result[chunk - 0x61] = computeKeywordStateTable(start + 1, strings, chunkStart, offset + length - chunkStart);
     } else {
-      assert(length2 == 1);
+      assert(length == 1);
       return new KeywordState(_EMPTY_TABLE, strings[offset]);
     }
     if (isLeaf) {
@@ -544,12 +544,12 @@
       _lastComment = _lastComment.setNext(new StringToken(type, value, _tokenStart));
     }
   }
-  void appendEndToken(TokenType type2, TokenType beginType) {
+  void appendEndToken(TokenType type, TokenType beginType) {
     Token token;
     if (_firstComment == null) {
-      token = new Token(type2, _tokenStart);
+      token = new Token(type, _tokenStart);
     } else {
-      token = new TokenWithComment(type2, _tokenStart, _firstComment);
+      token = new TokenWithComment(type, _tokenStart, _firstComment);
       _firstComment = null;
       _lastComment = null;
     }
@@ -643,8 +643,8 @@
       return advance();
     }
     if (next == 0x72) {
-      int peek2 = peek();
-      if (peek2 == 0x22 || peek2 == 0x27) {
+      int peek = this.peek();
+      if (peek == 0x22 || peek == 0x27) {
         int start = offset;
         return tokenizeString(advance(), start, true);
       }
@@ -1017,23 +1017,23 @@
     beginToken();
     return next;
   }
-  int tokenizeKeywordOrIdentifier(int next2, bool allowDollar) {
+  int tokenizeKeywordOrIdentifier(int next, bool allowDollar) {
     KeywordState state = KeywordState.KEYWORD_STATE;
     int start = offset;
-    while (state != null && 0x61 <= next2 && next2 <= 0x7A) {
-      state = state.next(next2 as int);
-      next2 = advance();
+    while (state != null && 0x61 <= next && next <= 0x7A) {
+      state = state.next(next as int);
+      next = advance();
     }
     if (state == null || state.keyword() == null) {
-      return tokenizeIdentifier(next2, start, allowDollar);
+      return tokenizeIdentifier(next, start, allowDollar);
     }
-    if ((0x41 <= next2 && next2 <= 0x5A) || (0x30 <= next2 && next2 <= 0x39) || next2 == 0x5F || next2 == 0x24) {
-      return tokenizeIdentifier(next2, start, allowDollar);
-    } else if (next2 < 128) {
+    if ((0x41 <= next && next <= 0x5A) || (0x30 <= next && next <= 0x39) || next == 0x5F || next == 0x24) {
+      return tokenizeIdentifier(next, start, allowDollar);
+    } else if (next < 128) {
       appendKeywordToken(state.keyword());
-      return next2;
+      return next;
     } else {
-      return tokenizeIdentifier(next2, start, allowDollar);
+      return tokenizeIdentifier(next, start, allowDollar);
     }
   }
   int tokenizeLessThan(int next) {
diff --git a/pkg/analyzer_experimental/lib/src/generated/sdk.dart b/pkg/analyzer_experimental/lib/src/generated/sdk.dart
index 2accc54..234742f 100644
--- a/pkg/analyzer_experimental/lib/src/generated/sdk.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/sdk.dart
@@ -157,8 +157,8 @@
    *
    * @param category the name of the category containing the library
    */
-  void set category(String category2) {
-    this._category = category2;
+  void set category(String category) {
+    this._category = category;
   }
 
   /**
@@ -173,8 +173,8 @@
    *
    * @param documented `true` if the library is documented
    */
-  void set documented(bool documented2) {
-    this._documented = documented2;
+  void set documented(bool documented) {
+    this._documented = documented;
   }
 
   /**
@@ -182,8 +182,8 @@
    *
    * @param implementation `true` if the library is an implementation library
    */
-  void set implementation(bool implementation2) {
-    this._implementation = implementation2;
+  void set implementation(bool implementation) {
+    this._implementation = implementation;
   }
 
   /**
@@ -192,8 +192,8 @@
    *
    * @param path the path to the file defining the library
    */
-  void set path(String path2) {
-    this._path = path2;
+  void set path(String path) {
+    this._path = path;
   }
 
   /**
diff --git a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
index 032d5e7..6d3d7e9 100644
--- a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
@@ -195,7 +195,9 @@
       advance();
 
     }
-    if (!isEOF(token2)) {
+    // TODO(pquitslund): consider a better way to notice trailing synthetics
+    if (!isEOF(token2) && 
+        !(isCLOSE_CURLY_BRACKET(token2) && isEOF(token2.next))) {
       throw new FormatterException(
           'Expected "EOF" but got "${token2}".');
     }
@@ -261,6 +263,11 @@
         return true;
       }
     }
+    // Advance past synthetic { } tokens
+    if (isOPEN_CURLY_BRACKET(token2) || isCLOSE_CURLY_BRACKET(token2)) {
+      token2 = token2.next;
+      return checkTokens();
+    }
 
     return false;
   }
@@ -286,6 +293,14 @@
 /// Test if this token is an INDEX token.
 bool isINDEX(Token token) => tokenIs(token, TokenType.INDEX);
 
+/// Test if this token is a OPEN_CURLY_BRACKET token.
+bool isOPEN_CURLY_BRACKET(Token token) =>
+    tokenIs(token, TokenType.OPEN_CURLY_BRACKET);
+
+/// Test if this token is a CLOSE_CURLY_BRACKET token.
+bool isCLOSE_CURLY_BRACKET(Token token) =>
+    tokenIs(token, TokenType.CLOSE_CURLY_BRACKET);
+
 /// Test if this token is a OPEN_SQUARE_BRACKET token.
 bool isOPEN_SQ_BRACKET(Token token) =>
     tokenIs(token, TokenType.OPEN_SQUARE_BRACKET);
@@ -294,8 +309,19 @@
 bool isCLOSE_SQUARE_BRACKET(Token token) =>
     tokenIs(token, TokenType.CLOSE_SQUARE_BRACKET);
 
+
 /// An AST visitor that drives formatting heuristics.
 class SourceVisitor implements ASTVisitor {
+  
+  static final OPEN_CURLY = syntheticToken(TokenType.OPEN_CURLY_BRACKET, '{');
+  static final CLOSE_CURLY = syntheticToken(TokenType.CLOSE_CURLY_BRACKET, '}');
+  
+  static const SYNTH_OFFSET = -13;
+  
+  static StringToken syntheticToken(TokenType type, String value) =>
+      new StringToken(type, value, SYNTH_OFFSET);
+  
+  static bool isSynthetic(Token token) => token.offset == SYNTH_OFFSET;
 
   /// The writer to which the source is to be written.
   final SourceWriter writer;
@@ -308,6 +334,9 @@
 
   /// A flag to indicate that a newline should be emitted before the next token.
   bool needsNewline = false;
+  
+  /// A counter for spaces that should be emitted preceding the next token.
+  int leadingSpaces = 0;
 
   /// Used for matching EOL comments
   final twoSlashes = new RegExp(r'//[^/]');
@@ -514,13 +543,41 @@
     token(node.period);
     visit(node.name);
     visit(node.parameters);
-    token(node.separator /* = or : */, precededBy: space, followedBy: space);
-    visitNodes(node.initializers, separatedBy: commaSeperator);
-    visit(node.redirectedConstructor);
+    
+    // Check for redirects or initializer lists
+    if (node.separator != null) {
+      if (node.redirectedConstructor != null) {
+        visitConstructorRedirects(node);
+      } else { 
+        visitConstructorInitializers(node);
+      }
+    }
 
     visitPrefixedBody(space, node.body);
   }
 
+  visitConstructorInitializers(ConstructorDeclaration node) {
+    newlines();
+    indent(2);
+    token(node.separator /* : */);
+    space();
+    for (var i = 0; i < node.initializers.length; i++) {
+      if (i > 0) {
+        comma();
+        newlines();
+        space(2);
+      }
+      node.initializers[i].accept(this);
+    } 
+    unindent(2);
+  }
+
+  visitConstructorRedirects(ConstructorDeclaration node) {
+    token(node.separator /* = */, precededBy: space, followedBy: space);
+    visitNodes(node.initializers, separatedBy: commaSeperator);
+    visit(node.redirectedConstructor);
+  }
+  
   visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
     token(node.keyword);
     token(node.period);
@@ -730,24 +787,26 @@
     space();
     visitNodes(node.hiddenNames, separatedBy: commaSeperator);
   }
-
+  
   visitIfStatement(IfStatement node) {
+    var hasElse = node.elseStatement != null;
     token(node.ifKeyword);
     space();
     token(node.leftParenthesis);
     visit(node.condition);
     token(node.rightParenthesis);
     space();
-    visit(node.thenStatement);
-    //visitPrefixed(' else ', node.elseStatement);
-    if (node.elseStatement != null) {
+    if (hasElse) {
+      printAsBlock(node.thenStatement);
       space();
       token(node.elseKeyword);
       space();
-      visit(node.elseStatement);
+      printAsBlock(node.elseStatement);
+    } else {
+      visit(node.thenStatement);
     }
   }
-
+  
   visitImplementsClause(ImplementsClause node) {
     token(node.keyword);
     space();
@@ -1226,6 +1285,13 @@
     }
   }
   
+  emitSpaces() {
+    while (leadingSpaces > 0) {
+      writer.print(' ');
+      leadingSpaces--;
+    }
+  }
+  
   checkForSelectionUpdate(Token token) {
     // Cache the first token on or AFTER the selection offset
     if (preSelection != null && selection == null) {
@@ -1233,7 +1299,8 @@
       var overshot = token.offset - preSelection.offset;
       if (overshot >= 0) {
         //TODO(pquitslund): update length (may need truncating)
-        selection = new Selection(writer.toString().length - overshot, 
+        selection = new Selection(
+            writer.toString().length + leadingSpaces - overshot, 
             preSelection.length);
       }
     }
@@ -1245,15 +1312,16 @@
   }
 
   comma() {
-    append(',');
+    writer.print(',');
   }
 
+  
   /// Emit a non-breakable space.
-  space() {
+  space([n = 1]) {
     //TODO(pquitslund): replace with a proper space token
-    append(' ');
+    leadingSpaces+=n;
   }
-
+  
   /// Emit a breakable space
   breakableSpace() {
     //Implement
@@ -1262,21 +1330,40 @@
   /// Append the given [string] to the source writer if it's non-null.
   append(String string) {
     if (string != null && !string.isEmpty) {
+      emitSpaces();
       writer.print(string);
     }
   }
 
   /// Indent.
-  indent() {
-    writer.indent();
+  indent([n = 1]) {
+    while (n-- > 0) {
+      writer.indent();
+    }
   }
-
+  
   /// Unindent
-  unindent() {
-    writer.unindent();
+  unindent([n = 1]) {
+    while (n-- > 0) {
+      writer.unindent();
+    }
   }
-
-
+  
+  /// Print this statement as if it were a block (e.g., surrounded by braces).
+  printAsBlock(Statement statement) {
+    if (statement is! Block) {
+      token(OPEN_CURLY);
+      indent();
+      newlines();
+      visit(statement);
+      newlines();
+      unindent();
+      token(CLOSE_CURLY);
+    } else {
+      visit(statement);
+    }
+  }
+  
   /// Emit any detected comments and newlines or a minimum as specified
   /// by [min].
   int emitPrecedingCommentsAndNewlines(Token token, {min: 0}) {
@@ -1294,7 +1381,7 @@
     var lines = max(min, countNewlinesBetween(previousToken, currentToken));
     writer.newlines(lines);
 
-    var previousToken = currentToken.previous;
+    previousToken = currentToken.previous;
 
     while (comment != null) {
 
@@ -1306,7 +1393,7 @@
         writer.newlines(newlines);
         lines += newlines;
       } else if (!isEOF(token)) {
-        space();
+        append(' ');
       }
 
       previousToken = comment;
@@ -1336,7 +1423,7 @@
       var ws = countSpacesBetween(previousToken, comment);
       // Preserve one space but no more
       if (ws > 0) {
-        space();
+        append(' ');
       }
     }
 
@@ -1361,7 +1448,7 @@
 
   /// Count the blanks between these two tokens.
   int countNewlinesBetween(Token last, Token current) {
-    if (last == null || current == null) {
+    if (last == null || current == null || isSynthetic(last)) {
       return 0;
     }
 
diff --git a/pkg/analyzer_experimental/test/generated/ast_test.dart b/pkg/analyzer_experimental/test/generated/ast_test.dart
index 36380ec..0c07d4c 100644
--- a/pkg/analyzer_experimental/test/generated/ast_test.dart
+++ b/pkg/analyzer_experimental/test/generated/ast_test.dart
@@ -262,7 +262,7 @@
   static CompilationUnit compilationUnit5(String scriptTag) => compilationUnit8(scriptTag, null, null);
   static CompilationUnit compilationUnit6(String scriptTag, List<CompilationUnitMember> declarations) => compilationUnit8(scriptTag, null, list(declarations));
   static CompilationUnit compilationUnit7(String scriptTag, List<Directive> directives) => compilationUnit8(scriptTag, list(directives), null);
-  static CompilationUnit compilationUnit8(String scriptTag2, List<Directive> directives, List<CompilationUnitMember> declarations) => new CompilationUnit.full(TokenFactory.token3(TokenType.EOF), scriptTag2 == null ? null : scriptTag(scriptTag2), directives == null ? new List<Directive>() : directives, declarations == null ? new List<CompilationUnitMember>() : declarations, TokenFactory.token3(TokenType.EOF));
+  static CompilationUnit compilationUnit8(String scriptTag, List<Directive> directives, List<CompilationUnitMember> declarations) => new CompilationUnit.full(TokenFactory.token3(TokenType.EOF), scriptTag == null ? null : ASTFactory.scriptTag(scriptTag), directives == null ? new List<Directive>() : directives, declarations == null ? new List<CompilationUnitMember>() : declarations, TokenFactory.token3(TokenType.EOF));
   static ConditionalExpression conditionalExpression(Expression condition, Expression thenExpression, Expression elseExpression) => new ConditionalExpression.full(condition, TokenFactory.token3(TokenType.QUESTION), thenExpression, TokenFactory.token3(TokenType.COLON), elseExpression);
   static ConstructorDeclaration constructorDeclaration(Identifier returnType, String name, FormalParameterList parameters, List<ConstructorInitializer> initializers) => new ConstructorDeclaration.full(null, null, TokenFactory.token(Keyword.EXTERNAL), null, null, returnType, name == null ? null : TokenFactory.token3(TokenType.PERIOD), name == null ? null : identifier3(name), parameters, initializers == null || initializers.isEmpty ? null : TokenFactory.token3(TokenType.PERIOD), initializers == null ? new List<ConstructorInitializer>() : initializers, null, emptyFunctionBody());
   static ConstructorDeclaration constructorDeclaration2(Keyword constKeyword, Keyword factoryKeyword, Identifier returnType, String name, FormalParameterList parameters, List<ConstructorInitializer> initializers, FunctionBody body) => new ConstructorDeclaration.full(null, null, null, constKeyword == null ? null : TokenFactory.token(constKeyword), factoryKeyword == null ? null : TokenFactory.token(factoryKeyword), returnType, name == null ? null : TokenFactory.token3(TokenType.PERIOD), name == null ? null : identifier3(name), parameters, initializers == null || initializers.isEmpty ? null : TokenFactory.token3(TokenType.PERIOD), initializers == null ? new List<ConstructorInitializer>() : initializers, null, body);
@@ -306,7 +306,7 @@
     }
     return new HideCombinator.full(TokenFactory.token2("hide"), identifierList);
   }
-  static PrefixedIdentifier identifier(SimpleIdentifier prefix, SimpleIdentifier identifier2) => new PrefixedIdentifier.full(prefix, TokenFactory.token3(TokenType.PERIOD), identifier2);
+  static PrefixedIdentifier identifier(SimpleIdentifier prefix, SimpleIdentifier identifier) => new PrefixedIdentifier.full(prefix, TokenFactory.token3(TokenType.PERIOD), identifier);
   static SimpleIdentifier identifier3(String lexeme) => new SimpleIdentifier.full(TokenFactory.token4(TokenType.IDENTIFIER, lexeme));
   static PrefixedIdentifier identifier4(String prefix, SimpleIdentifier identifier) => new PrefixedIdentifier.full(identifier3(prefix), TokenFactory.token3(TokenType.PERIOD), identifier);
   static PrefixedIdentifier identifier5(String prefix, String identifier) => new PrefixedIdentifier.full(identifier3(prefix), TokenFactory.token3(TokenType.PERIOD), identifier3(identifier));
@@ -324,8 +324,8 @@
   static InterpolationExpression interpolationExpression2(String identifier) => new InterpolationExpression.full(TokenFactory.token3(TokenType.STRING_INTERPOLATION_IDENTIFIER), identifier3(identifier), null);
   static InterpolationString interpolationString(String contents, String value) => new InterpolationString.full(TokenFactory.token2(contents), value);
   static IsExpression isExpression(Expression expression, bool negated, TypeName type) => new IsExpression.full(expression, TokenFactory.token(Keyword.IS), negated ? TokenFactory.token3(TokenType.BANG) : null, type);
-  static Label label(SimpleIdentifier label2) => new Label.full(label2, TokenFactory.token3(TokenType.COLON));
-  static Label label2(String label22) => label(identifier3(label22));
+  static Label label(SimpleIdentifier label) => new Label.full(label, TokenFactory.token3(TokenType.COLON));
+  static Label label2(String label) => ASTFactory.label(identifier3(label));
   static LabeledStatement labeledStatement(List<Label> labels, Statement statement) => new LabeledStatement.full(labels, statement);
   static LibraryDirective libraryDirective(List<Annotation> metadata, LibraryIdentifier libraryName) => new LibraryDirective.full(null, metadata, TokenFactory.token(Keyword.LIBRARY), libraryName, TokenFactory.token3(TokenType.SEMICOLON));
   static LibraryDirective libraryDirective2(String libraryName) => libraryDirective(new List<Annotation>(), libraryIdentifier2([libraryName]));
@@ -374,7 +374,7 @@
   static RethrowExpression rethrowExpression() => new RethrowExpression.full(TokenFactory.token(Keyword.RETHROW));
   static ReturnStatement returnStatement() => returnStatement2(null);
   static ReturnStatement returnStatement2(Expression expression) => new ReturnStatement.full(TokenFactory.token(Keyword.RETURN), expression, TokenFactory.token3(TokenType.SEMICOLON));
-  static ScriptTag scriptTag(String scriptTag2) => new ScriptTag.full(TokenFactory.token2(scriptTag2));
+  static ScriptTag scriptTag(String scriptTag) => new ScriptTag.full(TokenFactory.token2(scriptTag));
   static ShowCombinator showCombinator(List<SimpleIdentifier> identifiers) => new ShowCombinator.full(TokenFactory.token2("show"), list(identifiers));
   static ShowCombinator showCombinator2(List<String> identifiers) {
     List<SimpleIdentifier> identifierList = new List<SimpleIdentifier>();
@@ -1420,7 +1420,7 @@
     assertSource("library l;", ASTFactory.compilationUnit3([ASTFactory.libraryDirective2("l")]));
   }
   void test_visitCompilationUnit_directive_declaration() {
-    assertSource("library l; var a;", ASTFactory.compilationUnit4(ASTFactory.list([(ASTFactory.libraryDirective2("l") as Directive)]), ASTFactory.list([(ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]) as CompilationUnitMember)])));
+    assertSource("library l; var a;", ASTFactory.compilationUnit4(ASTFactory.list([ASTFactory.libraryDirective2("l") as Directive]), ASTFactory.list([ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]) as CompilationUnitMember])));
   }
   void test_visitCompilationUnit_empty() {
     assertSource("", ASTFactory.compilationUnit());
@@ -1435,7 +1435,7 @@
     assertSource("!#/bin/dartvm library l;", ASTFactory.compilationUnit7("!#/bin/dartvm", [ASTFactory.libraryDirective2("l")]));
   }
   void test_visitCompilationUnit_script_directives_declarations() {
-    assertSource("!#/bin/dartvm library l; var a;", ASTFactory.compilationUnit8("!#/bin/dartvm", ASTFactory.list([(ASTFactory.libraryDirective2("l") as Directive)]), ASTFactory.list([(ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]) as CompilationUnitMember)])));
+    assertSource("!#/bin/dartvm library l; var a;", ASTFactory.compilationUnit8("!#/bin/dartvm", ASTFactory.list([ASTFactory.libraryDirective2("l") as Directive]), ASTFactory.list([ASTFactory.topLevelVariableDeclaration2(Keyword.VAR, [ASTFactory.variableDeclaration("a")]) as CompilationUnitMember])));
   }
   void test_visitConditionalExpression() {
     assertSource("a ? b : c", ASTFactory.conditionalExpression(ASTFactory.identifier3("a"), ASTFactory.identifier3("b"), ASTFactory.identifier3("c")));
@@ -1451,7 +1451,7 @@
   }
   void test_visitConstructorDeclaration_multipleInitializers() {
     assertSource("C() : a = b, c = d {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), ASTFactory.list([
-        (ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b")) as ConstructorInitializer),
+        ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b")) as ConstructorInitializer,
         ASTFactory.constructorFieldInitializer(false, "c", ASTFactory.identifier3("d"))]), ASTFactory.blockFunctionBody2([])));
   }
   void test_visitConstructorDeclaration_multipleParameters() {
@@ -1463,7 +1463,7 @@
     assertSource("C.m() {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), "m", ASTFactory.formalParameterList([]), null, ASTFactory.blockFunctionBody2([])));
   }
   void test_visitConstructorDeclaration_singleInitializer() {
-    assertSource("C() : a = b {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), ASTFactory.list([(ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b")) as ConstructorInitializer)]), ASTFactory.blockFunctionBody2([])));
+    assertSource("C() : a = b {}", ASTFactory.constructorDeclaration2(null, null, ASTFactory.identifier3("C"), null, ASTFactory.formalParameterList([]), ASTFactory.list([ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b")) as ConstructorInitializer]), ASTFactory.blockFunctionBody2([])));
   }
   void test_visitConstructorFieldInitializer_withoutThis() {
     assertSource("a = b", ASTFactory.constructorFieldInitializer(false, "a", ASTFactory.identifier3("b")));
@@ -1511,7 +1511,7 @@
     assertSource(";", ASTFactory.emptyStatement());
   }
   void test_visitExportDirective_combinator() {
-    assertSource("export 'a.dart' show A;", ASTFactory.exportDirective2("a.dart", [(ASTFactory.showCombinator([ASTFactory.identifier3("A")]) as Combinator)]));
+    assertSource("export 'a.dart' show A;", ASTFactory.exportDirective2("a.dart", [ASTFactory.showCombinator([ASTFactory.identifier3("A")]) as Combinator]));
   }
   void test_visitExportDirective_combinators() {
     assertSource("export 'a.dart' show A hide B;", ASTFactory.exportDirective2("a.dart", [
@@ -1630,7 +1630,7 @@
     assertSource("for (; c;) {}", ASTFactory.forStatement(null as Expression, ASTFactory.identifier3("c"), null, ASTFactory.block([])));
   }
   void test_visitForStatement_cu() {
-    assertSource("for (; c; u) {}", ASTFactory.forStatement(null as Expression, ASTFactory.identifier3("c"), ASTFactory.list([(ASTFactory.identifier3("u") as Expression)]), ASTFactory.block([])));
+    assertSource("for (; c; u) {}", ASTFactory.forStatement(null as Expression, ASTFactory.identifier3("c"), ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
   }
   void test_visitForStatement_e() {
     assertSource("for (e;;) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), null, null, ASTFactory.block([])));
@@ -1639,10 +1639,10 @@
     assertSource("for (e; c;) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), ASTFactory.identifier3("c"), null, ASTFactory.block([])));
   }
   void test_visitForStatement_ecu() {
-    assertSource("for (e; c; u) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), ASTFactory.identifier3("c"), ASTFactory.list([(ASTFactory.identifier3("u") as Expression)]), ASTFactory.block([])));
+    assertSource("for (e; c; u) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), ASTFactory.identifier3("c"), ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
   }
   void test_visitForStatement_eu() {
-    assertSource("for (e;; u) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), null, ASTFactory.list([(ASTFactory.identifier3("u") as Expression)]), ASTFactory.block([])));
+    assertSource("for (e;; u) {}", ASTFactory.forStatement(ASTFactory.identifier3("e"), null, ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
   }
   void test_visitForStatement_i() {
     assertSource("for (var i;;) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), null, null, ASTFactory.block([])));
@@ -1651,13 +1651,13 @@
     assertSource("for (var i; c;) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), ASTFactory.identifier3("c"), null, ASTFactory.block([])));
   }
   void test_visitForStatement_icu() {
-    assertSource("for (var i; c; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), ASTFactory.identifier3("c"), ASTFactory.list([(ASTFactory.identifier3("u") as Expression)]), ASTFactory.block([])));
+    assertSource("for (var i; c; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), ASTFactory.identifier3("c"), ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
   }
   void test_visitForStatement_iu() {
-    assertSource("for (var i;; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), null, ASTFactory.list([(ASTFactory.identifier3("u") as Expression)]), ASTFactory.block([])));
+    assertSource("for (var i;; u) {}", ASTFactory.forStatement2(ASTFactory.variableDeclarationList2(Keyword.VAR, [ASTFactory.variableDeclaration("i")]), null, ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
   }
   void test_visitForStatement_u() {
-    assertSource("for (;; u) {}", ASTFactory.forStatement(null as Expression, null, ASTFactory.list([(ASTFactory.identifier3("u") as Expression)]), ASTFactory.block([])));
+    assertSource("for (;; u) {}", ASTFactory.forStatement(null as Expression, null, ASTFactory.list([ASTFactory.identifier3("u") as Expression]), ASTFactory.block([])));
   }
   void test_visitFunctionDeclaration_getter() {
     assertSource("get f() {}", ASTFactory.functionDeclaration(null, Keyword.GET, "f", ASTFactory.functionExpression()));
diff --git a/pkg/analyzer_experimental/test/generated/element_test.dart b/pkg/analyzer_experimental/test/generated/element_test.dart
index d2571ca..954592e 100644
--- a/pkg/analyzer_experimental/test/generated/element_test.dart
+++ b/pkg/analyzer_experimental/test/generated/element_test.dart
@@ -1716,24 +1716,24 @@
     constructor.type = constructorType;
     return constructor;
   }
-  static ExportElementImpl exportFor(LibraryElement exportedLibrary2, List<NamespaceCombinator> combinators2) {
+  static ExportElementImpl exportFor(LibraryElement exportedLibrary, List<NamespaceCombinator> combinators) {
     ExportElementImpl spec = new ExportElementImpl();
-    spec.exportedLibrary = exportedLibrary2;
-    spec.combinators = combinators2;
+    spec.exportedLibrary = exportedLibrary;
+    spec.combinators = combinators;
     return spec;
   }
-  static FieldElementImpl fieldElement(String name, bool isStatic, bool isFinal, bool isConst, Type2 type2) {
+  static FieldElementImpl fieldElement(String name, bool isStatic, bool isFinal, bool isConst, Type2 type) {
     FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier3(name));
     field.const3 = isConst;
     field.final2 = isFinal;
     field.static = isStatic;
-    field.type = type2;
+    field.type = type;
     PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(field);
     getter.getter = true;
     getter.static = isStatic;
     getter.synthetic = true;
     getter.variable = field;
-    getter.returnType = type2;
+    getter.returnType = type;
     field.getter = getter;
     FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
     getter.type = getterType;
@@ -1743,7 +1743,7 @@
       setter.static = isStatic;
       setter.synthetic = true;
       setter.variable = field;
-      setter.parameters = <ParameterElement> [requiredParameter2("_${name}", type2)];
+      setter.parameters = <ParameterElement> [requiredParameter2("_${name}", type)];
       setter.returnType = VoidTypeImpl.instance;
       setter.type = new FunctionTypeImpl.con1(setter);
       field.setter = setter;
@@ -1822,26 +1822,26 @@
     }
     return _objectElement;
   }
-  static PropertyAccessorElementImpl getterElement(String name, bool isStatic, Type2 type2) {
+  static PropertyAccessorElementImpl getterElement(String name, bool isStatic, Type2 type) {
     FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier3(name));
     field.static = isStatic;
     field.synthetic = true;
-    field.type = type2;
+    field.type = type;
     PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(field);
     getter.getter = true;
     getter.static = isStatic;
     getter.variable = field;
-    getter.returnType = type2;
+    getter.returnType = type;
     field.getter = getter;
     FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
     getter.type = getterType;
     return getter;
   }
-  static ImportElementImpl importFor(LibraryElement importedLibrary2, PrefixElement prefix2, List<NamespaceCombinator> combinators2) {
+  static ImportElementImpl importFor(LibraryElement importedLibrary, PrefixElement prefix, List<NamespaceCombinator> combinators) {
     ImportElementImpl spec = new ImportElementImpl();
-    spec.importedLibrary = importedLibrary2;
-    spec.prefix = prefix2;
-    spec.combinators = combinators2;
+    spec.importedLibrary = importedLibrary;
+    spec.prefix = prefix;
+    spec.combinators = combinators;
     return spec;
   }
   static LibraryElementImpl library(AnalysisContext context, String libraryName) {
@@ -1855,7 +1855,7 @@
   }
   static LocalVariableElementImpl localVariableElement(Identifier name) => new LocalVariableElementImpl(name);
   static LocalVariableElementImpl localVariableElement2(String name) => new LocalVariableElementImpl(ASTFactory.identifier3(name));
-  static MethodElementImpl methodElement(String methodName, Type2 returnType2, List<Type2> argumentTypes) {
+  static MethodElementImpl methodElement(String methodName, Type2 returnType, List<Type2> argumentTypes) {
     MethodElementImpl method = new MethodElementImpl.con1(ASTFactory.identifier3(methodName));
     int count = argumentTypes.length;
     List<ParameterElement> parameters = new List<ParameterElement>(count);
@@ -1866,7 +1866,7 @@
       parameters[i] = parameter;
     }
     method.parameters = parameters;
-    method.returnType = returnType2;
+    method.returnType = returnType;
     FunctionTypeImpl methodType = new FunctionTypeImpl.con1(method);
     method.type = methodType;
     return method;
@@ -1876,10 +1876,10 @@
     parameter.parameterKind = ParameterKind.NAMED;
     return parameter;
   }
-  static ParameterElementImpl namedParameter2(String name, Type2 type2) {
+  static ParameterElementImpl namedParameter2(String name, Type2 type) {
     ParameterElementImpl parameter = new ParameterElementImpl.con1(ASTFactory.identifier3(name));
     parameter.parameterKind = ParameterKind.NAMED;
-    parameter.type = type2;
+    parameter.type = type;
     return parameter;
   }
   static ParameterElementImpl positionalParameter(String name) {
@@ -1887,10 +1887,10 @@
     parameter.parameterKind = ParameterKind.POSITIONAL;
     return parameter;
   }
-  static ParameterElementImpl positionalParameter2(String name, Type2 type2) {
+  static ParameterElementImpl positionalParameter2(String name, Type2 type) {
     ParameterElementImpl parameter = new ParameterElementImpl.con1(ASTFactory.identifier3(name));
     parameter.parameterKind = ParameterKind.POSITIONAL;
-    parameter.type = type2;
+    parameter.type = type;
     return parameter;
   }
   static PrefixElementImpl prefix(String name) => new PrefixElementImpl(ASTFactory.identifier3(name));
@@ -1899,26 +1899,26 @@
     parameter.parameterKind = ParameterKind.REQUIRED;
     return parameter;
   }
-  static ParameterElementImpl requiredParameter2(String name, Type2 type2) {
+  static ParameterElementImpl requiredParameter2(String name, Type2 type) {
     ParameterElementImpl parameter = new ParameterElementImpl.con1(ASTFactory.identifier3(name));
     parameter.parameterKind = ParameterKind.REQUIRED;
-    parameter.type = type2;
+    parameter.type = type;
     return parameter;
   }
-  static PropertyAccessorElementImpl setterElement(String name, bool isStatic, Type2 type2) {
+  static PropertyAccessorElementImpl setterElement(String name, bool isStatic, Type2 type) {
     FieldElementImpl field = new FieldElementImpl.con1(ASTFactory.identifier3(name));
     field.static = isStatic;
     field.synthetic = true;
-    field.type = type2;
+    field.type = type;
     PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(field);
     getter.getter = true;
     getter.static = isStatic;
     getter.variable = field;
-    getter.returnType = type2;
+    getter.returnType = type;
     field.getter = getter;
     FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
     getter.type = getterType;
-    ParameterElementImpl parameter = requiredParameter2("a", type2);
+    ParameterElementImpl parameter = requiredParameter2("a", type);
     PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(field);
     setter.setter = true;
     setter.static = isStatic;
@@ -1932,7 +1932,7 @@
   }
   static TopLevelVariableElementImpl topLevelVariableElement(Identifier name) => new TopLevelVariableElementImpl.con1(name);
   static TopLevelVariableElementImpl topLevelVariableElement2(String name) => new TopLevelVariableElementImpl.con2(name);
-  static TopLevelVariableElementImpl topLevelVariableElement3(String name, bool isFinal, Type2 type2) {
+  static TopLevelVariableElementImpl topLevelVariableElement3(String name, bool isFinal, Type2 type) {
     TopLevelVariableElementImpl variable = new TopLevelVariableElementImpl.con2(name);
     variable.final2 = isFinal;
     PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(variable);
@@ -1940,7 +1940,7 @@
     getter.static = true;
     getter.synthetic = true;
     getter.variable = variable;
-    getter.returnType = type2;
+    getter.returnType = type;
     variable.getter = getter;
     FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter);
     getter.type = getterType;
@@ -1950,7 +1950,7 @@
       setter.static = true;
       setter.synthetic = true;
       setter.variable = variable;
-      setter.parameters = <ParameterElement> [requiredParameter2("_${name}", type2)];
+      setter.parameters = <ParameterElement> [requiredParameter2("_${name}", type)];
       setter.returnType = VoidTypeImpl.instance;
       setter.type = new FunctionTypeImpl.con1(setter);
       variable.setter = setter;
diff --git a/pkg/analyzer_experimental/test/generated/resolver_test.dart b/pkg/analyzer_experimental/test/generated/resolver_test.dart
index 0e21d4b..6229a06 100644
--- a/pkg/analyzer_experimental/test/generated/resolver_test.dart
+++ b/pkg/analyzer_experimental/test/generated/resolver_test.dart
@@ -1290,6 +1290,16 @@
     assertNoErrors(source);
     verify([source]);
   }
+  void test_constructorDeclaration_scope_signature() {
+    Source source = addSource(EngineTestCase.createSource([
+        "const app = 0;",
+        "class A {",
+        "  A(@app int app) {}",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
   void test_constWithNonConstantArgument_literals() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
@@ -1533,6 +1543,30 @@
     assertNoErrors(source);
     verify([source]);
   }
+  void test_functionDeclaration_scope_returnType() {
+    Source source = addSource(EngineTestCase.createSource(["int f(int) {}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_functionDeclaration_scope_signature() {
+    Source source = addSource(EngineTestCase.createSource(["const app = 0;", "f(@app int app) {}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_functionTypeAlias_scope_returnType() {
+    Source source = addSource(EngineTestCase.createSource(["typedef int f(int);"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_functionTypeAlias_scope_signature() {
+    Source source = addSource(EngineTestCase.createSource(["const app = 0;", "typedef int f(@app int app);"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
   void test_implicitThisReferenceInInitializer_constructorName() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
@@ -1684,6 +1718,21 @@
     assertNoErrors(source);
     verify([source]);
   }
+  void test_importPrefixes_withFirstLetterDifference() {
+    Source source = addSource(EngineTestCase.createSource([
+        "library L;",
+        "import 'lib1.dart' as math;",
+        "import 'lib2.dart' as path;",
+        "main() {",
+        "  math.test1();",
+        "  path.test2();",
+        "}"]));
+    addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "test1() {}"]));
+    addSource2("/lib2.dart", EngineTestCase.createSource(["library lib2;", "test2() {}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
   void test_inconsistentCaseExpressionTypes() {
     Source source = addSource(EngineTestCase.createSource([
         "f(var p) {",
@@ -2204,6 +2253,16 @@
     assertNoErrors(source);
     verify([source]);
   }
+  void test_methodDeclaration_scope_signature() {
+    Source source = addSource(EngineTestCase.createSource([
+        "const app = 0;",
+        "class A {",
+        "  foo(@app int app) {}",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
   void test_misMatchedGetterAndSetterTypes_instance_sameTypes() {
     Source source = addSource(EngineTestCase.createSource([
         "class C {",
@@ -3452,6 +3511,10 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_constWithUndefinedConstructorDefault);
       });
+      _ut.test('test_constructorDeclaration_scope_signature', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_constructorDeclaration_scope_signature);
+      });
       _ut.test('test_defaultValueInFunctionTypeAlias', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_defaultValueInFunctionTypeAlias);
@@ -3560,6 +3623,22 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_finalNotInitialized_redirectingConstructor);
       });
+      _ut.test('test_functionDeclaration_scope_returnType', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_functionDeclaration_scope_returnType);
+      });
+      _ut.test('test_functionDeclaration_scope_signature', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_functionDeclaration_scope_signature);
+      });
+      _ut.test('test_functionTypeAlias_scope_returnType', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_functionTypeAlias_scope_returnType);
+      });
+      _ut.test('test_functionTypeAlias_scope_signature', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_functionTypeAlias_scope_signature);
+      });
       _ut.test('test_implicitThisReferenceInInitializer_constructorName', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_implicitThisReferenceInInitializer_constructorName);
@@ -3616,6 +3695,10 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_importOfNonLibrary_libraryNotDeclared);
       });
+      _ut.test('test_importPrefixes_withFirstLetterDifference', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_importPrefixes_withFirstLetterDifference);
+      });
       _ut.test('test_inconsistentCaseExpressionTypes', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_inconsistentCaseExpressionTypes);
@@ -3812,6 +3895,10 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_memberWithClassName_setter);
       });
+      _ut.test('test_methodDeclaration_scope_signature', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_methodDeclaration_scope_signature);
+      });
       _ut.test('test_misMatchedGetterAndSetterTypes_instance_sameTypes', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_misMatchedGetterAndSetterTypes_instance_sameTypes);
@@ -4906,6 +4993,18 @@
     resolve(source);
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
   }
+  void test_undefinedMethod_assignmentExpression() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {}",
+        "class B {",
+        "  f(A a) {",
+        "    A a2 = new A();",
+        "    a += a2;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+  }
   void test_undefinedMethod_ignoreTypePropagation() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {}",
@@ -4913,7 +5012,7 @@
         "  m() {}",
         "}",
         "class C {",
-        "f() {",
+        "  f() {",
         "    A a = new B();",
         "    a.m();",
         "  }",
@@ -4943,6 +5042,16 @@
     resolve(source);
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
   }
+  void test_undefinedOperator_postfixExpression() {
+    Source source = addSource(EngineTestCase.createSource(["class A {}", "f(A a) {", "  a++;", "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
+  void test_undefinedOperator_prefixExpression() {
+    Source source = addSource(EngineTestCase.createSource(["class A {}", "f(A a) {", "  ++a;", "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
   void test_undefinedSetter() {
     Source source = addSource(EngineTestCase.createSource(["class T {}", "f(T e1) { e1.m = 0; }"]));
     resolve(source);
@@ -5280,6 +5389,10 @@
         final __test = new StaticTypeWarningCodeTest();
         runJUnitTest(__test, __test.test_undefinedMethod);
       });
+      _ut.test('test_undefinedMethod_assignmentExpression', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_undefinedMethod_assignmentExpression);
+      });
       _ut.test('test_undefinedMethod_ignoreTypePropagation', () {
         final __test = new StaticTypeWarningCodeTest();
         runJUnitTest(__test, __test.test_undefinedMethod_ignoreTypePropagation);
@@ -5300,6 +5413,14 @@
         final __test = new StaticTypeWarningCodeTest();
         runJUnitTest(__test, __test.test_undefinedOperator_plus);
       });
+      _ut.test('test_undefinedOperator_postfixExpression', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_undefinedOperator_postfixExpression);
+      });
+      _ut.test('test_undefinedOperator_prefixExpression', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_undefinedOperator_prefixExpression);
+      });
       _ut.test('test_undefinedSetter', () {
         final __test = new StaticTypeWarningCodeTest();
         runJUnitTest(__test, __test.test_undefinedSetter);
@@ -5705,6 +5826,122 @@
     assertErrors(source, [HintCode.TYPE_CHECK_IS_NOT_NULL]);
     verify([source]);
   }
+  void test_undefinedGetter() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {}",
+        "f(var a) {",
+        "  if(a is A) {",
+        "    return a.m;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.UNDEFINED_GETTER]);
+  }
+  void test_undefinedGetter_message() {
+    JUnitTestCase.assertEquals(StaticTypeWarningCode.UNDEFINED_GETTER.message, StaticWarningCode.UNDEFINED_GETTER.message);
+  }
+  void test_undefinedMethod() {
+    Source source = addSource(EngineTestCase.createSource([
+        "f() {",
+        "  var a = 'str';",
+        "  a.notAMethodOnString();",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.UNDEFINED_METHOD]);
+  }
+  void test_undefinedMethod_assignmentExpression() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {}",
+        "class B {",
+        "  f(var a, var a2) {",
+        "    a = new A();",
+        "    a2 = new A();",
+        "    a += a2;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.UNDEFINED_METHOD]);
+  }
+  void test_undefinedOperator_indexBoth() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {}",
+        "f(var a) {",
+        "  if(a is A) {",
+        "    a[0]++;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.UNDEFINED_OPERATOR, HintCode.UNDEFINED_OPERATOR]);
+  }
+  void test_undefinedOperator_indexGetter() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {}",
+        "f(var a) {",
+        "  if(a is A) {",
+        "    a[0];",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+  }
+  void test_undefinedOperator_indexSetter() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {}",
+        "f(var a) {",
+        "  if(a is A) {",
+        "    a[0] = 1;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+  }
+  void test_undefinedOperator_plus() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {}",
+        "f(var a) {",
+        "  if(a is A) {",
+        "    a + 1;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+  }
+  void test_undefinedOperator_postfixExpression() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {}",
+        "f(var a) {",
+        "  if(a is A) {",
+        "    a++;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+  }
+  void test_undefinedOperator_prefixExpression() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {}",
+        "f(var a) {",
+        "  if(a is A) {",
+        "    ++a;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+  }
+  void test_undefinedSetter() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {}",
+        "f(var a) {",
+        "  if(a is A) {",
+        "    a.m = 0;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.UNDEFINED_SETTER]);
+  }
+  void test_undefinedSetter_message() {
+    JUnitTestCase.assertEquals(StaticTypeWarningCode.UNDEFINED_SETTER.message, StaticWarningCode.UNDEFINED_SETTER.message);
+  }
   void test_unnecessaryCast_type_supertype() {
     Source source = addSource(EngineTestCase.createSource(["m(int i) {", "  var b = i as Object;", "}"]));
     resolve(source);
@@ -5959,6 +6196,54 @@
         final __test = new HintCodeTest();
         runJUnitTest(__test, __test.test_typeCheck_type_not_Null);
       });
+      _ut.test('test_undefinedGetter', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_undefinedGetter);
+      });
+      _ut.test('test_undefinedGetter_message', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_undefinedGetter_message);
+      });
+      _ut.test('test_undefinedMethod', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_undefinedMethod);
+      });
+      _ut.test('test_undefinedMethod_assignmentExpression', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_undefinedMethod_assignmentExpression);
+      });
+      _ut.test('test_undefinedOperator_indexBoth', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_undefinedOperator_indexBoth);
+      });
+      _ut.test('test_undefinedOperator_indexGetter', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_undefinedOperator_indexGetter);
+      });
+      _ut.test('test_undefinedOperator_indexSetter', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_undefinedOperator_indexSetter);
+      });
+      _ut.test('test_undefinedOperator_plus', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_undefinedOperator_plus);
+      });
+      _ut.test('test_undefinedOperator_postfixExpression', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_undefinedOperator_postfixExpression);
+      });
+      _ut.test('test_undefinedOperator_prefixExpression', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_undefinedOperator_prefixExpression);
+      });
+      _ut.test('test_undefinedSetter', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_undefinedSetter);
+      });
+      _ut.test('test_undefinedSetter_message', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_undefinedSetter_message);
+      });
       _ut.test('test_unnecessaryCast_type_supertype', () {
         final __test = new HintCodeTest();
         runJUnitTest(__test, __test.test_unnecessaryCast_type_supertype);
@@ -6420,7 +6705,7 @@
    * @throws AssertionFailedError if any errors have been reported
    */
   void assertNoErrors(Source source) {
-    EngineTestCase.assertLength(0, analysisContext.computeErrors(source));
+    assertErrors(source, []);
   }
 
   /**
@@ -16466,16 +16751,16 @@
    * @param body the body of the function
    * @return a resolved function expression
    */
-  FunctionExpression resolvedFunctionExpression(FormalParameterList parameters2, FunctionBody body) {
+  FunctionExpression resolvedFunctionExpression(FormalParameterList parameters, FunctionBody body) {
     List<ParameterElement> parameterElements = new List<ParameterElement>();
-    for (FormalParameter parameter in parameters2.parameters) {
+    for (FormalParameter parameter in parameters.parameters) {
       ParameterElementImpl element = new ParameterElementImpl.con1(parameter.identifier);
       element.parameterKind = parameter.kind;
       element.type = _typeProvider.dynamicType;
       parameter.identifier.staticElement = element;
       parameterElements.add(element);
     }
-    FunctionExpression node = ASTFactory.functionExpression2(parameters2, body);
+    FunctionExpression node = ASTFactory.functionExpression2(parameters, body);
     FunctionElementImpl element = new FunctionElementImpl.con1(null);
     element.parameters = new List.from(parameterElements);
     element.type = new FunctionTypeImpl.con1(element);
@@ -16514,12 +16799,12 @@
    * @param variableName the name of the variable
    * @return a simple identifier that has been resolved to a variable element with the given type
    */
-  SimpleIdentifier resolvedVariable(InterfaceType type2, String variableName) {
+  SimpleIdentifier resolvedVariable(InterfaceType type, String variableName) {
     SimpleIdentifier identifier = ASTFactory.identifier3(variableName);
     VariableElementImpl element = ElementFactory.localVariableElement(identifier);
-    element.type = type2;
+    element.type = type;
     identifier.staticElement = element;
-    identifier.staticType = type2;
+    identifier.staticType = type;
     return identifier;
   }
 
@@ -16529,14 +16814,14 @@
    * @param parameter the parameter whose type is to be set
    * @param type the new type of the given parameter
    */
-  void setType(FormalParameter parameter, Type2 type2) {
+  void setType(FormalParameter parameter, Type2 type) {
     SimpleIdentifier identifier = parameter.identifier;
     Element element = identifier.staticElement;
     if (element is! ParameterElement) {
       element = new ParameterElementImpl.con1(identifier);
       identifier.staticElement = element;
     }
-    ((element as ParameterElementImpl)).type = type2;
+    ((element as ParameterElementImpl)).type = type;
   }
   static dartSuite() {
     _ut.group('StaticTypeAnalyzerTest', () {
@@ -17035,6 +17320,13 @@
     assertNoErrors(source);
     verify([source]);
   }
+  void test_unusedImport_annotationOnDirective() {
+    Source source = addSource(EngineTestCase.createSource(["library L;", "@A()", "import 'lib1.dart';"]));
+    Source source2 = addSource2("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  const A() {}", "}"]));
+    resolve(source);
+    assertErrors(source, []);
+    verify([source, source2]);
+  }
   void test_unusedImport_core_library() {
     Source source = addSource(EngineTestCase.createSource(["library L;", "import 'dart:core';"]));
     resolve(source);
@@ -17169,6 +17461,10 @@
         final __test = new NonHintCodeTest();
         runJUnitTest(__test, __test.test_unnecessaryCast_type_dynamic);
       });
+      _ut.test('test_unusedImport_annotationOnDirective', () {
+        final __test = new NonHintCodeTest();
+        runJUnitTest(__test, __test.test_unusedImport_annotationOnDirective);
+      });
       _ut.test('test_unusedImport_core_library', () {
         final __test = new NonHintCodeTest();
         runJUnitTest(__test, __test.test_unusedImport_core_library);
diff --git a/pkg/analyzer_experimental/test/generated/scanner_test.dart b/pkg/analyzer_experimental/test/generated/scanner_test.dart
index aa74c46..e709c47 100644
--- a/pkg/analyzer_experimental/test/generated/scanner_test.dart
+++ b/pkg/analyzer_experimental/test/generated/scanner_test.dart
@@ -2089,7 +2089,7 @@
   void assertError(ScannerErrorCode expectedError, int expectedOffset, String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
     scan(source, listener);
-    listener.assertErrors([new AnalysisError.con2(null, expectedOffset, 1, expectedError, [(source.codeUnitAt(expectedOffset) as int)])]);
+    listener.assertErrors([new AnalysisError.con2(null, expectedOffset, 1, expectedError, [source.codeUnitAt(expectedOffset) as int])]);
   }
 
   /**
diff --git a/pkg/analyzer_experimental/test/generated/test_support.dart b/pkg/analyzer_experimental/test/generated/test_support.dart
index d0977be..90af45a 100644
--- a/pkg/analyzer_experimental/test/generated/test_support.dart
+++ b/pkg/analyzer_experimental/test/generated/test_support.dart
@@ -232,9 +232,9 @@
    * @param errorCode the error code being searched for
    * @return `true` if an error with the given error code has been gathered
    */
-  bool hasError(ErrorCode errorCode2) {
+  bool hasError(ErrorCode errorCode) {
     for (AnalysisError error in errors) {
-      if (identical(error.errorCode, errorCode2)) {
+      if (identical(error.errorCode, errorCode)) {
         return true;
       }
     }
diff --git a/pkg/analyzer_experimental/test/services/formatter_test.dart b/pkg/analyzer_experimental/test/services/formatter_test.dart
index 51187f3..c2e1f18 100644
--- a/pkg/analyzer_experimental/test/services/formatter_test.dart
+++ b/pkg/analyzer_experimental/test/services/formatter_test.dart
@@ -598,7 +598,8 @@
           '}\n',
           'class A {\n'
           '  int _a;\n'
-          '  A(a) : _a = a;\n'
+          '  A(a)\n'
+          '      : _a = a;\n'
           '}\n'
         );
     });
@@ -622,6 +623,20 @@
         'part of foo;\n'
       );
     });
+    
+    test('CU (cons inits)', () {
+      expectCUFormatsTo('class X {\n'
+          '  var x, y;\n'
+          '  X() : x = 1, y = 2;\n'
+          '}\n', 
+          'class X {\n'
+          '  var x, y;\n'
+          '  X()\n'
+          '      : x = 1,\n' 
+          '        y = 2;\n'
+          '}\n'
+      );
+    });
 
     test('stmt', () {
       expectStmtFormatsTo(
@@ -763,6 +778,21 @@
         '}'
       );
     });
+    
+    test('Statement (if)', () {
+      expectStmtFormatsTo('if (true) print("true!");', 
+                          'if (true) print("true!");');
+      expectStmtFormatsTo('if (true) { print("true!"); }', 
+                          'if (true) {\n'
+                          '  print("true!");\n'
+                          '}');
+      expectStmtFormatsTo('if (true) print("true!"); else print("false!");', 
+                          'if (true) {\n'
+                          '  print("true!");\n'
+                          '} else {\n'
+                          '  print("false!");\n'
+                          '}');
+    }); 
 
     test('initialIndent', () {
       var formatter = new CodeFormatter(
diff --git a/pkg/browser/lib/interop.js b/pkg/browser/lib/interop.js
index 40e1700..8577e4f 100644
--- a/pkg/browser/lib/interop.js
+++ b/pkg/browser/lib/interop.js
@@ -224,7 +224,9 @@
 (function() {
   // Proxy support for js.dart.
 
-  var globalContext = window;
+  // We don't use 'window' because we might be in a web worker, but we don't
+  // use 'self' because not all browsers support it
+  var globalContext = function() { return this; }();
 
   // Table for local objects and functions that are proxied.
   function ProxiedObjectTable() {
diff --git a/pkg/custom_element/lib/custom-elements.debug.js b/pkg/custom_element/lib/custom-elements.debug.js
index 843e8a7..a391b8a 100644
--- a/pkg/custom_element/lib/custom-elements.debug.js
+++ b/pkg/custom_element/lib/custom-elements.debug.js
@@ -1207,8 +1207,8 @@
       changeAttribute.call(this, name, value, setAttribute);
     }
     var removeAttribute = prototype.removeAttribute;
-    prototype.removeAttribute = function(name, value) {
-      changeAttribute.call(this, name, value, removeAttribute);
+    prototype.removeAttribute = function(name) {
+      changeAttribute.call(this, name, null, removeAttribute);
     }
   }
 
@@ -1217,7 +1217,7 @@
     operation.apply(this, arguments);
     if (this.attributeChangedCallback
         && (this.getAttribute(name) !== oldValue)) {
-      this.attributeChangedCallback(name, oldValue);
+      this.attributeChangedCallback(name, oldValue, value);
     }
   }
 
diff --git a/pkg/custom_element/lib/custom-elements.min.js b/pkg/custom_element/lib/custom-elements.min.js
index fdec66a..8ecb7a4 100644
--- a/pkg/custom_element/lib/custom-elements.min.js
+++ b/pkg/custom_element/lib/custom-elements.min.js
@@ -25,4 +25,4 @@
 // 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=Date.now()%1e9;SideTable=function(){this.name="__st"+(1e9*Math.random()>>>0)+(b++ +"__")},SideTable.prototype={set:function(b,c){var d=b[this.name];d&&d[0]===b?d[1]=c:a(b,this.name,{value:[b,c],writable:!0})},get:function(a){var b;return(b=a[this.name])&&b[0]===a?b[1]: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.shadowRoot;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):(l(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 y.dom&&console.group("upgrade:",b.localName),a.upgrade(b),y.dom&&console.groupEnd(),!0}}function i(a){l(a),p(a)&&d(a,function(a){l(a)})}function j(a){if(B.push(a),!A){A=!0;var b=window.Platform&&window.Platform.endOfMicrotask||setTimeout;b(k)}}function k(){A=!1;for(var a,b=B,c=0,d=b.length;d>c&&(a=b[c]);c++)a();B=[]}function l(a){z?j(function(){m(a)}):m(a)}function m(a){(a.enteredViewCallback||a.__upgraded__&&y.dom)&&(y.dom&&console.group("inserted:",a.localName),p(a)&&(a.__inserted=(a.__inserted||0)+1,a.__inserted<1&&(a.__inserted=1),a.__inserted>1?y.dom&&console.warn("inserted:",a.localName,"insert/remove count:",a.__inserted):a.enteredViewCallback&&(y.dom&&console.log("inserted:",a.localName),a.enteredViewCallback())),y.dom&&console.groupEnd())}function n(a){o(a),d(a,function(a){o(a)})}function o(a){z?j(function(){_removed(a)}):_removed(a)}function o(a){(a.leftViewCallback||a.__upgraded__&&y.dom)&&(y.dom&&console.log("removed:",a.localName),p(a)||(a.__inserted=(a.__inserted||0)-1,a.__inserted>0&&(a.__inserted=0),a.__inserted<0?y.dom&&console.warn("removed:",a.localName,"insert/remove count:",a.__inserted):a.leftViewCallback&&a.leftViewCallback()))}function p(a){for(var b=a,c=window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(document)||document;b;){if(b==c)return!0;b=b.parentNode||b.host}}function q(a){if(a.shadowRoot&&!a.shadowRoot.__watched){y.dom&&console.log("watching shadow-root for: ",a.localName);for(var b=a.shadowRoot;b;)r(b),b=b.olderShadowRoot}}function r(a){a.__watched||(v(a),a.__watched=!0)}function s(a){switch(a.localName){case"style":case"script":case"template":case void 0:return!0}}function t(a){if(y.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&&(D(a.addedNodes,function(a){s(a)||g(a)}),D(a.removedNodes,function(a){s(a)||n(a)}))}),y.dom&&console.groupEnd()}function u(){t(C.takeRecords()),k()}function v(a){C.observe(a,{childList:!0,subtree:!0})}function w(a){v(a)}function x(a){y.dom&&console.group("upgradeDocument: ",(a.URL||a._URL||"").split("/").pop()),g(a),y.dom&&console.groupEnd()}var y=window.logFlags||{},z=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;a.hasPolyfillMutations=z;var A=!1,B=[],C=new MutationObserver(t),D=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.watchShadow=q,a.upgradeAll=g,a.upgradeSubtree=f,a.observeDocument=w,a.upgradeDocument=x,a.takeRecords=u}(window.CustomElements),function(a){function b(b,f){var g=f||{};if(!b)throw new Error("document.register: first argument `name` must not be empty");if(b.indexOf("-")<0)throw new Error("document.register: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(b)+"'.");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];if(c){if(a==c.tag&&b==c.is)return new c.ctor;if(!b&&!c.is)return new c.ctor}if(b){var d=o(a);return d.setAttribute("is",b),d}var d=w(a);return a.indexOf("-")>=0&&h(d,HTMLElement),d}function p(a){if(!a.__upgraded__&&a.nodeType===Node.ELEMENT_NODE){var b=a.getAttribute("is"),c=v[b||a.localName];if(c){if(b&&c.tag==a.localName)return g(a,c);if(!b&&!c.extends)return 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.register),t=!r.register&&s;if(t){var u=function(){};a.registry={},a.upgradeElement=u,a.watchShadow=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(){CustomElements.parser.parse(document),CustomElements.upgradeDocument(document);var a=window.Platform&&Platform.endOfMicrotask?Platform.endOfMicrotask:setTimeout;a(function(){CustomElements.ready=!0,CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.body.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!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":"loading"==document.readyState?"DOMContentLoaded":"load";window.addEventListener(b,a)}}(),function(){if(HTMLElement.prototype.createShadowRoot){var a=HTMLElement.prototype.createShadowRoot;HTMLElement.prototype.createShadowRoot=function(){var b=a.call(this);return b.host=this,b}}}();
+window.CustomElements={flags:{}};var SideTable;if("undefined"!=typeof WeakMap&&navigator.userAgent.indexOf("Firefox/")<0?SideTable=WeakMap:function(){var a=Object.defineProperty,b=Date.now()%1e9;SideTable=function(){this.name="__st"+(1e9*Math.random()>>>0)+(b++ +"__")},SideTable.prototype={set:function(b,c){var d=b[this.name];d&&d[0]===b?d[1]=c:a(b,this.name,{value:[b,c],writable:!0})},get:function(a){var b;return(b=a[this.name])&&b[0]===a?b[1]: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.shadowRoot;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):(l(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 y.dom&&console.group("upgrade:",b.localName),a.upgrade(b),y.dom&&console.groupEnd(),!0}}function i(a){l(a),p(a)&&d(a,function(a){l(a)})}function j(a){if(B.push(a),!A){A=!0;var b=window.Platform&&window.Platform.endOfMicrotask||setTimeout;b(k)}}function k(){A=!1;for(var a,b=B,c=0,d=b.length;d>c&&(a=b[c]);c++)a();B=[]}function l(a){z?j(function(){m(a)}):m(a)}function m(a){(a.enteredViewCallback||a.__upgraded__&&y.dom)&&(y.dom&&console.group("inserted:",a.localName),p(a)&&(a.__inserted=(a.__inserted||0)+1,a.__inserted<1&&(a.__inserted=1),a.__inserted>1?y.dom&&console.warn("inserted:",a.localName,"insert/remove count:",a.__inserted):a.enteredViewCallback&&(y.dom&&console.log("inserted:",a.localName),a.enteredViewCallback())),y.dom&&console.groupEnd())}function n(a){o(a),d(a,function(a){o(a)})}function o(a){z?j(function(){_removed(a)}):_removed(a)}function o(a){(a.leftViewCallback||a.__upgraded__&&y.dom)&&(y.dom&&console.log("removed:",a.localName),p(a)||(a.__inserted=(a.__inserted||0)-1,a.__inserted>0&&(a.__inserted=0),a.__inserted<0?y.dom&&console.warn("removed:",a.localName,"insert/remove count:",a.__inserted):a.leftViewCallback&&a.leftViewCallback()))}function p(a){for(var b=a,c=window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(document)||document;b;){if(b==c)return!0;b=b.parentNode||b.host}}function q(a){if(a.shadowRoot&&!a.shadowRoot.__watched){y.dom&&console.log("watching shadow-root for: ",a.localName);for(var b=a.shadowRoot;b;)r(b),b=b.olderShadowRoot}}function r(a){a.__watched||(v(a),a.__watched=!0)}function s(a){switch(a.localName){case"style":case"script":case"template":case void 0:return!0}}function t(a){if(y.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&&(D(a.addedNodes,function(a){s(a)||g(a)}),D(a.removedNodes,function(a){s(a)||n(a)}))}),y.dom&&console.groupEnd()}function u(){t(C.takeRecords()),k()}function v(a){C.observe(a,{childList:!0,subtree:!0})}function w(a){v(a)}function x(a){y.dom&&console.group("upgradeDocument: ",(a.URL||a._URL||"").split("/").pop()),g(a),y.dom&&console.groupEnd()}var y=window.logFlags||{},z=!window.MutationObserver||window.MutationObserver===window.JsMutationObserver;a.hasPolyfillMutations=z;var A=!1,B=[],C=new MutationObserver(t),D=Array.prototype.forEach.call.bind(Array.prototype.forEach);a.watchShadow=q,a.upgradeAll=g,a.upgradeSubtree=f,a.observeDocument=w,a.upgradeDocument=x,a.takeRecords=u}(window.CustomElements),function(a){function b(b,f){var g=f||{};if(!b)throw new Error("document.register: first argument `name` must not be empty");if(b.indexOf("-")<0)throw new Error("document.register: first argument ('name') must contain a dash ('-'). Argument provided was '"+String(b)+"'.");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){l.call(this,a,null,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,b)}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];if(c){if(a==c.tag&&b==c.is)return new c.ctor;if(!b&&!c.is)return new c.ctor}if(b){var d=o(a);return d.setAttribute("is",b),d}var d=w(a);return a.indexOf("-")>=0&&h(d,HTMLElement),d}function p(a){if(!a.__upgraded__&&a.nodeType===Node.ELEMENT_NODE){var b=a.getAttribute("is"),c=v[b||a.localName];if(c){if(b&&c.tag==a.localName)return g(a,c);if(!b&&!c.extends)return 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.register),t=!r.register&&s;if(t){var u=function(){};a.registry={},a.upgradeElement=u,a.watchShadow=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(){CustomElements.parser.parse(document),CustomElements.upgradeDocument(document);var a=window.Platform&&Platform.endOfMicrotask?Platform.endOfMicrotask:setTimeout;a(function(){CustomElements.ready=!0,CustomElements.readyTime=Date.now(),window.HTMLImports&&(CustomElements.elapsed=CustomElements.readyTime-HTMLImports.readyTime),document.body.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!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":"loading"==document.readyState?"DOMContentLoaded":"load";window.addEventListener(b,a)}}(),function(){if(HTMLElement.prototype.createShadowRoot){var a=HTMLElement.prototype.createShadowRoot;HTMLElement.prototype.createShadowRoot=function(){var b=a.call(this);return b.host=this,b}}}();
diff --git a/pkg/custom_element/lib/custom_element.dart b/pkg/custom_element/lib/custom_element.dart
index 98bef74..19824cf 100644
--- a/pkg/custom_element/lib/custom_element.dart
+++ b/pkg/custom_element/lib/custom_element.dart
@@ -23,6 +23,8 @@
 import 'package:meta/meta.dart';
 import 'src/custom_tag_name.dart';
 
+part 'src/attribute_map.dart';
+
 // TODO(jmesserly): replace with a real custom element polyfill.
 // This is just something temporary.
 /**
@@ -115,6 +117,7 @@
   /** The web component element wrapped by this class. */
   Element _host;
   List _shadowRoots;
+  _AttributeMap _attributes;
 
   /**
    * Shadow roots generated by dwc for each custom element, indexed by the
@@ -171,6 +174,9 @@
    * Note that [root] will be a [ShadowRoot] if the browser supports Shadow DOM.
    */
   void created() {}
+  // Added for analyzer warnings
+  @deprecated
+  void createdCallback() {}
 
   /** Invoked when this component gets inserted in the DOM tree. */
   void inserted() {}
@@ -182,10 +188,8 @@
   @deprecated
   void leftView() {}
 
-  // TODO(jmesserly): how do we implement this efficiently?
-  // See https://github.com/dart-lang/web-ui/issues/37
   /** Invoked when any attribute of the component is modified. */
-  void attributeChanged(String name, String oldValue, String newValue) {}
+  void attributeChanged(String name, String oldValue) {}
 
   get model => host.model;
 
@@ -272,9 +276,12 @@
   Node insertAllBefore(Iterable<Node> newChild, Node refChild) =>
     host.insertAllBefore(newChild, refChild);
 
-  Map<String, String> get attributes => host.attributes;
+  Map<String, String> get attributes {
+    if (_attributes == null) _attributes = new _AttributeMap(this);
+    return _attributes;
+  }
   set attributes(Map<String, String> value) {
-    host.attributes = value;
+    (attributes as _AttributeMap)._replaceAll(value);
   }
 
   List<Element> get elements => host.children;
@@ -316,10 +323,7 @@
 
   String get nodeValue => host.nodeValue;
 
-  @deprecated
-  // TODO(sigmund): restore the old return type and call host.on when
-  // dartbug.com/8131 is fixed.
-  dynamic get on { throw new UnsupportedError('on is deprecated'); }
+  Events get on => host.on;
 
   String get contentEditable => host.contentEditable;
   set contentEditable(String v) { host.contentEditable = v; }
diff --git a/pkg/custom_element/lib/src/attribute_map.dart b/pkg/custom_element/lib/src/attribute_map.dart
new file mode 100644
index 0000000..8af62c3
--- /dev/null
+++ b/pkg/custom_element/lib/src/attribute_map.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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 custom_element;
+
+/**
+ * Represents an attribute map of model values. If any items are added,
+ * removed, or replaced, then observers that are listening to [changes]
+ * will be notified.
+ */
+class _AttributeMap implements Map<String, String> {
+  final CustomElement _element;
+  final Map<String, String> _map;
+
+  /** Creates an attribute map wrapping the host attributes. */
+  _AttributeMap(CustomElement element)
+      : _element = element, _map = element.host.attributes;
+
+  // Forward all read methods:
+  Iterable<String> get keys => _map.keys;
+  Iterable<String> get values => _map.values;
+  int get length =>_map.length;
+  bool get isEmpty => _map.isEmpty;
+  bool get isNotEmpty => _map.isNotEmpty;
+  bool containsValue(Object value) => _map.containsValue(value);
+  bool containsKey(Object key) => _map.containsKey(key);
+  String operator [](Object key) => _map[key];
+  void forEach(void f(String key, String value)) => _map.forEach(f);
+  String toString() => _map.toString();
+
+  // Override the write methods and ensure attributeChanged is called:
+  void operator []=(String key, String value) {
+    int len = _map.length;
+    String oldValue = _map[key];
+    _map[key] = value;
+    if (len != _map.length || !identical(oldValue, value)) {
+      _element.attributeChanged(key, oldValue);
+    }
+  }
+
+  void addAll(Map<String, String> other) {
+    other.forEach((String key, String value) { this[key] = value; });
+  }
+
+  String putIfAbsent(String key, String ifAbsent()) {
+    int len = _map.length;
+    String result = _map.putIfAbsent(key, ifAbsent);
+    if (len != _map.length) {
+      _element.attributeChanged(key, null);
+    }
+    return result;
+  }
+
+  String remove(Object key) {
+    int len = _map.length;
+    String result =  _map.remove(key);
+    if (len != _map.length) {
+      _element.attributeChanged(key, result);
+    }
+    return result;
+  }
+
+  void clear() {
+    int len = _map.length;
+    if (len > 0) {
+      _map.forEach((key, value) {
+        _element.attributeChanged(key, value);
+      });
+    }
+    _map.clear();
+  }
+
+  /**
+   * This is not a [Map] method. We use it to implement "set attributes", which
+   * is a global replace operation. Rather than [clear] followed by [addAll],
+   * we try to be a bit smarter.
+   */
+  void _replaceAll(Map<String, String> other) {
+    for (var key in keys) {
+      if (!other.containsKey(key)) remove(key);
+    }
+    addAll(other);
+  }
+}
diff --git a/pkg/docgen/test/single_library_test.dart b/pkg/docgen/test/single_library_test.dart
index 78c8a5d..dd4044e 100644
--- a/pkg/docgen/test/single_library_test.dart
+++ b/pkg/docgen/test/single_library_test.dart
@@ -10,7 +10,7 @@
 main() {
   group('Generate docs for', () {
     test('one simple file.', () {
-      var temporaryDir = new Directory('single_library').createTempSync();
+      var temporaryDir = Directory.createSystemTempSync('single_library_');
       var fileName = path.join(temporaryDir.path, 'temp.dart');
       var file = new File(fileName);
       file.writeAsStringSync('''
diff --git a/pkg/observe/lib/src/bind_property.dart b/pkg/observe/lib/src/bind_property.dart
index c8524e7..c35bfb9 100644
--- a/pkg/observe/lib/src/bind_property.dart
+++ b/pkg/observe/lib/src/bind_property.dart
@@ -13,7 +13,7 @@
  *
  *       MyModel() {
  *         ...
- *         _sub = bindProperty(_otherModel, const Symbol('value'),
+ *         _sub = onPropertyChange(_otherModel, const Symbol('value'),
  *             () => notifyProperty(this, const Symbol('prop'));
  *       }
  *
@@ -23,7 +23,8 @@
  *
  * See also [notifyProperty].
  */
-StreamSubscription bindProperty(Observable source, Symbol sourceName,
+// TODO(jmesserly): make this an instance method?
+StreamSubscription onPropertyChange(Observable source, Symbol sourceName,
     void callback()) {
   return source.changes.listen((records) {
     for (var record in records) {
diff --git a/pkg/observe/lib/src/observable.dart b/pkg/observe/lib/src/observable.dart
index d39f84a..c5c56ab 100644
--- a/pkg/observe/lib/src/observable.dart
+++ b/pkg/observe/lib/src/observable.dart
@@ -7,7 +7,7 @@
 /**
  * Use `@observable` to make a field automatically observable.
  */
-const Object observable = const _ObservableAnnotation();
+const ObservableProperty observable = const ObservableProperty();
 
 /**
  * Interface representing an observable object. This is used by data in
@@ -124,7 +124,7 @@
         if (field.isFinal || field.isStatic || field.isPrivate) continue;
 
         for (var meta in field.metadata) {
-          if (identical(observable, meta.reflectee)) {
+          if (meta.reflectee is ObservableProperty) {
             var name = field.simpleName;
             // Note: since this is a field, getting the value shouldn't execute
             // user code, so we don't need to worry about errors.
@@ -220,12 +220,16 @@
 
 
 /**
- * The type of the `@observable` annotation.
+ * An annotation that is used to make a property observable.
+ * Normally this is used via the [observable] constant, for example:
  *
- * Library private because you should be able to use the [observable] field
- * to get the one and only instance. We could make it public though, if anyone
- * needs it for some reason.
+ *     class Monster {
+ *       @observable int health;
+ *     }
+ *
+ * If needed, you can subclass this to create another annotation that will also
+ * be treated as observable.
  */
-class _ObservableAnnotation {
-  const _ObservableAnnotation();
+class ObservableProperty {
+  const ObservableProperty();
 }
diff --git a/pkg/observe/lib/transform.dart b/pkg/observe/lib/transform.dart
index 029a017..d1e8139 100644
--- a/pkg/observe/lib/transform.dart
+++ b/pkg/observe/lib/transform.dart
@@ -34,7 +34,8 @@
     // as much work as applying the transform. We rather have some false
     // positives here, and then generate no outputs when we apply this
     // transform.
-    return input.readAsString().then((c) => c.contains("@observable"));
+    return input.readAsString().then(
+      (c) => c.contains("@observable") || c.contains("@published"));
   }
 
   Future apply(Transform transform) {
@@ -102,8 +103,12 @@
 
 _getSpan(SourceFile file, ASTNode node) => file.span(node.offset, node.end);
 
-/** True if the node has the `@observable` annotation. */
-bool _hasObservable(AnnotatedNode node) => _hasAnnotation(node, 'observable');
+/** True if the node has the `@observable` or `@published` annotation. */
+// TODO(jmesserly): it is not good to be hard coding these. We should do a
+// resolve and do a proper ObservableProperty subtype check. However resolve
+// is very expensive in analyzer_experimental, so it isn't feasible yet.
+bool _hasObservable(AnnotatedNode node) =>
+    _hasAnnotation(node, 'observable') || _hasAnnotation(node, 'published');
 
 bool _hasAnnotation(AnnotatedNode node, String name) {
   // TODO(jmesserly): this isn't correct if the annotation has been imported
@@ -134,7 +139,7 @@
       declaresObservable = true;
     } else if (id.name == 'ChangeNotifierBase') {
       declaresObservable = true;
-    } else if (id.name != 'PolymerElement' && id.name != 'CustomElement'
+    } else if (id.name != 'HtmlElement' && id.name != 'CustomElement'
         && id.name != 'Object') {
       // TODO(sigmund): this is conservative, consider using type-resolution to
       // improve this check.
@@ -183,14 +188,13 @@
       }
       if (_hasObservable(member)) {
         if (!declaresObservable) {
-          logger.warning('Observable fields should be put in an observable'
-              ' objects. Please declare that this class extends from '
+          logger.warning('Observable fields should be put in an observable '
+              'objects. Please declare that this class extends from '
               'ObservableBase, includes ObservableMixin, or implements '
               'Observable.',
               _getSpan(file, member));
-
         }
-        _transformFields(member.fields, code, member.offset, member.end);
+        _transformFields(file, member, code, logger);
 
         var names = member.fields.variables.map((v) => v.name.name);
 
@@ -289,40 +293,89 @@
       _hasKeyword(fields.keyword, Keyword.FINAL);
 }
 
-void _transformFields(VariableDeclarationList fields, TextEditTransaction code,
-    int begin, int end) {
+void _transformFields(SourceFile file, FieldDeclaration member,
+    TextEditTransaction code, TransformLogger logger) {
 
+  final fields = member.fields;
   if (_isReadOnly(fields)) return;
 
-  var indent = guessIndent(code.original, begin);
-  var replace = new StringBuffer();
+  // Private fields aren't supported:
+  for (var field in fields.variables) {
+    final name = field.name.name;
+    if (Identifier.isPrivateName(name)) {
+      logger.warning('Cannot make private field $name observable.',
+          _getSpan(file, field));
+      return;
+    }
+  }
 
   // Unfortunately "var" doesn't work in all positions where type annotations
   // are allowed, such as "var get name". So we use "dynamic" instead.
   var type = 'dynamic';
   if (fields.type != null) {
     type = _getOriginalCode(code, fields.type);
+  } else if (_hasKeyword(fields.keyword, Keyword.VAR)) {
+    // Replace 'var' with 'dynamic'
+    code.edit(fields.keyword.offset, fields.keyword.end, type);
   }
 
-  for (var field in fields.variables) {
-    var initializer = '';
-    if (field.initializer != null) {
-      initializer = ' = ${_getOriginalCode(code, field.initializer)}';
-    }
+  // Note: the replacements here are a bit subtle. It needs to support multiple
+  // fields declared via the same @observable, as well as preserving newlines.
+  // (Preserving newlines is important because it allows the generated code to
+  // be debugged without needing a source map.)
+  //
+  // For example:
+  //
+  //     @observable
+  //     @otherMetaData
+  //         Foo
+  //             foo = 1, bar = 2,
+  //             baz;
+  //
+  // Will be transformed into something like:
+  //
+  //     @observable
+  //     @OtherMetaData()
+  //         Foo
+  //             get foo => __foo; Foo __foo = 1; set foo ...; ... bar ...
+  //             @observable @OtherMetaData() Foo get baz => __baz; Foo baz; ...
+  //
+  // Metadata is moved to the getter.
 
-    var name = field.name.name;
+  String metadata = '';
+  if (fields.variables.length > 1) {
+    metadata = member.metadata
+      .map((m) => _getOriginalCode(code, m))
+      .join(' ');
+  }
 
-    // TODO(jmesserly): should we generate this one one line, so source maps
-    // don't break?
-    if (replace.length > 0) replace.write('\n\n$indent');
-    replace.write('''
-$type __\$$name$initializer;
-$type get $name => __\$$name;
-set $name($type value) {
-  __\$$name = notifyPropertyChange(const Symbol('$name'), __\$$name, value);
+  for (int i = 0; i < fields.variables.length; i++) {
+    final field = fields.variables[i];
+    final name = field.name.name;
+
+    var beforeInit = 'get $name => __\$$name; $type __\$$name';
+
+    // The first field is expanded differently from subsequent fields, because
+    // we can reuse the metadata and type annotation.
+    if (i > 0) beforeInit = '$metadata $type $beforeInit';
+
+    code.edit(field.name.offset, field.name.end, beforeInit);
+
+    // Replace comma with semicolon
+    final end = _findFieldSeperator(field.endToken.next);
+    if (end.type == TokenType.COMMA) code.edit(end.offset, end.end, ';');
+
+    code.edit(end.end, end.end, ' set $name($type value) { '
+        '__\$$name = notifyPropertyChange(#$name, __\$$name, value); }');
+  }
 }
-'''.replaceAll('\n', '\n$indent'));
-  }
 
-  code.edit(begin, end, '$replace');
+Token _findFieldSeperator(Token token) {
+  while (token != null) {
+    if (token.type == TokenType.COMMA || token.type == TokenType.SEMICOLON) {
+      break;
+    }
+    token = token.next;
+  }
+  return token;
 }
diff --git a/pkg/observe/test/transform_test.dart b/pkg/observe/test/transform_test.dart
index 9a64fac..5a4b138 100644
--- a/pkg/observe/test/transform_test.dart
+++ b/pkg/observe/test/transform_test.dart
@@ -47,17 +47,24 @@
     _testInitializers('this.a, {this.b}', '(a, {b}) : __\$a = a, __\$b = b');
   });
 
-  group('test full text', () {
-    test('with changes', () {
-      return _transform(_sampleObservable('A', 'foo'))
-        .then((output) => expect(output, _sampleObservableOutput('A', 'foo')));
-    });
+  for (var annotation in ['observable', 'published']) {
+    group('@$annotation full text', () {
+      test('with changes', () {
+        return _transform(_sampleObservable(annotation)).then(
+            (out) => expect(out, _sampleObservableOutput(annotation)));
+      });
 
-    test('no changes', () {
-      var input = 'class A {/*@observable annotation to trigger transform */;}';
-      return _transform(input).then((output) => expect(output, input));
+      test('complex with changes', () {
+        return _transform(_complexObservable(annotation)).then(
+            (out) => expect(out, _complexObservableOutput(annotation)));
+      });
+
+      test('no changes', () {
+        var input = 'class A {/*@$annotation annotation to trigger transform */;}';
+        return _transform(input).then((output) => expect(output, input));
+      });
     });
-  });
+  }
 }
 
 _testClause(String clauses, String expected) {
@@ -121,37 +128,64 @@
   Asset get primaryInput => _asset;
 
   _MockTransform(this._asset);
-  Future<Asset> getInput(Asset id) {
+  Future<Asset> getInput(AssetId id) {
     if (id == primaryInput.id) return new Future.value(primaryInput);
-    fail();
+    fail('_MockTransform fail');
   }
 
   void addOutput(Asset output) {
     outs.add(output);
   }
+
+  readInput(id) => throw new UnimplementedError();
+  readInputAsString(id, {encoding}) => throw new UnimplementedError();
 }
 
-String _sampleObservable(String className, String fieldName) => '''
-library ${className}_$fieldName;
+String _sampleObservable(String annotation) => '''
+library A_foo;
 import 'package:observe/observe.dart';
 
-class $className extends ObservableBase {
-  @observable int $fieldName;
-  $className(this.$fieldName);
+class A extends ObservableBase {
+  @$annotation int foo;
+  A(this.foo);
 }
 ''';
 
-String _sampleObservableOutput(String className, String fieldName) => '''
-library ${className}_$fieldName;
-import 'package:observe/observe.dart';
+String _sampleObservableOutput(String annotation) =>
+    "library A_foo;\n"
+    "import 'package:observe/observe.dart';\n\n"
+    "class A extends ChangeNotifierBase {\n"
+    "  @$annotation int get foo => __\$foo; int __\$foo; "
+      "${_makeSetter('int', 'foo')}\n"
+    "  A(foo) : __\$foo = foo;\n"
+    "}\n";
 
-class $className extends ChangeNotifierBase {
-  int __\$$fieldName;
-  int get $fieldName => __\$$fieldName;
-  set $fieldName(int value) {
-    __\$$fieldName = notifyPropertyChange(const Symbol('$fieldName'), __\$$fieldName, value);
-  }
-  
-  $className($fieldName) : __\$$fieldName = $fieldName;
+_makeSetter(type, name) => 'set $name($type value) { '
+    '__\$$name = notifyPropertyChange(#$name, __\$$name, value); }';
+
+String _complexObservable(String annotation) => '''
+class Foo extends ObservableBase {
+  @$annotation
+  @otherMetadata
+      Foo
+          foo/*D*/= 1, bar =/*A*/2/*B*/,
+          quux/*C*/;
+
+  @$annotation var baz;
 }
 ''';
+
+String _complexObservableOutput(String annotation) =>
+    "class Foo extends ChangeNotifierBase {\n"
+    "  @$annotation\n"
+    "  @otherMetadata\n"
+    "      Foo\n"
+    "          get foo => __\$foo; Foo __\$foo/*D*/= 1; "
+        "${_makeSetter('Foo', 'foo')} "
+        "@$annotation @otherMetadata Foo get bar => __\$bar; "
+        "Foo __\$bar =/*A*/2/*B*/; ${_makeSetter('Foo', 'bar')}\n"
+    "          @$annotation @otherMetadata Foo get quux => __\$quux; "
+        "Foo __\$quux/*C*/; ${_makeSetter('Foo', 'quux')}\n\n"
+    "  @$annotation dynamic get baz => __\$baz; dynamic __\$baz; "
+        "${_makeSetter('dynamic', 'baz')}\n"
+    "}\n";
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 9ff7d8d..d5c5205 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -57,24 +57,42 @@
 stack_trace/test/trace_test: Fail # http://dartbug.com/12380
 crypto/test/sha256_test: Pass, Fail # Issue 12502
 crypto/test/hmac_sha256_test: Pass, Fail # Issue 12502
-polymer/test/events_test: Fail # Issue 12865, 13197
+polymer/test/attr_deserialize_test: Fail # Issue 12865, 13197
+polymer/test/attr_mustache_test: Fail # Issue 12865, 13197
 polymer/test/event_path_test: Fail # Issue 12865, 13197
+polymer/test/events_test: Fail # Issue 12865, 13197
+polymer/test/prop_attr_reflection_test: Fail # Issue 12865, 13197
 
 [ $runtime == ie9 || $runtime == ie10 ]
-polymer/test/events_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/attr_deserialize_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/attr_mustache_test: Fail, Timeout # Issue 12865, 13197, 13260
 polymer/test/event_path_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/events_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/prop_attr_reflection_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/publish_attributes_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/take_attributes_test: Fail, Timeout # Issue 12865, 13197, 13260
 
 [ $system == windows && ($runtime == chrome || $runtime == ff) ]
-polymer/test/events_test: Pass, Timeout # Issue 13260
+polymer/test/attr_deserialize_test: Pass, Timeout # Issue 13260
+polymer/test/attr_mustache_test: Pass, Timeout # Issue 13260
 polymer/test/event_path_test: Pass, Timeout # Issue 13260
+polymer/test/events_test: Pass, Timeout # Issue 13260
+polymer/test/prop_attr_reflection_test: Pass, Timeout # Issue 13260
+polymer/test/publish_attributes_test: Pass, Timeout # Issue 13260
+polymer/test/take_attributes_test: Pass, Timeout # Issue 13260
 
 # Skip browser-specific tests on VM
 [ $runtime == vm ]
 path/test/browser_test: Fail, OK # Uses dart:html
 intl/test/find_default_locale_browser_test: Skip
 intl/test/date_time_format_http_request_test: Skip
-polymer/test/events_test: Fail, OK # Uses dart:html
+polymer/test/attr_deserialize_test: Fail, OK # Uses dart:html
+polymer/test/attr_mustache_test: Fail, OK # Uses dart:html
 polymer/test/event_path_test: Fail, OK # Uses dart:html
+polymer/test/events_test: Fail, OK # Uses dart:html
+polymer/test/prop_attr_reflection_test: Fail, OK # Uses dart:html
+polymer/test/publish_attributes_test: Fail, OK # Uses dart:html
+polymer/test/take_attributes_test: Fail, OK # Uses dart:html
 polymer/example: Fail, OK # Uses dart:html
 
 [ $runtime == vm && $system == windows ]
@@ -140,7 +158,6 @@
 observe/test/transform_test: Fail, OK # Uses dart:io.
 path/test/io_test: Fail, OK # Uses dart:io.
 polymer/test/build/*: Fail, OK # Uses dart:io.
-polymer/test/utils_test: Fail, OK # Uses dart:io.
 watcher/test/*: Fail, OK # Uses dart:io.
 
 scheduled_test/test/descriptor/async_test: Fail # http://dartbug.com/8440
@@ -182,17 +199,17 @@
 # not minified.
 unittest/test/*_minified_test: Skip # DO NOT COPY THIS UNLESS YOU WORK ON DART2JS
 
+[ $arch == mips ]
+*: Skip  # Issue 13650
+
 [ $arch == arm ]
-*: Skip
+*: Skip  # Issue 13624
 
 [ $arch == simarm ]
-*: Skip
+watcher/test/no_subscription_test: Pass, Fail  # Issue 13705.
 
-[ $arch == mips ]
-*: Skip
-
-[ $arch == simmips ]
-*: Skip
+[ $arch == simarm || $arch == simmips ]
+third_party/html5lib/test/tokenizer_test: Pass, Slow
 
 # Skip serialization test that explicitly has no library declaration in the
 # test on Dartium, which requires all tests to have a library.
diff --git a/pkg/polymer/example/component/news/web/news-component.html b/pkg/polymer/example/component/news/web/news-component.html
index 7f63f54..70254b8 100644
--- a/pkg/polymer/example/component/news/web/news-component.html
+++ b/pkg/polymer/example/component/news/web/news-component.html
@@ -31,7 +31,7 @@
 
     @initMethod
     _init() {
-      registerPolymerElement('x-news', () => new XNews());
+      Polymer.register('x-news', XNews);
     }
   </script>
 </polymer-element>
diff --git a/pkg/polymer/lib/boot.js b/pkg/polymer/lib/boot.js
index 0a3fe62..2bcb590 100644
--- a/pkg/polymer/lib/boot.js
+++ b/pkg/polymer/lib/boot.js
@@ -56,8 +56,30 @@
       ' tool to compile a depolyable JavaScript version')
     return;
   }
-  document.write(
-    '<script src="packages/html_import/html_import.min.js"></script>');
+
+
+  // Load HTML Imports:
+  var htmlImportsSrc = 'src="packages/html_import/html_import.min.js"';
+  document.write('<script ' + htmlImportsSrc + '></script>');
+  var importScript = document.querySelector('script[' + htmlImportsSrc + ']');
+  importScript.addEventListener('load', function() {
+    // NOTE: this is from polymer/src/lib/dom.js
+    window.HTMLImports.importer.preloadSelectors +=
+        ', polymer-element link[rel=stylesheet]';
+  });
+
+  // TODO(jmesserly): we need this in deploy tool too.
+  // NOTE: this is from polymer/src/boot.js:
+  // FOUC prevention tactic
+  var style = document.createElement('style');
+  style.textContent = 'body {opacity: 0;}';
+  var head = document.querySelector('head');
+  head.insertBefore(style, head.firstChild);
+
+  window.addEventListener('WebComponentsReady', function() {
+    document.body.style.webkitTransition = 'opacity 0.3s';
+    document.body.style.opacity = 1;
+  });
 
   // 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.
diff --git a/pkg/polymer/lib/component_build.dart b/pkg/polymer/lib/component_build.dart
index 6a923f0..cdd0820 100644
--- a/pkg/polymer/lib/component_build.dart
+++ b/pkg/polymer/lib/component_build.dart
@@ -6,6 +6,7 @@
 @deprecated
 library build_utils;
 
+import 'dart:async';
 import 'package:meta/meta.dart';
 
 import 'builder.dart' as builder;
@@ -18,5 +19,5 @@
 Future build(List<String> arguments, List<String> entryPoints,
     {bool printTime: true, bool shouldPrint: true}) {
   return builder.build(
-      entryPoints: entryPoints, options: parseOptions(arguments));
+      entryPoints: entryPoints, options: builder.parseOptions(arguments));
 }
diff --git a/pkg/polymer/lib/deserialize.dart b/pkg/polymer/lib/deserialize.dart
new file mode 100644
index 0000000..7f72c2c
--- /dev/null
+++ b/pkg/polymer/lib/deserialize.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library polymer.deserialize;
+
+import 'dart:convert' show JSON;
+import 'dart:mirrors' show reflect, TypeMirror;
+
+final _typeHandlers = () {
+  // TODO(jmesserly): switch to map and symbol literal form when supported.
+  var m = new Map();
+  m[const Symbol('dart.core.String')] = (x, _) => x;
+  m[const Symbol('dart.core.Null')] = (x, _) => x;
+  m[const Symbol('dart.core.DateTime')] = (x, _) {
+    // TODO(jmesserly): shouldn't need to try-catch here
+    // See: https://code.google.com/p/dart/issues/detail?id=1878
+    try {
+      return DateTime.parse(x);
+    } catch (e) {
+      return new DateTime.now();
+    }
+  };
+  m[const Symbol('dart.core.bool')] = (x, _) => x != 'false';
+  m[const Symbol('dart.core.int')] =
+      (x, def) => int.parse(x, onError: (_) => def);
+  m[const Symbol('dart.core.double')] =
+      (x, def) => double.parse(x, (_) => def);
+  return m;
+}();
+
+/**
+ * Convert representation of [value] based on type of [defaultValue].
+ */
+Object deserializeValue(String value, Object defaultValue, TypeMirror type) {
+  var handler = _typeHandlers[type.qualifiedName];
+  if (handler != null) return handler(value, defaultValue);
+
+  try {
+    // If the string is an object, we can parse is with the JSON library.
+    // include convenience replace for single-quotes. If the author omits
+    // quotes altogether, parse will fail.
+    return JSON.decode(value.replaceAll("'", '"'));
+
+    // TODO(jmesserly): deserialized JSON is not assignable to most objects in
+    // Dart. We should attempt to convert it appropriately.
+  } catch(e) {
+    // The object isn't valid JSON, return the raw value
+    return value;
+  }
+}
diff --git a/pkg/polymer/lib/job.dart b/pkg/polymer/lib/job.dart
new file mode 100644
index 0000000..677784a
--- /dev/null
+++ b/pkg/polymer/lib/job.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 polymer.job;
+
+import 'dart:async' show Timer;
+
+/**
+ * Invoke [callback] in [wait], unless the job is re-registered,
+ * which resets the timer. For example:
+ *
+ *     _myJob = runJob(_myJob, callback, const Duration(milliseconds: 100));
+ *
+ * Returns a job handle which can be used to re-register a job.
+ */
+// Dart note: renamed to runJob to avoid conflict with instance member "job".
+Job runJob(Job job, void callback(), Duration wait) {
+  if (job != null) {
+    job.stop();
+  } else {
+    job = new Job();
+  }
+  job.go(callback, wait);
+  return job;
+}
+
+// TODO(jmesserly): it isn't clear to me what is supposed to be public API here.
+// Or what name we should use. "Job" is awfully generic.
+// (The type itself is not exported in Polymer.)
+class Job {
+  Function _callback;
+  Timer _timer;
+
+  void go(void callback(), Duration wait) {
+    this._callback = callback;
+    _timer = new Timer(wait, complete);
+  }
+
+  void stop() {
+    if (_timer != null) {
+      _timer.cancel();
+      _timer = null;
+    }
+  }
+
+  void complete() {
+    if (_timer != null) {
+      stop();
+      _callback();
+    }
+  }
+}
diff --git a/pkg/polymer/lib/platform.dart b/pkg/polymer/lib/platform.dart
new file mode 100644
index 0000000..5dc5c3e
--- /dev/null
+++ b/pkg/polymer/lib/platform.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Exposes helper functionality for interacting with the platform. Similar to
+ * the [Platform] class from dart:html.
+ */
+// TODO(jmesserly): in Polymer this is a static class called "Platform", but
+// that conflicts with dart:html. What should we do? Does this functionality
+// belong in html's Platform instead?
+library polymer.platform;
+
+import 'dart:html' show Text, MutationObserver;
+import 'dart:collection' show Queue;
+import 'package:observe/src/microtask.dart' show performMicrotaskCheckpoint;
+
+void flush() {
+  endOfMicrotask(performMicrotaskCheckpoint);
+}
+
+int _iterations = 0;
+final Queue _callbacks = new Queue();
+final Text _twiddle = () {
+  var twiddle = new Text('');
+  new MutationObserver((x, y) {
+    while (_callbacks.isNotEmpty) {
+      try {
+        _callbacks.removeFirst()();
+      } catch (e) { // Dart note: fire the error async.
+        new Completer().completeError(e);
+      }
+    }
+  }).observe(twiddle, characterData: true);
+  return twiddle;
+}();
+
+void endOfMicrotask(void callback()) {
+  _twiddle.text = '${_iterations++}';
+  _callbacks.add(callback);
+}
diff --git a/pkg/polymer/lib/polymer.dart b/pkg/polymer/lib/polymer.dart
index e417fe5..a7ae73f 100644
--- a/pkg/polymer/lib/polymer.dart
+++ b/pkg/polymer/lib/polymer.dart
@@ -40,136 +40,31 @@
 library polymer;
 
 import 'dart:async';
+import 'dart:collection' show HashMap;
+import 'dart:html';
+import 'dart:js' as js;
 import 'dart:mirrors';
 
+import 'package:custom_element/custom_element.dart';
+import 'package:logging/logging.dart' show Logger, Level;
 import 'package:mdv/mdv.dart' as mdv;
+import 'package:mdv/mdv.dart' show NodeBinding;
+import 'package:meta/meta.dart' show deprecated;
+import 'package:observe/observe.dart';
 import 'package:observe/src/microtask.dart';
 import 'package:path/path.dart' as path;
-import 'polymer_element.dart' show registerPolymerElement;
+import 'package:polymer_expressions/polymer_expressions.dart'
+    show PolymerExpressions;
+
+import 'deserialize.dart' as deserialize;
+import 'job.dart';
+import 'platform.dart' as platform;
 
 export 'package:custom_element/custom_element.dart';
 export 'package:observe/observe.dart';
 export 'package:observe/html.dart';
 export 'package:observe/src/microtask.dart';
 
-export 'polymer_element.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();
-}
+part 'src/declaration.dart';
+part 'src/instance.dart';
+part 'src/loader.dart';
diff --git a/pkg/polymer/lib/polymer_element.dart b/pkg/polymer/lib/polymer_element.dart
index a7ade34..c004985 100644
--- a/pkg/polymer/lib/polymer_element.dart
+++ b/pkg/polymer/lib/polymer_element.dart
@@ -4,555 +4,4 @@
 
 library polymer.polymer_element;
 
-import 'dart:async';
-import 'dart:html';
-import 'dart:mirrors';
-import 'dart:js' as js;
-
-import 'package:custom_element/custom_element.dart';
-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.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;
-
-    var extendee = declaration.attributes['extends'];
-    if (extendee != null) {
-      // Skip normal tags, only initialize parent custom elements.
-      if (extendee.contains('-')) _initialize(extendee);
-    }
-
-    _parseHostEvents(declaration);
-    _parseLocalEvents(declaration);
-    _publishAttributes(declaration);
-
-    var templateContent = declaration.query('template').content;
-    _shimStyling(templateContent, localName);
-
-    _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.query('template');
-      if (templateNode == null) return;
-
-      // Create the contents of the element's ShadowRoot, and add them.
-      root.nodes.add(instanceTemplate(templateNode));
-    }
-  }
-
-  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 _shimStyling(DocumentFragment template, String localName) {
-    if (js.context == null) return;
-
-    var platform = js.context['Platform'];
-    if (platform == null) return;
-
-    var style = template.query('style');
-    if (style == 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 scopedCSS = shimShadowDOMStyling2.apply(shadowCss,
-        [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,
-};
+export 'polymer.dart' show PolymerElement, registerPolymerElement;
diff --git a/pkg/polymer/lib/src/build/linter.dart b/pkg/polymer/lib/src/build/linter.dart
index 3ed9c50..6542df7 100644
--- a/pkg/polymer/lib/src/build/linter.dart
+++ b/pkg/polymer/lib/src/build/linter.dart
@@ -16,8 +16,10 @@
 import 'package:barback/barback.dart';
 import 'package:html5lib/dom.dart';
 import 'package:html5lib/dom_parsing.dart';
+import 'package:source_maps/span.dart';
 
 import 'common.dart';
+import 'utils.dart';
 
 typedef String MessageFormatter(String kind, String message, Span span);
 
@@ -191,6 +193,9 @@
 /**
  * Information needed about other polymer-element tags in order to validate
  * how they are used and extended.
+ *
+ * Note: these are only created for polymer-element, because pure custom
+ * elements don't have a declarative form.
  */
 class _ElementSummary {
   final String tagName;
@@ -284,6 +289,19 @@
           node.sourceSpan);
     }
 
+    var attrs = node.attributes['attributes'];
+    if (attrs != null) {
+      var attrsSpan = node.attributeSpans['attributes'];
+
+      // names='a b c' or names='a,b,c'
+      // record each name for publishing
+      for (var attr in attrs.split(attrs.contains(',') ? ',' : ' ')) {
+        // remove excess ws
+        attr = attr.trim();
+        if (!_validateCustomAttributeName(attr, attrsSpan)) break;
+      }
+    }
+
     var oldValue = _inPolymerElement;
     _inPolymerElement = true;
     super.visitElement(node);
@@ -369,10 +387,13 @@
 
     var info = _elements[customTagName];
     if (info == null) {
-      _logger.warning('definition for custom element with tag name '
+      // TODO(jmesserly): this warning is wrong if someone is using raw custom
+      // elements. Is there another way we can handle this warning that won't
+      // generate false positives?
+      _logger.warning('definition for Polymer element with tag name '
           '"$customTagName" not found.', node.sourceSpan);
       return;
-    } 
+    }
 
     var baseTag = info.baseExtendsTag;
     if (baseTag != null && !hasIsAttribute) {
@@ -384,7 +405,7 @@
           'the custom element declaration.', node.sourceSpan);
       return;
     }
-    
+
     if (hasIsAttribute && baseTag == null) {
       _logger.warning(
           'custom element "$customTagName" doesn\'t declare any type '
@@ -393,7 +414,7 @@
           'the custom element declaration.', node.sourceSpan);
       return;
     }
-    
+
     if (hasIsAttribute && baseTag != nodeTag) {
       _logger.warning(
           'custom element "$customTagName" extends from "$baseTag". '
@@ -402,6 +423,20 @@
     }
   }
 
+  /**
+   * Validate an attribute on a custom-element. Returns true if valid.
+   */
+  bool _validateCustomAttributeName(String name, FileSpan span) {
+    if (name.contains('-')) {
+      var newName = toCamelCase(name);
+      _logger.warning('PolymerElement no longer recognizes attribute names with '
+          'dashes such as "$name". Use "$newName" or "${newName.toLowerCase()}" '
+          'instead (both forms are equivalent in HTML).', span);
+      return false;
+    }
+    return true;
+  }
+
   /** Validate event handlers are used correctly. */
   void _validateEventHandler(Element node, String name, String value) {
     if (!name.startsWith('on-')) {
@@ -409,20 +444,29 @@
           ' 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);
+          node.attributeSpans[name]);
       return;
     }
 
     if (!_inPolymerElement) {
       _logger.warning('Inline event handlers are only supported inside '
-          'declarations of <polymer-element>.', node.sourceSpan);
+          'declarations of <polymer-element>.', node.attributeSpans[name]);
+    }
+
+    var eventName = name.substring('on-'.length);
+    if (eventName.contains('-')) {
+      var newEvent = toCamelCase(eventName);
+      _logger.warning('Invalid event name "$name". After the "on-" the event '
+          'name should not use dashes. For example use "on-$newEvent" or '
+          '"on-${newEvent.toLowerCase()}" (both forms are equivalent in HTML).',
+          node.attributeSpans[name]);
     }
 
     if (value.contains('.') || value.contains('(')) {
       _logger.warning('Invalid event handler body "$value". Declare a method '
           'in your custom element "void handlerName(event, detail, target)" '
           'and use the form $name="handlerName".',
-          node.sourceSpan);
+          node.attributeSpans[name]);
     }
   }
 }
diff --git a/pkg/polymer/lib/src/build/runner.dart b/pkg/polymer/lib/src/build/runner.dart
index d940c18..3596e92 100644
--- a/pkg/polymer/lib/src/build/runner.dart
+++ b/pkg/polymer/lib/src/build/runner.dart
@@ -105,7 +105,7 @@
 final Set<String> _polymerPackageDependencies = [
     'analyzer_experimental', 'args', 'barback', 'browser', 'csslib',
     'custom_element', 'fancy_syntax', 'html5lib', 'html_import', 'js',
-    'logging', 'mdv', 'meta', 'mutation_observer', 'observe', 'path', 'polymer',
+    'logging', 'mdv', 'meta', 'mutation_observer', 'observe', 'path'
     'polymer_expressions', 'serialization', 'shadow_dom', 'source_maps',
     'stack_trace', 'unittest', 'unmodifiable_collection', 'yaml'].toSet();
 
@@ -149,7 +149,9 @@
   }
 
   for (var package in options.packageDirs.keys) {
-    // There is nothing to do in the 'polymer' package and its dependencies.
+    // There is nothing to do in the polymer package dependencies.
+    // However: in Polymer package *itself*, we need to replace ObservableMixin
+    // with ChangeNotifierMixin.
     if (!options.transformPolymerDependencies &&
         _polymerPackageDependencies.contains(package)) continue;
     barback.updateTransformers(package, options.phases);
diff --git a/pkg/polymer/lib/src/utils.dart b/pkg/polymer/lib/src/build/utils.dart
similarity index 100%
rename from pkg/polymer/lib/src/utils.dart
rename to pkg/polymer/lib/src/build/utils.dart
diff --git a/pkg/polymer/lib/src/declaration.dart b/pkg/polymer/lib/src/declaration.dart
new file mode 100644
index 0000000..a7584b6
--- /dev/null
+++ b/pkg/polymer/lib/src/declaration.dart
@@ -0,0 +1,713 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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 polymer;
+
+/**
+ * **Deprecated**: use [Polymer.register] instead.
+ *
+ * Registers a [PolymerElement]. This is similar to [registerCustomElement]
+ * but it is designed to work with the `<element>` element and adds additional
+ * features.
+ */
+@deprecated
+void registerPolymerElement(String localName, PolymerElement create()) {
+  Polymer._registerClassMirror(localName, reflect(create()).type);
+}
+
+/**
+ * **Warning**: this class is experiental and subject to change.
+ *
+ * The implementation for the `polymer-element` element.
+ *
+ * Normally you do not need to use this class directly, see [PolymerElement].
+ */
+class PolymerDeclaration extends CustomElement {
+  // Fully ported from revision:
+  // https://github.com/Polymer/polymer/blob/4dc481c11505991a7c43228d3797d28f21267779
+  //
+  //   src/declaration/attributes.js
+  //   src/declaration/events.js
+  //   src/declaration/polymer-element.js
+  //   src/declaration/properties.js
+  //   src/declaration/prototype.js (note: most code not needed in Dart)
+  //   src/declaration/styles.js
+  //
+  // Not yet ported:
+  //   src/declaration/path.js - blocked on HTMLImports.getDocumentUrl
+
+  // TODO(jmesserly): these should be Type not ClassMirror. But we can't get
+  // from ClassMirror to Type yet in dart2js, so we use ClassMirror for now.
+  // See https://code.google.com/p/dart/issues/detail?id=12607
+  ClassMirror _type;
+  ClassMirror get type => _type;
+
+  // TODO(jmesserly): this is a cache, because it's tricky in Dart to get from
+  // ClassMirror -> Supertype.
+  ClassMirror _supertype;
+  ClassMirror get supertype => _supertype;
+
+  // TODO(jmesserly): this is also a cache, since we can't store .element on
+  // each level of the __proto__ like JS does.
+  PolymerDeclaration _super;
+  PolymerDeclaration get superDeclaration => _super;
+
+  String _name;
+  String get name => _name;
+
+  /**
+   * Map of publish properties. Can be a [VariableMirror] or a [MethodMirror]
+   * representing a getter. If it is a getter, there will also be a setter.
+   */
+  Map<String, DeclarationMirror> _publish;
+
+  /** The names of published properties for this polymer-element. */
+  Iterable<String> get publishedProperties =>
+      _publish != null ? _publish.keys : const [];
+
+  /** Same as [_publish] but with lower case names. */
+  Map<String, DeclarationMirror> _publishLC;
+
+  Map<String, Symbol> _observe;
+
+  Map<Symbol, Object> _instanceAttributes;
+
+  List<Element> _sheets;
+  List<Element> get sheets => _sheets;
+
+  List<Element> _styles;
+  List<Element> get styles => _styles;
+
+  DocumentFragment get templateContent {
+    final template = query('template');
+    return template != null ? template.content : null;
+  }
+
+  /** Maps event names and their associated method in the element class. */
+  final Map<String, String> _eventDelegates = {};
+
+  /** 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?)
+  Expando<Set<String>> _templateDelegates;
+
+  void created() {
+    super.created();
+
+    // fetch the element name
+    _name = attributes['name'];
+    // install element definition, if ready
+    registerWhenReady();
+  }
+
+  void registerWhenReady() {
+    // if we have no prototype, wait
+    if (waitingForType(name)) {
+      return;
+    }
+    // fetch our extendee name
+    var extendee = attributes['extends'];
+    if (waitingForExtendee(extendee)) {
+      //console.warn(name + ': waitingForExtendee:' + extendee);
+      return;
+    }
+    // TODO(sjmiles): HTMLImports polyfill awareness:
+    // elements in the main document are likely to parse
+    // in advance of elements in imports because the
+    // polyfill parser is simulated
+    // therefore, wait for imports loaded before
+    // finalizing elements in the main document
+    // TODO(jmesserly): Polymer.dart waits for HTMLImportsLoaded, so I've
+    // removed "whenImportsLoaded" for now. Restore the workaround if needed.
+    _register(extendee);
+  }
+
+  void _register(extendee) {
+    //console.group('registering', name);
+    register(name, extendee);
+    //console.groupEnd();
+    // subclasses may now register themselves
+    _notifySuper(name);
+  }
+
+  bool waitingForType(String name) {
+    if (_getRegisteredType(name) != null) return false;
+
+    // then wait for a prototype
+    _waitType[name] = this;
+    // if explicitly marked as 'noscript'
+    if (attributes.containsKey('noscript')) {
+      // TODO(sorvell): CustomElements polyfill awareness:
+      // noscript elements should upgrade in logical order
+      // script injection ensures this under native custom elements;
+      // under imports + ce polyfills, scripts run before upgrades.
+      // dependencies should be ready at upgrade time so register
+      // prototype at this time.
+      // TODO(jmesserly): I'm not sure how to port this; since script
+      // injection doesn't work for Dart, we'll just call Polymer.register
+      // here and hope for the best.
+      Polymer.register(name);
+    }
+    return true;
+  }
+
+  bool waitingForExtendee(String extendee) {
+    // if extending a custom element...
+    if (extendee != null && extendee.indexOf('-') >= 0) {
+      // wait for the extendee to be _registered first
+      if (!_isRegistered(extendee)) {
+        _waitSuper.putIfAbsent(extendee, () => []).add(this);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void register(String name, String extendee) {
+    // build prototype combining extendee, Polymer base, and named api
+    buildType(name, extendee);
+
+    // back reference declaration element
+    // TODO(sjmiles): replace `element` with `elementElement` or `declaration`
+    _declarations[_type] = this;
+
+    // more declarative features
+    desugar();
+
+    // TODO(sorvell): install a helper method this.resolvePath to aid in
+    // setting resource paths. e.g.
+    // this.$.image.src = this.resolvePath('images/foo.png')
+    // Potentially remove when spec bug is addressed.
+    // https://www.w3.org/Bugs/Public/show_bug.cgi?id=21407
+    // TODO(jmesserly): resolvePath not ported, see first comment in this class.
+
+    // under ShadowDOMPolyfill, transforms to approximate missing CSS features
+    _shimShadowDomStyling(templateContent, name);
+
+    // register our custom element
+    registerType(name);
+
+    // NOTE: skip in Dart because we don't have mutable global scope.
+    // reference constructor in a global named by 'constructor' attribute
+    // publishConstructor();
+  }
+
+  /**
+   * Gets the Dart type registered for this name, and sets up declarative
+   * features. Fills in the [type] and [supertype] fields.
+   *
+   * *Note*: unlike the JavaScript version, we do not have to metaprogram the
+   * prototype, which simplifies this method.
+   */
+  void buildType(String name, String extendee) {
+    // get our custom type
+    _type = _getRegisteredType(name);
+
+    // get basal prototype
+    _supertype = _getRegisteredType(extendee);
+    if (supertype != null) _super = _getDeclaration(supertype);
+
+    // transcribe `attributes` declarations onto own prototype's `publish`
+    publishAttributes(type, _super);
+
+    publishProperties(type);
+
+    inferObservers(type);
+
+    // Skip the rest in Dart:
+    // chain various meta-data objects to inherited versions
+    // chain custom api to inherited
+    // build side-chained lists to optimize iterations
+    // inherit publishing meta-data
+    //this.inheritAttributesObjects(prototype);
+    //this.inheritDelegates(prototype);
+    // x-platform fixups
+  }
+
+  /** Implement various declarative features. */
+  void desugar() {
+    // compile list of attributes to copy to instances
+    accumulateInstanceAttributes();
+    // parse on-* delegates declared on `this` element
+    parseHostEvents();
+    // parse on-* delegates declared in templates
+    parseLocalEvents();
+    // install external stylesheets as if they are inline
+    installSheets();
+    // TODO(jmesserly): this feels unnatrual in Dart. Since we have convenient
+    // lazy static initialization, can we get by without it?
+    var registered = type.methods[const Symbol('registerCallback')];
+    if (registered != null && registered.isStatic &&
+        registered.isRegularMethod) {
+      type.invoke(const Symbol('registerCallback'), [this]);
+    }
+
+  }
+
+  void registerType(String name) {
+    // TODO(jmesserly): document.register
+    registerCustomElement(name, () =>
+        type.newInstance(const Symbol(''), const []).reflectee);
+  }
+
+  void publishAttributes(ClassMirror type, PolymerDeclaration superDecl) {
+    // get properties to publish
+    if (superDecl != null && superDecl._publish != null) {
+      _publish = new Map.from(superDecl._publish);
+    }
+    _publish = _getProperties(type, _publish, (x) => x is PublishedProperty);
+
+    // merge names from 'attributes' attribute
+    var attrs = attributes['attributes'];
+    if (attrs != null) {
+      // names='a b c' or names='a,b,c'
+      // record each name for publishing
+      for (var attr in attrs.split(attrs.contains(',') ? ',' : ' ')) {
+        // remove excess ws
+        attr = attr.trim();
+
+        // do not override explicit entries
+        if (_publish != null && _publish.containsKey(attr)) continue;
+
+        var property = new Symbol(attr);
+        var mirror = type.variables[property];
+        if (mirror == null) {
+          mirror = type.getters[property];
+          if (mirror != null && !_hasSetter(type, mirror)) mirror = null;
+        }
+        if (mirror == null) {
+          window.console.warn('property for attribute $attr of polymer-element '
+              'name=$name not found.');
+          continue;
+        }
+        if (_publish == null) _publish = {};
+        _publish[attr] = mirror;
+      }
+    }
+
+    // NOTE: the following is not possible in Dart; fields must be declared.
+    // install 'attributes' as properties on the prototype,
+    // but don't override
+  }
+
+  void accumulateInstanceAttributes() {
+    // inherit instance attributes
+    _instanceAttributes = new Map<Symbol, Object>();
+    if (_super != null) _instanceAttributes.addAll(_super._instanceAttributes);
+
+    // merge attributes from element
+    attributes.forEach((name, value) {
+      if (isInstanceAttribute(name)) {
+        _instanceAttributes[new Symbol(name)] = value;
+      }
+    });
+  }
+
+  static bool isInstanceAttribute(name) {
+    // do not clone these attributes onto instances
+    final blackList = const {
+        'name': 1, 'extends': 1, 'constructor': 1, 'noscript': 1,
+        'attributes': 1};
+
+    return !blackList.containsKey(name) && !name.startsWith('on-');
+  }
+
+  /** Extracts events from the element tag attributes. */
+  void parseHostEvents() {
+    addAttributeDelegates(_eventDelegates);
+  }
+
+  void addAttributeDelegates(Map<String, String> delegates) {
+    attributes.forEach((name, value) {
+      if (_hasEventPrefix(name)) {
+        delegates[_removeEventPrefix(name)] = value;
+      }
+    });
+  }
+
+  /** Extracts events under the element's <template>. */
+  void parseLocalEvents() {
+    for (var t in queryAll('template')) {
+      final events = new Set<String>();
+      // acquire delegates from entire subtree at t
+      accumulateTemplatedEvents(t, events);
+      if (events.isNotEmpty) {
+        // store delegate information directly on template
+        if (_templateDelegates == null) {
+          _templateDelegates = new Expando<Set<String>>();
+        }
+        _templateDelegates[t] = events;
+      }
+    }
+  }
+
+  void accumulateTemplatedEvents(Element node, Set<String> events) {
+    if (node.localName == 'template' && node.content != null) {
+      accumulateChildEvents(node.content, events);
+    }
+  }
+
+  void accumulateChildEvents(node, Set<String> events) {
+    assert(node is Element || node is DocumentFragment);
+    for (var n in node.children) {
+      accumulateEvents(n, events);
+    }
+  }
+
+  void accumulateEvents(Element node, Set<String> events) {
+    accumulateAttributeEvents(node, events);
+    accumulateChildEvents(node, events);
+    accumulateTemplatedEvents(node, events);
+  }
+
+  void accumulateAttributeEvents(Element node, Set<String> events) {
+    for (var name in node.attributes.keys) {
+      if (_hasEventPrefix(name)) {
+        accumulateEvent(_removeEventPrefix(name), events);
+      }
+    }
+  }
+
+  void accumulateEvent(String name, Set<String> events) {
+    var translated = _eventTranslations[name];
+    events.add(translated != null ? translated : name);
+  }
+
+  String urlToPath(String url) {
+    if (url == null) return '';
+    return (url.split('/')..removeLast()..add('')).join('/');
+  }
+
+  /**
+   * Install external stylesheets loaded in <element> elements into the
+   * element's template.
+   */
+  void installSheets() {
+    cacheSheets();
+    cacheStyles();
+    installLocalSheets();
+    installGlobalStyles();
+  }
+
+  void cacheSheets() {
+    _sheets = findNodes(_SHEET_SELECTOR);
+    for (var s in sheets) s.remove();
+  }
+
+  void cacheStyles() {
+    _styles = findNodes('$_STYLE_SELECTOR[$_SCOPE_ATTR]');
+    for (var s in styles) s.remove();
+  }
+
+  /**
+   * Takes external stylesheets loaded in an `<element>` element and moves
+   * their content into a style element inside the `<element>`'s template.
+   * The sheet is then removed from the `<element>`. This is done only so
+   * that if the element is loaded in the main document, the sheet does
+   * not become active.
+   * Note, ignores sheets with the attribute 'polymer-scope'.
+   */
+  void installLocalSheets() {
+    var sheets = this.sheets.where(
+        (s) => !s.attributes.containsKey(_SCOPE_ATTR));
+    var content = this.templateContent;
+    if (content != null) {
+      var cssText = new StringBuffer();
+      for (var sheet in sheets) {
+        cssText..write(_cssTextFromSheet(sheet))..write('\n');
+      }
+      if (cssText.length > 0) {
+        content.insertBefore(
+            new StyleElement()..text = '$cssText',
+            content.firstChild);
+      }
+    }
+  }
+
+  List<Element> findNodes(String selector, [bool matcher(Element e)]) {
+    var nodes = this.queryAll(selector).toList();
+    var content = this.templateContent;
+    if (content != null) {
+      nodes = nodes..addAll(content.queryAll(selector));
+    }
+    if (matcher != null) return nodes.where(matcher).toList();
+    return nodes;
+  }
+
+  /**
+   * Promotes external stylesheets and style elements with the attribute
+   * polymer-scope='global' into global scope.
+   * This is particularly useful for defining @keyframe rules which
+   * currently do not function in scoped or shadow style elements.
+   * (See wkb.ug/72462)
+   */
+  // TODO(sorvell): remove when wkb.ug/72462 is addressed.
+  void installGlobalStyles() {
+    var style = styleForScope(_STYLE_GLOBAL_SCOPE);
+    _applyStyleToScope(style, document.head);
+  }
+
+  String cssTextForScope(String scopeDescriptor) {
+    var cssText = new StringBuffer();
+    // handle stylesheets
+    var selector = '[$_SCOPE_ATTR=$scopeDescriptor]';
+    matcher(s) => s.matches(selector);
+
+    for (var sheet in sheets.where(matcher)) {
+      cssText..write(_cssTextFromSheet(sheet))..write('\n\n');
+    }
+    // handle cached style elements
+    for (var style in styles.where(matcher)) {
+      cssText..write(style.textContent)..write('\n\n');
+    }
+    return cssText.toString();
+  }
+
+  StyleElement styleForScope(String scopeDescriptor) {
+    var cssText = cssTextForScope(scopeDescriptor);
+    return cssTextToScopeStyle(cssText, scopeDescriptor);
+  }
+
+  StyleElement cssTextToScopeStyle(String cssText, String scopeDescriptor) {
+    if (cssText == '') return null;
+
+    return new StyleElement()
+        ..text = cssText
+        ..attributes[_STYLE_SCOPE_ATTRIBUTE] = '$name-$scopeDescriptor';
+  }
+
+  /**
+   * fetch a list of all observable properties names in our inheritance chain
+   * above Polymer.
+   */
+  // TODO(sjmiles): perf: reflection is slow, relatively speaking
+  // If an element may take 6us to create, getCustomPropertyNames might
+  // cost 1.6us more.
+  void inferObservers(ClassMirror type) {
+    for (var method in type.methods.values) {
+      if (method.isStatic || !method.isRegularMethod) continue;
+
+      String name = MirrorSystem.getName(method.simpleName);
+      if (name.endsWith('Changed')) {
+        if (_observe == null) _observe = {};
+        name = name.substring(0, name.length - 7);
+        _observe[name] = method.simpleName;
+      }
+    }
+  }
+
+  void publishProperties(ClassMirror type) {
+    // Dart note: _publish was already populated by publishAttributes
+    if (_publish != null) _publishLC = _lowerCaseMap(_publish);
+  }
+
+  Map<String, dynamic> _lowerCaseMap(Map<String, dynamic> properties) {
+    final map = new Map<String, dynamic>();
+    properties.forEach((name, value) {
+      map[name.toLowerCase()] = value;
+    });
+    return map;
+  }
+}
+
+/// maps tag names to prototypes
+final Map _typesByName = new Map<String, ClassMirror>();
+
+ClassMirror _getRegisteredType(String name) => _typesByName[name];
+
+/// elements waiting for prototype, by name
+final Map _waitType = new Map<String, PolymerDeclaration>();
+
+void _notifyType(String name) {
+  var waiting = _waitType.remove(name);
+  if (waiting != null) waiting.registerWhenReady();
+}
+
+/// elements waiting for super, by name
+final Map _waitSuper = new Map<String, List<PolymerDeclaration>>();
+
+void _notifySuper(String name) {
+  _registered.add(name);
+  var waiting = _waitSuper.remove(name);
+  if (waiting != null) {
+    for (var w in waiting) {
+      w.registerWhenReady();
+    }
+  }
+}
+
+/// track document.register'ed tag names
+final Set _registered = new Set<String>();
+
+bool _isRegistered(name) => _registered.contains(name);
+
+final Map _declarations = new Map<ClassMirror, PolymerDeclaration>();
+
+PolymerDeclaration _getDeclaration(ClassMirror type) => _declarations[type];
+
+final _objectType = reflectClass(Object);
+
+Map _getProperties(ClassMirror type, Map props, bool matches(metadata)) {
+  for (var field in type.variables.values) {
+    if (field.isFinal || field.isStatic || field.isPrivate) continue;
+
+    for (var meta in field.metadata) {
+      if (matches(meta.reflectee)) {
+        if (props == null) props = {};
+        props[MirrorSystem.getName(field.simpleName)] = field;
+        break;
+      }
+    }
+  }
+
+  for (var getter in type.getters.values) {
+    if (getter.isStatic || getter.isPrivate) continue;
+
+    for (var meta in getter.metadata) {
+      if (matches(meta.reflectee)) {
+        if (_hasSetter(type, getter)) {
+          if (props == null) props = {};
+          props[MirrorSystem.getName(getter.simpleName)] = getter;
+        }
+        break;
+      }
+    }
+  }
+
+  return props;
+}
+
+bool _hasSetter(ClassMirror type, MethodMirror getter) {
+  var setterName = new Symbol('${MirrorSystem.getName(getter.simpleName)}=');
+  return type.setters.containsKey(setterName);
+}
+
+bool _inDartHtml(ClassMirror type) =>
+    type.owner.simpleName == const Symbol('dart.dom.html');
+
+
+/** Attribute prefix used for declarative event handlers. */
+const _EVENT_PREFIX = 'on-';
+
+/** Whether an attribute declares an event. */
+bool _hasEventPrefix(String attr) => attr.startsWith(_EVENT_PREFIX);
+
+String _removeEventPrefix(String name) => name.substring(_EVENT_PREFIX.length);
+
+/**
+ * Using Polymer's platform/src/ShadowCSS.js passing the style tag's content.
+ */
+void _shimShadowDomStyling(DocumentFragment template, String localName) {
+  if (js.context == null || template == null) return;
+
+  var platform = js.context['Platform'];
+  if (platform == null) return;
+
+  var style = template.query('style');
+  if (style == 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 scopedCSS = shimShadowDOMStyling2.apply(shadowCss,
+      [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;
+}
+
+const _STYLE_SELECTOR = 'style';
+const _SHEET_SELECTOR = '[rel=stylesheet]';
+const _STYLE_GLOBAL_SCOPE = 'global';
+const _SCOPE_ATTR = 'polymer-scope';
+const _STYLE_SCOPE_ATTRIBUTE = 'element';
+
+void _applyStyleToScope(StyleElement style, Node scope) {
+  if (style == null) return;
+
+  // TODO(sorvell): necessary for IE
+  // see https://connect.microsoft.com/IE/feedback/details/790212/
+  // cloning-a-style-element-and-adding-to-document-produces
+  // -unexpected-result#details
+  // var clone = style.cloneNode(true);
+  var clone = new StyleElement()..text = style.text;
+
+  var attr = style.attributes[_STYLE_SCOPE_ATTRIBUTE];
+  if (attr != null) {
+    clone.attributes[_STYLE_SCOPE_ATTRIBUTE] = attr;
+  }
+
+  scope.append(clone);
+}
+
+String _cssTextFromSheet(Element sheet) {
+  if (sheet == null || js.context == null) return '';
+
+  // TODO(jmesserly): this is a hacky way to communcate with HTMLImports...
+
+  // Remove rel=stylesheet, href to keep this inert.
+  var href = sheet.attributes.remove('href');
+  var rel = sheet.attributes.remove('rel');
+  document.body.append(sheet);
+  String resource;
+  try {
+    resource = js.context['document']['body']['lastChild']['__resource'];
+  } finally {
+    sheet.remove();
+    if (href != null) sheet.attributes['href'] = href;
+    if (rel != null) sheet.attributes['rel'] = rel;
+  }
+  return resource != null ? resource : '';
+}
+
+const _OBSERVE_SUFFIX = 'Changed';
+
+// TODO(jmesserly): is this list complete?
+final _eventTranslations = const {
+  // TODO(jmesserly): these three Polymer.js translations won't work in Dart,
+  // because we strip the webkit prefix (below). Reconcile.
+  'webkitanimationstart': 'webkitAnimationStart',
+  'webkitanimationend': 'webkitAnimationEnd',
+  'webkittransitionend': 'webkitTransitionEnd',
+
+  'domfocusout': 'DOMFocusOut',
+  'domfocusin': 'DOMFocusIn',
+
+  // TODO(jmesserly): Dart specific renames. Reconcile with Polymer.js
+  'animationend': 'webkitAnimationEnd',
+  'animationiteration': 'webkitAnimationIteration',
+  'animationstart': 'webkitAnimationStart',
+  'doubleclick': 'dblclick',
+  'fullscreenchange': 'webkitfullscreenchange',
+  'fullscreenerror': 'webkitfullscreenerror',
+  'keyadded': 'webkitkeyadded',
+  'keyerror': 'webkitkeyerror',
+  'keymessage': 'webkitkeymessage',
+  'needkey': 'webkitneedkey',
+  'speechchange': 'webkitSpeechChange',
+};
+
+final _reverseEventTranslations = () {
+  final map = new Map<String, String>();
+  _eventTranslations.forEach((onName, eventType) {
+    map[eventType] = onName;
+  });
+  return map;
+}();
+
+// Dart note: we need this function because we have additional renames JS does
+// not have. The JS renames are simply case differences, whereas we have ones
+// like doubleclick -> dblclick and stripping the webkit prefix.
+String _eventNameFromType(String eventType) {
+  final result = _reverseEventTranslations[eventType];
+  return result != null ? result : eventType;
+}
diff --git a/pkg/polymer/lib/src/instance.dart b/pkg/polymer/lib/src/instance.dart
new file mode 100644
index 0000000..f0bff99
--- /dev/null
+++ b/pkg/polymer/lib/src/instance.dart
@@ -0,0 +1,930 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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 polymer;
+
+/**
+ * Use this annotation to publish a field as an attribute. For example:
+ *
+ *     class MyPlaybackElement extends PolymerElement {
+ *       // This will be available as an HTML attribute, for example:
+ *       //     <my-playback volume="11">
+ *       @published double volume;
+ *     }
+ */
+// TODO(jmesserly): does @published imply @observable or vice versa?
+const published = const PublishedProperty();
+
+/** An annotation used to publish a field as an attribute. See [published]. */
+class PublishedProperty extends ObservableProperty {
+  const PublishedProperty();
+}
+
+// TODO(jmesserly): make this the mixin so we can have Polymer type extensions,
+// and move the implementation of PolymerElement in here. Once done it will look
+// like:
+// abstract class Polymer { ... all the things ... }
+// typedef PolymerElement = HtmlElement with Polymer, Observable;
+abstract class Polymer {
+  // TODO(jmesserly): should this really be public?
+  /** Regular expression that matches data-bindings. */
+  static final bindPattern = new RegExp(r'\{\{([^{}]*)}}');
+
+  /**
+   * Like [document.register] but for Polymer elements.
+   *
+   * Use the [name] to specify custom elment's tag name, for example:
+   * "fancy-button" if the tag is used as `<fancy-button>`.
+   *
+   * The [type] is the type to construct. If not supplied, it defaults to
+   * [PolymerElement].
+   */
+  // NOTE: this is called "element" in src/declaration/polymer-element.js, and
+  // exported as "Polymer".
+  static void register(String name, [Type type]) {
+    //console.log('registering [' + name + ']');
+    if (type == null) type = PolymerElement;
+    _registerClassMirror(name, reflectClass(type));
+  }
+
+  // TODO(jmesserly): we use ClassMirror internall for now, until it is possible
+  // to get from ClassMirror -> Type.
+  static void _registerClassMirror(String name, ClassMirror type) {
+    _typesByName[name] = type;
+    // notify the registrar waiting for 'name', if any
+    _notifyType(name);
+  }
+}
+
+/**
+ * The base class for Polymer elements. It provides convience features on top
+ * of the custom elements web standard.
+ */
+class PolymerElement extends CustomElement with ObservableMixin {
+  // Fully ported from revision:
+  // https://github.com/Polymer/polymer/blob/4dc481c11505991a7c43228d3797d28f21267779
+  //
+  //   src/instance/attributes.js
+  //   src/instance/base.js
+  //   src/instance/events.js
+  //   src/instance/mdv.js
+  //   src/instance/properties.js
+  //   src/instance/utils.js
+  //
+  // Not yet ported:
+  //   src/instance/style.js -- blocked on ShadowCSS.shimPolyfillDirectives
+
+  /// The one syntax to rule them all.
+  static final BindingDelegate _polymerSyntax = new PolymerExpressions();
+
+  static int _preparingElements = 0;
+
+  PolymerDeclaration _declaration;
+
+  /** The most derived `<polymer-element>` declaration for this element. */
+  PolymerDeclaration get declaration => _declaration;
+
+  Map<String, StreamSubscription> _elementObservers;
+  bool _unbound; // lazy-initialized
+  Job _unbindAllJob;
+
+  bool get _elementPrepared => _declaration != null;
+
+  bool get applyAuthorStyles => false;
+  bool get resetStyleInheritance => false;
+  bool get alwaysPrepare => false;
+
+  /**
+   * Shadow roots created by [parseElement]. See [getShadowRoot].
+   */
+  final _shadowRoots = new HashMap<String, ShadowRoot>();
+
+  /** Map of items in the shadow root(s) by their [Element.id]. */
+  // TODO(jmesserly): various issues:
+  // * wrap in UnmodifiableMapView?
+  // * should we have an object that implements noSuchMethod?
+  // * should the map have a key order (e.g. LinkedHash or SplayTree)?
+  // * should this be a live list? Polymer doesn't, maybe due to JS limitations?
+  // For now I picked the most performant choice: non-live HashMap.
+  final Map<String, Element> $ = new HashMap<String, Element>();
+
+  /**
+   * Gets the shadow root associated with the corresponding custom element.
+   *
+   * This is identical to [shadowRoot], unless there are multiple levels of
+   * inheritance and they each have their own shadow root. For example,
+   * this can happen if the base class and subclass both have `<template>` tags
+   * in their `<polymer-element>` tags.
+   */
+  // TODO(jmesserly): Polymer does not have this feature. Reconcile.
+  ShadowRoot getShadowRoot(String customTagName) => _shadowRoots[customTagName];
+
+  ShadowRoot createShadowRoot([name]) {
+    if (name != null) {
+      throw new ArgumentError('name argument must not be supplied.');
+    }
+
+    // Provides ability to traverse from ShadowRoot to the host.
+    // TODO(jmessery): remove once we have this ability on the DOM.
+    final root = super.createShadowRoot();
+    _shadowHost[root] = host;
+    return root;
+  }
+
+  /**
+   * Invoke [callback] in [wait], unless the job is re-registered,
+   * which resets the timer. For example:
+   *
+   *     _myJob = job(_myJob, callback, const Duration(milliseconds: 100));
+   *
+   * Returns a job handle which can be used to re-register a job.
+   */
+  Job job(Job job, void callback(), Duration wait) =>
+      runJob(job, callback, wait);
+
+  // TODO(jmesserly): I am not sure if we should have the
+  // created/createdCallback distinction. See post here:
+  // https://groups.google.com/d/msg/polymer-dev/W0ZUpU5caIM/v5itFnvnehEJ
+  // Same issue with inserted and removed.
+  void created() {
+    if (document.window != null || alwaysPrepare || _preparingElements > 0) {
+      prepareElement();
+    }
+  }
+
+  void prepareElement() {
+    // Dart note: get the _declaration, which also marks _elementPrepared
+    _declaration = _getDeclaration(reflect(this).type);
+    // do this first so we can observe changes during initialization
+    observeProperties();
+    // install boilerplate attributes
+    copyInstanceAttributes();
+    // process input attributes
+    takeAttributes();
+    // add event listeners
+    addHostListeners();
+    // guarantees that while preparing, any sub-elements will also be prepared
+    _preparingElements++;
+    // process declarative resources
+    parseDeclarations(_declaration);
+    _preparingElements--;
+    // user entry point
+    ready();
+  }
+
+  /** Called when [prepareElement] is finished. */
+  void ready() {}
+
+  void inserted() {
+    if (!_elementPrepared) {
+      prepareElement();
+    }
+    cancelUnbindAll(preventCascade: true);
+  }
+
+  void removed() {
+    asyncUnbindAll();
+  }
+
+  /** Recursive ancestral <element> initialization, oldest first. */
+  void parseDeclarations(PolymerDeclaration declaration) {
+    if (declaration != null) {
+      parseDeclarations(declaration.superDeclaration);
+      parseDeclaration(declaration.host);
+    }
+  }
+
+  /**
+   * Parse input `<polymer-element>` as needed, override for custom behavior.
+   */
+  void parseDeclaration(Element elementElement) {
+    var root = shadowFromTemplate(fetchTemplate(elementElement));
+
+    // Dart note: this is extra code compared to Polymer to support
+    // the getShadowRoot method.
+    if (root == null) return;
+
+    var name = elementElement.attributes['name'];
+    if (name == null) return;
+    _shadowRoots[name] = root;
+  }
+
+  /**
+   * Return a shadow-root template (if desired), override for custom behavior.
+   */
+  Element fetchTemplate(Element elementElement) =>
+      elementElement.query('template');
+
+  /** Utility function that creates a shadow root from a `<template>`. */
+  ShadowRoot shadowFromTemplate(Element template) {
+    if (template == null) return null;
+    // cache elder shadow root (if any)
+    var elderRoot = this.shadowRoot;
+    // make a shadow root
+    var root = createShadowRoot();
+    // migrate flag(s)(
+    root.applyAuthorStyles = applyAuthorStyles;
+    root.resetStyleInheritance = resetStyleInheritance;
+    // stamp template
+    // which includes parsing and applying MDV bindings before being
+    // inserted (to avoid {{}} in attribute values)
+    // e.g. to prevent <img src="images/{{icon}}"> from generating a 404.
+    var dom = instanceTemplate(template);
+    // append to shadow dom
+    root.append(dom);
+    // perform post-construction initialization tasks on shadow root
+    shadowRootReady(root, template);
+    // return the created shadow root
+    return root;
+  }
+
+  void shadowRootReady(ShadowRoot root, Element template) {
+    // locate nodes with id and store references to them in this.$ hash
+    marshalNodeReferences(root);
+    // add local events of interest...
+    addInstanceListeners(root, template);
+    // TODO(jmesserly): port this
+    // set up pointer gestures
+    // PointerGestures.register(root);
+  }
+
+  /** Locate nodes with id and store references to them in [$] hash. */
+  void marshalNodeReferences(ShadowRoot root) {
+    if (root == null) return;
+    for (var n in root.queryAll('[id]')) {
+      $[n.id] = n;
+    }
+  }
+
+  void attributeChanged(String name, String oldValue) {
+    if (name != 'class' && name != 'style') {
+      attributeToProperty(name, attributes[name]);
+    }
+  }
+
+  // TODO(jmesserly): use stream or future here?
+  void onMutation(Node node, void listener(MutationObserver obs)) {
+    new MutationObserver((records, MutationObserver observer) {
+      listener(observer);
+      observer.disconnect();
+    })..observe(node, childList: true, subtree: true);
+  }
+
+  void copyInstanceAttributes() {
+    _declaration._instanceAttributes.forEach((name, value) {
+      attributes[name] = value;
+    });
+  }
+
+  void takeAttributes() {
+    if (_declaration._publishLC == null) return;
+    attributes.forEach(attributeToProperty);
+  }
+
+  /**
+   * If attribute [name] is mapped to a property, deserialize
+   * [value] into that property.
+   */
+  void attributeToProperty(String name, String value) {
+    // try to match this attribute to a property (attributes are
+    // all lower-case, so this is case-insensitive search)
+    var property = propertyForAttribute(name);
+    if (property == null) return;
+
+    // filter out 'mustached' values, these are to be
+    // replaced with bound-data and are not yet values
+    // themselves.
+    if (value == null || value.contains(Polymer.bindPattern)) return;
+
+    // get original value
+    final self = reflect(this);
+    final defaultValue = self.getField(property.simpleName).reflectee;
+
+    // deserialize Boolean or Number values from attribute
+    final newValue = deserializeValue(value, defaultValue,
+        _inferPropertyType(defaultValue, property));
+
+    // only act if the value has changed
+    if (!identical(newValue, defaultValue)) {
+      // install new value (has side-effects)
+      self.setField(property.simpleName, newValue);
+    }
+  }
+
+  /** Return the published property matching name, or null. */
+  // TODO(jmesserly): should we just return Symbol here?
+  DeclarationMirror propertyForAttribute(String name) {
+    final publishLC = _declaration._publishLC;
+    if (publishLC == null) return null;
+    //console.log('propertyForAttribute:', name, 'matches', match);
+    return publishLC[name];
+  }
+
+  /**
+   * Convert representation of [value] based on [type] and [defaultValue].
+   */
+  // TODO(jmesserly): this should probably take a ClassMirror instead of
+  // TypeMirror, but it is currently impossible to get from a TypeMirror to a
+  // ClassMirror.
+  Object deserializeValue(String value, Object defaultValue, TypeMirror type) =>
+      deserialize.deserializeValue(value, defaultValue, type);
+
+  String serializeValue(Object value, TypeMirror inferredType) {
+    if (value == null) return null;
+
+    final type = inferredType.qualifiedName;
+    if (type == const Symbol('dart.core.bool')) {
+      return _toBoolean(value) ? '' : null;
+    } else if (type == const Symbol('dart.core.String')
+        || type == const Symbol('dart.core.int')
+        || type == const Symbol('dart.core.double')) {
+      return '$value';
+    }
+    return null;
+  }
+
+  void reflectPropertyToAttribute(String name) {
+    // TODO(sjmiles): consider memoizing this
+    final self = reflect(this);
+    // try to intelligently serialize property value
+    // TODO(jmesserly): cache symbol?
+    final propValue = self.getField(new Symbol(name)).reflectee;
+    final property = _declaration._publish[name];
+    var inferredType = _inferPropertyType(propValue, property);
+    final serializedValue = serializeValue(propValue, inferredType);
+    // boolean properties must reflect as boolean attributes
+    if (serializedValue != null) {
+      attributes[name] = serializedValue;
+      // TODO(sorvell): we should remove attr for all properties
+      // that have undefined serialization; however, we will need to
+      // refine the attr reflection system to achieve this; pica, for example,
+      // relies on having inferredType object properties not removed as
+      // attrs.
+    } else if (inferredType.qualifiedName == const Symbol('dart.core.bool')) {
+      attributes.remove(name);
+    }
+  }
+
+  /**
+   * 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);
+
+  NodeBinding bind(String name, model, String path) {
+    // note: binding is a prepare signal. This allows us to be sure that any
+    // property changes that occur as a result of binding will be observed.
+    if (!_elementPrepared) prepareElement();
+
+    var property = propertyForAttribute(name);
+    if (property != null) {
+      unbind(name);
+      // use n-way Polymer binding
+      var observer = bindProperty(property.simpleName, model, path);
+      // reflect bound property to attribute when binding
+      // to ensure binding is not left on attribute if property
+      // does not update due to not changing.
+      reflectPropertyToAttribute(name);
+      return bindings[name] = observer;
+    } else {
+      return super.bind(name, model, path);
+    }
+  }
+
+  void asyncUnbindAll() {
+    if (_unbound == true) return;
+    _unbindLog.info('[$localName] asyncUnbindAll');
+    _unbindAllJob = job(_unbindAllJob, unbindAll, const Duration(seconds: 0));
+  }
+
+  void unbindAll() {
+    if (_unbound == true) return;
+
+    unbindAllProperties();
+    super.unbindAll();
+    _unbindNodeTree(shadowRoot);
+    // TODO(sjmiles): must also unbind inherited shadow roots
+    _unbound = true;
+  }
+
+  void cancelUnbindAll({bool preventCascade}) {
+    if (_unbound == true) {
+      _unbindLog.warning(
+          '[$localName] already unbound, cannot cancel unbindAll');
+      return;
+    }
+    _unbindLog.info('[$localName] cancelUnbindAll');
+    if (_unbindAllJob != null) {
+      _unbindAllJob.stop();
+      _unbindAllJob = null;
+    }
+
+    // cancel unbinding our shadow tree iff we're not in the process of
+    // cascading our tree (as we do, for example, when the element is inserted).
+    if (preventCascade == true) return;
+    _forNodeTree(shadowRoot, (n) {
+      if (n is PolymerElement) {
+        (n as PolymerElement).cancelUnbindAll();
+      }
+    });
+  }
+
+  static void _unbindNodeTree(Node node) {
+    _forNodeTree(node, (node) => node.unbindAll());
+  }
+
+  static void _forNodeTree(Node node, void callback(Node node)) {
+    if (node == null) return;
+
+    callback(node);
+    for (var child = node.firstChild; child != null; child = child.nextNode) {
+      _forNodeTree(child, callback);
+    }
+  }
+
+  /** Set up property observers. */
+  void observeProperties() {
+    // TODO(sjmiles):
+    // we observe published properties so we can reflect them to attributes
+    // ~100% of our team's applications would work without this reflection,
+    // perhaps we can make it optional somehow
+    //
+    // add user's observers
+    final observe = _declaration._observe;
+    final publish = _declaration._publish;
+    if (observe != null) {
+      observe.forEach((name, value) {
+        if (publish != null && publish.containsKey(name)) {
+          observeBoth(name, value);
+        } else {
+          observeProperty(name, value);
+        }
+      });
+    }
+    // add observers for published properties
+    if (publish != null) {
+      publish.forEach((name, value) {
+        if (observe == null || !observe.containsKey(name)) {
+          observeAttributeProperty(name);
+        }
+      });
+    }
+  }
+
+  void _observe(String name, void callback(newValue, oldValue)) {
+    _observeLog.info('[$localName] watching [$name]');
+    // TODO(jmesserly): this is a little different than the JS version so we
+    // can pass the oldValue, which is missing from Dart's PathObserver.
+    // This probably gives us worse performance.
+    var path = new PathObserver(this, name);
+    Object oldValue = null;
+    _registerObserver(name, path.changes.listen((_) {
+      final newValue = path.value;
+      final old = oldValue;
+      oldValue = newValue;
+      callback(newValue, old);
+    }));
+  }
+
+  void _registerObserver(String name, StreamSubscription sub) {
+    if (_elementObservers == null) {
+      _elementObservers = new Map<String, StreamSubscription>();
+    }
+    _elementObservers[name] = sub;
+  }
+
+  void observeAttributeProperty(String name) {
+    _observe(name, (value, old) => reflectPropertyToAttribute(name));
+  }
+
+  void observeProperty(String name, Symbol method) {
+    final self = reflect(this);
+    _observe(name, (value, old) => self.invoke(method, [old]));
+  }
+
+  void observeBoth(String name, Symbol methodName) {
+    final self = reflect(this);
+    _observe(name, (value, old) {
+      reflectPropertyToAttribute(name);
+      self.invoke(methodName, [old]);
+    });
+  }
+
+  void unbindProperty(String name) {
+    if (_elementObservers == null) return;
+    var sub = _elementObservers.remove(name);
+    if (sub != null) sub.cancel();
+  }
+
+  void unbindAllProperties() {
+    if (_elementObservers == null) return;
+    for (var sub in _elementObservers.values) sub.cancel();
+    _elementObservers.clear();
+  }
+
+  /**
+   * Bind a [property] in this object to a [path] in model. *Note* in Dart it
+   * is necessary to also define the field:
+   *
+   *     var myProperty;
+   *
+   *     created() {
+   *       super.created();
+   *       bindProperty(#myProperty, this, 'myModel.path.to.otherProp');
+   *     }
+   */
+  // TODO(jmesserly): replace with something more localized, like:
+  // @ComputedField('myModel.path.to.otherProp');
+  NodeBinding bindProperty(Symbol name, Object model, String path) =>
+      // apply Polymer two-way reference binding
+      _bindProperties(this, name, model, path);
+
+  /**
+   * bind a property in A to a path in B by converting A[property] to a
+   * getter/setter pair that accesses B[...path...]
+   */
+  static NodeBinding _bindProperties(PolymerElement inA, Symbol inProperty,
+        Object inB, String inPath) {
+
+    if (_bindLog.isLoggable(Level.INFO)) {
+      _bindLog.info('[$inB]: bindProperties: [$inPath] to '
+          '[${inA.localName}].[$inProperty]');
+    }
+
+    // Dart note: normally we only reach this code when we know it's a
+    // property, but if someone uses bindProperty directly they might get a
+    // NoSuchMethodError either from the getField below, or from the setField
+    // inside PolymerBinding. That doesn't seem unreasonable, but it's a slight
+    // difference from Polymer.js behavior.
+
+    // capture A's value if B's value is null or undefined,
+    // otherwise use B's value
+    var path = new PathObserver(inB, inPath);
+    if (path.value == null) {
+      path.value = reflect(inA).getField(inProperty).reflectee;
+    }
+    return new _PolymerBinding(inA, inProperty, inB, inPath);
+  }
+
+  /** Attach event listeners on the host (this) element. */
+  void addHostListeners() {
+    var events = _declaration._eventDelegates;
+    if (events.isEmpty) return;
+
+    if (_eventsLog.isLoggable(Level.INFO)) {
+      _eventsLog.info('[$localName] addHostListeners: $events');
+    }
+    addNodeListeners(this, events.keys, hostEventListener);
+  }
+
+  /** Attach event listeners inside a shadow [root]. */
+  void addInstanceListeners(ShadowRoot root, Element template) {
+    var templateDelegates = _declaration._templateDelegates;
+    if (templateDelegates == null) return;
+    var events = templateDelegates[template];
+    if (events == null) return;
+
+    if (_eventsLog.isLoggable(Level.INFO)) {
+      _eventsLog.info('[$localName] addInstanceListeners: $events');
+    }
+    addNodeListeners(root, events, instanceEventListener);
+  }
+
+  void addNodeListeners(Node node, Iterable<String> events,
+      void listener(Event e)) {
+
+    for (var name in events) {
+      addNodeListener(node, name, listener);
+    }
+  }
+
+  void addNodeListener(Node node, String event, void listener(Event e)) {
+    node.on[event].listen(listener);
+  }
+
+  void hostEventListener(Event event) {
+    // TODO(jmesserly): do we need this check? It was using cancelBubble, see:
+    // https://github.com/Polymer/polymer/issues/292
+    if (!event.bubbles) return;
+
+    bool log = _eventsLog.isLoggable(Level.INFO);
+    if (log) {
+      _eventsLog.info('>>> [$localName]: hostEventListener(${event.type})');
+    }
+
+    var h = findEventDelegate(event);
+    if (h != null) {
+      if (log) _eventsLog.info('[$localName] found host handler name [$h]');
+      var detail = event is CustomEvent ?
+          (event as CustomEvent).detail : null;
+      // TODO(jmesserly): cache the symbols?
+      dispatchMethod(new Symbol(h), [event, detail, this]);
+    }
+
+    if (log) {
+      _eventsLog.info('<<< [$localName]: hostEventListener(${event.type})');
+    }
+  }
+
+  String findEventDelegate(Event event) =>
+      _declaration._eventDelegates[_eventNameFromType(event.type)];
+
+  /** Call [methodName] method on [this] with [args], if the method exists. */
+  // TODO(jmesserly): I removed the [node] argument as it was unused. Reconcile.
+  void dispatchMethod(Symbol methodName, List args) {
+    bool log = _eventsLog.isLoggable(Level.INFO);
+    if (log) _eventsLog.info('>>> [$localName]: dispatch $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 self = reflect(this);
+    var method = self.type.methods[methodName];
+    if (method != 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 = method.parameters.where((p) => !p.isOptional).length;
+    }
+    self.invoke(methodName, args);
+
+    if (log) _eventsLog.info('<<< [$localName]: dispatch $methodName');
+
+    // TODO(jmesserly): workaround for HTML events not supporting zones.
+    performMicrotaskCheckpoint();
+  }
+
+  void instanceEventListener(Event event) {
+    _listenLocal(host, event);
+  }
+
+  // TODO(sjmiles): much of the below privatized only because of the vague
+  // notion this code is too fiddly and we need to revisit the core feature
+  void _listenLocal(Element host, Event event) {
+    // TODO(jmesserly): do we need this check? It was using cancelBubble, see:
+    // https://github.com/Polymer/polymer/issues/292
+    if (!event.bubbles) return;
+
+    bool log = _eventsLog.isLoggable(Level.INFO);
+    if (log) _eventsLog.info('>>> [$localName]: listenLocal [${event.type}]');
+
+    final eventOn = '$_EVENT_PREFIX${_eventNameFromType(event.type)}';
+    if (event.path == null) {
+      _listenLocalNoEventPath(host, event, eventOn);
+    } else {
+      _listenLocalEventPath(host, event, eventOn);
+    }
+
+    if (log) _eventsLog.info('<<< [$localName]: listenLocal [${event.type}]');
+  }
+
+  static void _listenLocalEventPath(Element host, Event event, String eventOn) {
+    var c = null;
+    for (var target in event.path) {
+      // if we hit host, stop
+      if (identical(target, host)) return;
+
+      // find a controller for the target, unless we already found `host`
+      // as a controller
+      c = identical(c, host) ? c : _findController(target);
+
+      // if we have a controller, dispatch the event, and stop if the handler
+      // returns true
+      if (c != null && _handleEvent(c, target, event, eventOn)) {
+        return;
+      }
+    }
+  }
+
+  // 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
+  static void _listenLocalNoEventPath(Element host, Event event,
+      String eventOn) {
+
+    if (_eventsLog.isLoggable(Level.INFO)) {
+      _eventsLog.info('event.path() not supported for ${event.type}');
+    }
+
+    var target = event.target;
+    var c = null;
+    // if we hit dirt or host, stop
+    while (target != null && target != host) {
+      // find a controller for target `t`, unless we already found `host`
+      // as a controller
+      c = identical(c, host) ? c : _findController(target);
+
+      // if we have a controller, dispatch the event, return 'true' if
+      // handler returns true
+      if (c != null && _handleEvent(c, target, event, eventOn)) {
+        return;
+      }
+      target = target.parent;
+    }
+  }
+
+  // TODO(jmesserly): this won't find the correct host unless the ShadowRoot
+  // was created on a PolymerElement.
+  static Element _findController(Node node) {
+    while (node.parentNode != null) {
+      node = node.parentNode;
+    }
+    return _shadowHost[node];
+  }
+
+  static bool _handleEvent(Element ctrlr, Node node, Event event,
+      String eventOn) {
+
+    // 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 name = node is Element ? (node as Element).attributes[eventOn] : null;
+    if (name != null && _handleIfNotHandled(node, event)) {
+      if (_eventsLog.isLoggable(Level.INFO)) {
+        _eventsLog.info('[${ctrlr.localName}] found handler name [$name]');
+      }
+      var detail = event is CustomEvent ?
+          (event as CustomEvent).detail : null;
+
+      if (node != null) {
+        // TODO(jmesserly): cache symbols?
+        ctrlr.xtag.dispatchMethod(new Symbol(name), [event, detail, node]);
+      }
+    }
+
+    // TODO(jmesserly): do we need this? It was using cancelBubble, see:
+    // https://github.com/Polymer/polymer/issues/292
+    return !event.bubbles;
+  }
+
+  // TODO(jmesserly): I don't understand this bit. It seems to be a duplicate
+  // delivery prevention mechanism?
+  static bool _handleIfNotHandled(Node node, Event event) {
+    var list = _eventHandledTable[event];
+    if (list == null) _eventHandledTable[event] = list = new Set<Node>();
+    if (!list.contains(node)) {
+      list.add(node);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Invokes a function asynchronously.
+   * This will call `Platform.flush()` and then return a `new Timer`
+   * with the provided [method] and [timeout].
+   *
+   * If you would prefer to run the callback using
+   * [window.requestAnimationFrame], see the [async] method.
+   */
+  // Dart note: "async" is split into 2 methods so it can have a sensible type
+  // signatures. Also removed the various features that don't make sense in a
+  // Dart world, like binding to "this" and taking arguments list.
+  Timer asyncTimer(void method(), Duration timeout) {
+    // when polyfilling Object.observe, ensure changes
+    // propagate before executing the async method
+    platform.flush();
+    return new Timer(timeout, method);
+  }
+
+  /**
+   * Invokes a function asynchronously.
+   * This will call `Platform.flush()` and then call
+   * [window.requestAnimationFrame] with the provided [method] and return the
+   * result.
+   *
+   * If you would prefer to run the callback after a given duration, see
+   * the [asyncTimer] method.
+   */
+  int async(RequestAnimationFrameCallback method) {
+    // when polyfilling Object.observe, ensure changes
+    // propagate before executing the async method
+    platform.flush();
+    return window.requestAnimationFrame(method);
+  }
+
+  /**
+   * Fire a [CustomEvent] targeting [toNode], or this if toNode is not
+   * supplied. Returns the [detail] object.
+   */
+  Object fire(String type, {Object detail, Node toNode, bool canBubble}) {
+    var node = toNode != null ? toNode : this;
+    //log.events && console.log('[%s]: sending [%s]', node.localName, inType);
+    node.dispatchEvent(new CustomEvent(
+      type,
+      canBubble: canBubble != null ? canBubble : true,
+      detail: detail
+    ));
+    return detail;
+  }
+
+  /**
+   * Fire an event asynchronously. See [async] and [fire].
+   */
+  asyncFire(String type, {Object detail, Node toNode, bool canBubble}) {
+    // TODO(jmesserly): I'm not sure this method adds much in Dart, it's easy to
+    // add "() =>"
+    async((x) => fire(
+        type, detail: detail, toNode: toNode, canBubble: canBubble));
+  }
+
+  /**
+   * Remove [className] from [old], add class to [anew], if they exist.
+   */
+  void classFollows(Element anew, Element old, String className) {
+    if (old != null) {
+      old.classes.remove(className);
+    }
+    if (anew != null) {
+      anew.classes.add(className);
+    }
+  }
+}
+
+// Dart note: Polymer addresses n-way bindings by metaprogramming: redefine
+// the property on the PolymerElement instance to always get its value from the
+// model@path. We can't replicate this in Dart so we do the next best thing:
+// listen to changes on both sides and update the values.
+// TODO(jmesserly): our approach leads to race conditions in the bindings.
+// See http://code.google.com/p/dart/issues/detail?id=13567
+class _PolymerBinding extends NodeBinding {
+  final InstanceMirror _target;
+  final Symbol _property;
+  StreamSubscription _sub;
+  Object _lastValue;
+
+  _PolymerBinding(PolymerElement node, Symbol property, model, path)
+      : _target = reflect(node),
+        _property = property,
+        super(node, MirrorSystem.getName(property), model, path) {
+
+    _sub = node.changes.listen(_propertyValueChanged);
+  }
+
+  void close() {
+    if (closed) return;
+    _sub.cancel();
+    super.close();
+  }
+
+  void boundValueChanged(newValue) {
+    _lastValue = newValue;
+    _target.setField(_property, newValue);
+  }
+
+  void _propertyValueChanged(List<ChangeRecord> records) {
+    for (var record in records) {
+      if (record.changes(_property)) {
+        final newValue = _target.getField(_property).reflectee;
+        if (!identical(_lastValue, newValue)) {
+          value = newValue;
+        }
+        return;
+      }
+    }
+  }
+}
+
+bool _toBoolean(value) => null != value && false != value;
+
+TypeMirror _propertyType(DeclarationMirror property) =>
+    property is VariableMirror
+        ? (property as VariableMirror).type
+        : (property as MethodMirror).returnType;
+
+TypeMirror _inferPropertyType(Object value, DeclarationMirror property) {
+  var type = _propertyType(property);
+  if (type.qualifiedName == const Symbol('dart.core.Object') ||
+      type.qualifiedName == const Symbol('dynamic')) {
+    // Attempt to infer field type from the default value.
+    if (value != null) {
+      type = reflect(value).type;
+    }
+  }
+  return type;
+}
+
+final Logger _observeLog = new Logger('polymer.observe');
+final Logger _eventsLog = new Logger('polymer.events');
+final Logger _unbindLog = new Logger('polymer.unbind');
+final Logger _bindLog = new Logger('polymer.bind');
+
+final Expando _shadowHost = new Expando<Element>();
+
+final Expando _eventHandledTable = new Expando<Set<Node>>();
diff --git a/pkg/polymer/lib/src/loader.dart b/pkg/polymer/lib/src/loader.dart
new file mode 100644
index 0000000..e8cbb90
--- /dev/null
+++ b/pkg/polymer/lib/src/loader.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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 polymer;
+
+/** 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]) {
+  runMicrotask(() {
+    // 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();
+    registerCustomElement('polymer-element', () => new PolymerDeclaration());
+
+    for (var lib in libraries) {
+      _loadLibrary(lib, srcUrl);
+    }
+
+    // TODO(jmesserly): this should be in the custom_element polyfill, not here.
+    // notify the system that we are bootstrapped
+    document.body.dispatchEvent(
+        new CustomEvent('WebComponentsReady', canBubble: true));
+  });
+}
+
+/** 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) {
+        Polymer._registerClassMirror(meta.tagName, c);
+      }
+    }
+
+    // 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/transformer.dart b/pkg/polymer/lib/transformer.dart
index 5f4dc02..26d5678 100644
--- a/pkg/polymer/lib/transformer.dart
+++ b/pkg/polymer/lib/transformer.dart
@@ -6,6 +6,7 @@
 // TODO(sigmund): move into a plugin directory when pub supports it.
 library polymer.src.transform;
 
+import 'package:barback/barback.dart';
 import 'package:observe/transform.dart';
 import 'src/build/code_extractor.dart';
 import 'src/build/import_inliner.dart';
diff --git a/pkg/polymer/pubspec.yaml b/pkg/polymer/pubspec.yaml
index 4d93ad5..acd745f 100644
--- a/pkg/polymer/pubspec.yaml
+++ b/pkg/polymer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: polymer
-author: Web UI Authors <web-ui-dev@dartlang.org>
+author: Polymer.dart 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
@@ -16,11 +16,12 @@
   html_import: any
   logging: any
   mdv: any
+  meta: any
   observe: any
   path: any
   polymer_expressions: any
   shadow_dom: any
   source_maps: any
-  # TODO(jmesserly): make this a dev_dependency
-  unittest: any
   yaml: any
+dev_dependencies:
+  unittest: any
diff --git a/pkg/polymer/test/attr_deserialize_test.dart b/pkg/polymer/test/attr_deserialize_test.dart
new file mode 100644
index 0000000..8497752
--- /dev/null
+++ b/pkg/polymer/test/attr_deserialize_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('my-element')
+class MyElement extends PolymerElement {
+  @published double volume;
+  @published int factor;
+  @published bool crankIt;
+  @published String msg;
+  @published DateTime time;
+  @published Object json;
+}
+
+main() {
+  useHtmlConfiguration();
+
+  test('attributes were deserialized', () {
+    MyElement elem = query('my-element').xtag;
+    final msg = 'property should match attribute.';
+    expect(elem.volume, 11.0, reason: '"volume" should match attribute');
+    expect(elem.factor, 3, reason: '"factor" should match attribute');
+    expect(elem.crankIt, true, reason: '"crankIt" should match attribute');
+    expect(elem.msg, "Yo!", reason: '"msg" should match attribute');
+    expect(elem.time, DateTime.parse('2013-08-08T18:34Z'),
+        reason: '"time" should match attribute');
+    expect(elem.json, {'here': 'is', 'some': 'json', 'x': 123},
+        reason: '"json" should match attribute');
+
+    var text = elem.shadowRoot.text;
+    // Collapse adjacent whitespace like a browser would:
+    text = text.replaceAll('\n', ' ').replaceAll(new RegExp(r'\s+'), ' ');
+
+    // Note: using "${33.0}" because the toString differs in JS vs Dart VM.
+    expect(text, " Yo! The volume is ${33.0} !! The time is "
+        "2013-08-08 18:34:00.000Z and here's some JSON: "
+        "{here: is, some: json, x: 123} ",
+        reason: 'text should match expected HTML template');
+  });
+}
diff --git a/pkg/polymer/test/attr_deserialize_test.html b/pkg/polymer/test/attr_deserialize_test.html
new file mode 100644
index 0000000..de10fac
--- /dev/null
+++ b/pkg/polymer/test/attr_deserialize_test.html
@@ -0,0 +1,29 @@
+<!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>Polymer.dart attribute deserialization test</title>
+    <script src="packages/polymer/boot.js"></script>
+    <script src="packages/unittest/test_controller.js"></script>
+  </head>
+  <body>
+    <polymer-element name="my-element">
+      <template>
+        <h1>{{msg}} The volume is {{volume * factor}}
+          <template if="{{crankIt}}">!!</template></h1>
+        <h3>The time is {{time}} and here's some JSON: {{json}}</h3>
+      </template>
+    </polymer-element>
+
+    <my-element volume="11" crankit msg="Yo!" factor="3"
+        time="2013-08-08T18:34Z"
+        json="{'here': 'is', 'some': 'json', 'x': 123}">
+    </my-element>
+
+    <script type="application/dart" src="attr_deserialize_test.dart"></script>
+  </body>
+</html>
diff --git a/pkg/polymer/test/attr_mustache_test.dart b/pkg/polymer/test/attr_mustache_test.dart
new file mode 100644
index 0000000..fba0171
--- /dev/null
+++ b/pkg/polymer/test/attr_mustache_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('x-target')
+class XTarget extends PolymerElement {
+  final Completer _found = new Completer();
+  Future get foundSrc => _found.future;
+
+  // force an mdv binding
+  bind(name, model, path) =>
+      TemplateElement.mdvPackage(this).bind(name, model, path);
+
+  inserted() {
+    testSrcForMustache();
+  }
+
+  attributeChanged(name, oldValue) {
+    testSrcForMustache();
+    if (attributes[name] == '../testSource') {
+      _found.complete();
+    }
+  }
+
+  testSrcForMustache() {
+    expect(attributes['src'], isNot(matches(Polymer.bindPattern)),
+        reason: 'attribute does not contain {{...}}');
+  }
+}
+
+@CustomTag('x-test')
+class XTest extends PolymerElement {
+  @observable var src = 'testSource';
+}
+
+main() {
+  useHtmlConfiguration();
+
+  test('mustache attributes', () {
+    final xtest = document.query('#test').xtag;
+    final xtarget = xtest.shadowRoot.query('#target').xtag;
+    return xtarget.foundSrc;
+  });
+}
diff --git a/pkg/polymer/test/attr_mustache_test.html b/pkg/polymer/test/attr_mustache_test.html
new file mode 100644
index 0000000..df9f9ee
--- /dev/null
+++ b/pkg/polymer/test/attr_mustache_test.html
@@ -0,0 +1,27 @@
+<!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>take attributes</title>
+    <script src="packages/polymer/boot.js"></script>
+    <script src="packages/unittest/test_controller.js"></script>
+  </head>
+  <body>
+    <x-test id="test"></x-test>
+
+    <polymer-element name="x-target" attributes="src">
+    </polymer-element>
+
+    <polymer-element name="x-test">
+      <template>
+        <x-target id="target" src="../{{src}}"></x-target>
+      </template>
+    </polymer-element>
+
+  <script type="application/dart" src="attr_mustache_test.dart"></script>
+  </body>
+</html>
diff --git a/pkg/polymer/test/build/all_phases_test.dart b/pkg/polymer/test/build/all_phases_test.dart
index 1c2dccc..9e6a9b7 100644
--- a/pkg/polymer/test/build/all_phases_test.dart
+++ b/pkg/polymer/test/build/all_phases_test.dart
@@ -198,17 +198,14 @@
 }
 ''';
 
-String _sampleObservableOutput(String className, String fieldName) => '''
-library ${className}_$fieldName;
-import 'package:observe/observe.dart';
-
-class $className extends ChangeNotifierBase {
-  int __\$$fieldName;
-  int get $fieldName => __\$$fieldName;
-  set $fieldName(int value) {
-    __\$$fieldName = notifyPropertyChange(const Symbol('$fieldName'), __\$$fieldName, value);
-  }
-
-  $className($fieldName) : __\$$fieldName = $fieldName;
-}
-''';
+String _sampleObservableOutput(String className, String field) =>
+    "library ${className}_$field;\n"
+    "import 'package:observe/observe.dart';\n\n"
+    "class $className extends ChangeNotifierBase {\n"
+    "  @observable int get $field => __\$$field; "
+      "int __\$$field; "
+      "set $field(int value) { "
+      "__\$$field = notifyPropertyChange(#$field, __\$$field, value); "
+      "}\n"
+    "  $className($field) : __\$$field = $field;\n"
+    "}\n";
diff --git a/pkg/polymer/test/build/linter_test.dart b/pkg/polymer/test/build/linter_test.dart
index e4f3630..17975a8 100644
--- a/pkg/polymer/test/build/linter_test.dart
+++ b/pkg/polymer/test/build/linter_test.dart
@@ -261,7 +261,7 @@
             '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. '
-            '(lib/test.html 1 0)'
+            '(lib/test.html 1 5)'
       });
 
     _testLinter('on-foo is only supported in polymer elements', {
@@ -272,7 +272,7 @@
         'a|lib/test.html.messages':
             'warning: Inline event handlers are only supported inside '
             'declarations of <polymer-element>. '
-            '(lib/test.html 1 0)'
+            '(lib/test.html 1 5)'
       });
 
     _testLinter('on-foo is not an expression', {
@@ -285,7 +285,20 @@
             'warning: Invalid event handler body "bar()". Declare a method '
             'in your custom element "void handlerName(event, detail, target)" '
             'and use the form on-foo="handlerName". '
-            '(lib/test.html 1 28)'
+            '(lib/test.html 1 33)'
+      });
+
+    _testLinter('on-foo-bar is no longer supported', {
+        'a|lib/test.html': '''<html><body>
+            <polymer-element name="x-a"><div on-foo-bar="quux"></div>
+            </polymer-element>
+            '''.replaceAll('            ', ''),
+      }, {
+        'a|lib/test.html.messages':
+            'warning: Invalid event name "on-foo-bar". After the "on-" the '
+            'event name should not use dashes. For example use "on-fooBar" or '
+            '"on-foobar" (both forms are equivalent in HTML). '
+            '(lib/test.html 1 33)'
       });
   });
 
@@ -294,7 +307,7 @@
         'a|lib/test.html': '<x-foo></x-foo>',
       }, {
         'a|lib/test.html.messages':
-            'warning: definition for custom element with tag name "x-foo" not '
+            'warning: definition for Polymer element with tag name "x-foo" not '
             'found. (lib/test.html 0 0)'
       });
 
@@ -302,7 +315,7 @@
         'a|lib/test.html': '<div is="x-foo"></div>',
       }, {
         'a|lib/test.html.messages':
-            'warning: definition for custom element with tag name "x-foo" not '
+            'warning: definition for Polymer element with tag name "x-foo" not '
             'found. (lib/test.html 0 0)'
       });
 
@@ -409,6 +422,20 @@
             'to write <li is="x-a">? (lib/test.html 1 0)'
       });
   });
+
+  group('custom attributes', () {
+    _testLinter('foo-bar is no longer supported in attributes', {
+        'a|lib/test.html': '''<html><body>
+            <polymer-element name="x-a" attributes="foo-bar">
+            </polymer-element>
+            '''.replaceAll('            ', ''),
+      }, {
+        'a|lib/test.html.messages':
+            'warning: PolymerElement no longer recognizes attribute names with '
+            'dashes such as "foo-bar". Use "fooBar" or "foobar" instead (both '
+            'forms are equivalent in HTML). (lib/test.html 1 28)'
+      });
+  });
 }
 
 _testLinter(String name, Map inputFiles, Map outputMessages) {
diff --git a/pkg/polymer/test/utils_test.dart b/pkg/polymer/test/build/utils_test.dart
similarity index 98%
rename from pkg/polymer/test/utils_test.dart
rename to pkg/polymer/test/build/utils_test.dart
index 335e538..cd99656 100644
--- a/pkg/polymer/test/utils_test.dart
+++ b/pkg/polymer/test/build/utils_test.dart
@@ -7,7 +7,7 @@
 
 import 'package:unittest/compact_vm_config.dart';
 import 'package:unittest/unittest.dart';
-import 'package:polymer/src/utils.dart';
+import 'package:polymer/src/build/utils.dart';
 
 main() {
   useCompactVMConfiguration();
diff --git a/pkg/polymer/test/prop_attr_reflection_test.dart b/pkg/polymer/test/prop_attr_reflection_test.dart
new file mode 100644
index 0000000..d74f5e4
--- /dev/null
+++ b/pkg/polymer/test/prop_attr_reflection_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/platform.dart' as Platform;
+import 'package:polymer/polymer.dart';
+
+class XFoo extends PolymerElement {
+  @observable var foo = '';
+  @observable String baz = '';
+}
+
+class XBar extends XFoo {
+  @observable int zot = 3;
+  @observable bool zim = false;
+  @observable String str = 'str';
+  @observable Object obj;
+}
+
+class XCompose extends PolymerElement {
+  @observable bool zim = false;
+}
+
+main() {
+  useHtmlConfiguration();
+
+  // Most tests use @CustomTag, here we test out the impertive register:
+  Polymer.register('x-foo', XFoo);
+  Polymer.register('x-bar', XBar);
+  Polymer.register('x-compose', XCompose);
+
+  test('property attribute reflection', () {
+    var xcompose = query('x-compose').xtag;
+    var xfoo = query('x-foo').xtag;
+    xfoo.foo = 5;
+    Platform.flush();
+    Platform.endOfMicrotask(expectAsync0(() {
+      expect(xcompose.$['bar'].attributes.containsKey('zim'), false,
+          reason: 'attribute bound to property updates when binding is made');
+
+      expect('${xfoo.foo}', xfoo.attributes['foo'],
+          reason: 'attribute reflects property as string');
+      xfoo.attributes['foo'] = '27';
+      // TODO(jmesserly): why is JS leaving this as a String? From the code it
+      // looks like it should use the type of 5 and parse it as a number.
+      expect('${xfoo.foo}', xfoo.attributes['foo'],
+          reason: 'property reflects attribute');
+      //
+      xfoo.baz = 'Hello';
+      Platform.flush();
+      Platform.endOfMicrotask(expectAsync0(() {
+        expect(xfoo.baz, xfoo.attributes['baz'],
+            reason: 'attribute reflects property');
+        //
+        var xbar = query('x-bar').xtag;
+        //
+        xbar.foo = 'foo!';
+        xbar.zot = 27;
+        xbar.zim = true;
+        xbar.str = 'str!';
+        xbar.obj = {'hello': 'world'};
+        Platform.flush();
+        Platform.endOfMicrotask(expectAsync0(() {
+          expect(xbar.foo, xbar.attributes['foo'],
+              reason: 'inherited published property is reflected');
+          expect('${xbar.zot}', xbar.attributes['zot'],
+              reason: 'attribute reflects property as number');
+          expect(xbar.attributes['zim'], '', reason:
+              'attribute reflects true valued boolean property as '
+              'having attribute');
+          expect(xbar.str, xbar.attributes['str'],
+              reason: 'attribute reflects property as published string');
+          expect(xbar.attributes.containsKey('obj'), false,
+              reason: 'attribute does not reflect object property');
+          xbar.attributes['zim'] = 'false';
+          xbar.attributes['foo'] = 'foo!!';
+          xbar.attributes['zot'] = '54';
+          xbar.attributes['str'] = 'str!!';
+          xbar.attributes['obj'] = "{'hello': 'world'}";
+          expect(xbar.foo, xbar.attributes['foo'],
+              reason: 'property reflects attribute as string');
+          expect(xbar.zot, 54,
+              reason: 'property reflects attribute as number');
+          expect(xbar.zim, false,
+              reason: 'property reflects attribute as boolean');
+          expect(xbar.str, 'str!!',
+              reason: 'property reflects attribute as published string');
+          expect(xbar.obj, {'hello': 'world'},
+              reason: 'property reflects attribute as object');
+          xbar.zim = false;
+          Platform.flush();
+          Platform.endOfMicrotask(expectAsync0(() {
+            expect(xbar.attributes.containsKey('zim'), false, reason:
+                'attribute reflects false valued boolean property as NOT '
+                'having attribute');
+            var objAttr = xbar.attributes['obj'];
+            xbar.obj = 'hi';
+            Platform.endOfMicrotask(expectAsync0(() {
+              expect(xbar.attributes['obj'], objAttr, reason:
+                  'do not reflect property with default type of object');
+            }));
+          }));
+        }));
+      }));
+    }));
+  });
+}
diff --git a/pkg/polymer/test/prop_attr_reflection_test.html b/pkg/polymer/test/prop_attr_reflection_test.html
new file mode 100644
index 0000000..e4466d3
--- /dev/null
+++ b/pkg/polymer/test/prop_attr_reflection_test.html
@@ -0,0 +1,32 @@
+<!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>publish attributes</title>
+    <script src="packages/polymer/boot.js"></script>
+    <script src="packages/unittest/test_controller.js"></script>
+  </head>
+  <body>
+
+    <x-foo></x-foo>
+    <polymer-element name="x-foo" attributes="foo baz">
+    </polymer-element>
+
+    <x-bar></x-bar>
+    <polymer-element name="x-bar" extends="x-foo" attributes="zot zim str obj">
+    </polymer-element>
+
+    <x-compose></x-compose>
+    <polymer-element name="x-compose">
+      <template>
+        <x-bar id="bar" zim="{{zim}}"></x-bar>
+      </template>
+    </polymer-element>
+
+  <script type="application/dart" src="prop_attr_reflection_test.dart"></script>
+  </body>
+</html>
\ No newline at end of file
diff --git a/pkg/polymer/test/publish_attributes_test.dart b/pkg/polymer/test/publish_attributes_test.dart
new file mode 100644
index 0000000..e31b74f
--- /dev/null
+++ b/pkg/polymer/test/publish_attributes_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/polymer.dart';
+
+// Dart note: unlike JS, you can't publish something that doesn't
+// have a corresponding field because we can't dynamically add properties.
+// So we define XFoo and XBar types here.
+@CustomTag('x-foo')
+class XFoo extends PolymerElement {
+  @observable var Foo;
+  @observable var baz;
+}
+
+@CustomTag('x-bar')
+class XBar extends XFoo {
+  @observable var Bar;
+}
+
+@CustomTag('x-zot')
+class XZot extends XBar {
+  @published int zot = 3;
+}
+
+@CustomTag('x-squid')
+class XSquid extends XZot {
+  @published int baz = 13;
+  @published int zot = 5;
+  @published int squid = 7;
+}
+
+main() {
+  useHtmlConfiguration();
+
+  test('published properties', () {
+    published(tag) =>
+        query('polymer-element[name=$tag]').xtag.publishedProperties;
+
+    print(published('x-foo'));
+    print(published('x-bar'));
+    print(published('x-zot'));
+    print(published('x-squid'));
+
+    expect(published('x-foo'), ['Foo', 'baz']);
+    expect(published('x-bar'), ['Foo', 'baz', 'Bar']);
+    expect(published('x-zot'), ['Foo', 'baz', 'Bar', 'zot']);
+    expect(published('x-squid'), ['Foo', 'baz', 'Bar', 'zot', 'squid']);
+  });
+}
diff --git a/pkg/polymer/test/publish_attributes_test.html b/pkg/polymer/test/publish_attributes_test.html
new file mode 100644
index 0000000..6b9347a
--- /dev/null
+++ b/pkg/polymer/test/publish_attributes_test.html
@@ -0,0 +1,29 @@
+<!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>publish attributes</title>
+    <script src="packages/polymer/boot.js"></script>
+    <script src="packages/unittest/test_controller.js"></script>
+  </head>
+  <body>
+
+    <polymer-element name="x-foo" attributes="Foo baz">
+    </polymer-element>
+
+    <polymer-element name="x-bar" extends="x-foo" attributes="Bar">
+    </polymer-element>
+
+    <polymer-element name="x-zot" extends="x-bar">
+    </polymer-element>
+
+    <polymer-element name="x-squid" extends="x-zot" attributes="squid">
+    </polymer-element>
+
+  <script type="application/dart" src="publish_attributes_test.dart"></script>
+  </body>
+</html>
diff --git a/pkg/polymer/test/take_attributes_test.dart b/pkg/polymer/test/take_attributes_test.dart
new file mode 100644
index 0000000..a9e409f
--- /dev/null
+++ b/pkg/polymer/test/take_attributes_test.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('x-foo')
+class XFoo extends PolymerElement {
+  @published bool boolean = false;
+  @published num number = 42;
+  @published String str = "don't panic";
+}
+
+@CustomTag('x-bar')
+class XBar extends PolymerElement {
+  @observable bool boolean = false;
+  @observable num number = 42;
+  @observable String str = "don't panic";
+}
+
+@CustomTag('x-zot')
+class XZot extends XBar {
+  @observable num number = 84;
+}
+
+@CustomTag('x-date')
+class XDate extends PolymerElement {
+  @observable var value = new DateTime(2013, 9, 25);
+}
+
+@CustomTag('x-array')
+class XArray extends PolymerElement {
+  @observable List values;
+}
+
+@CustomTag('x-obj')
+class XObj extends PolymerElement {
+  @observable var values = {};
+}
+
+main() {
+  useHtmlConfiguration();
+
+  test('take attributes', () {
+    queryXTag(x) => document.query(x).xtag;
+
+    expect(queryXTag("#foo0").boolean, true);
+    expect(queryXTag("#foo1").boolean, false);
+    expect(queryXTag("#foo2").boolean, true);
+    expect(queryXTag("#foo3").boolean, false);
+    // this one is only 'truthy'
+    expect(queryXTag("#foo4").boolean, true);
+    // this one is also 'truthy', but should it be?
+    expect(queryXTag("#foo5").boolean, true);
+    //
+    expect(queryXTag("#foo0").number, 42);
+    expect(queryXTag("#foo0").str, "don't panic");
+    //
+    expect(queryXTag("#bar0").boolean, true);
+    expect(queryXTag("#bar1").boolean, false);
+    expect(queryXTag("#bar2").boolean, true);
+    expect(queryXTag("#bar3").boolean, false);
+    // this one is only 'truthy'
+    expect(queryXTag("#bar4").boolean, true);
+    // this one is also 'truthy', but should it be?
+    expect(queryXTag("#bar5").boolean, true);
+    //
+    expect(queryXTag("#bar0").number, 42);
+    expect(queryXTag("#bar0").str, "don't panic");
+    //
+    expect(queryXTag("#zot0").boolean, true);
+    expect(queryXTag("#zot1").boolean, false);
+    expect(queryXTag("#zot2").boolean, true);
+    expect(queryXTag("#zot3").boolean, false);
+    // this one is only 'truthy'
+    expect(queryXTag("#zot4").boolean, true);
+    // this one is also 'truthy', but should it be?
+    expect(queryXTag("#zot5").boolean, true);
+    //
+    expect(queryXTag("#zot0").number, 84);
+    expect(queryXTag("#zot6").number, 185);
+    expect(queryXTag("#zot0").str, "don't panic");
+    //
+    // Date deserialization tests
+    expect(queryXTag("#date1").value, new DateTime(2014, 12, 25));
+    expect(queryXTag("#date2").value, isNot(equals(new DateTime(2014, 12, 25))),
+        reason: 'Dart does not support this format');
+    expect(queryXTag("#date3").value, new DateTime(2014, 12, 25, 11, 45));
+    expect(queryXTag("#date4").value, new DateTime(2014, 12, 25, 11, 45, 30));
+    // Failures on Firefox. Need to fix this with custom parsing
+    //expect(String(queryXTag("#date5").value), String(new Date(2014, 11, 25, 11, 45, 30)));
+    //
+    // milliseconds in the Date string not supported on Firefox
+    //expect(queryXTag("#date5").value.getMilliseconds(), new Date(2014, 11, 25, 11, 45, 30, 33).getMilliseconds());
+    //
+    // Array deserialization tests
+    expect(queryXTag("#arr1").values, [0, 1, 2]);
+    expect(queryXTag("#arr2").values, [33]);
+    // Object deserialization tests
+    expect(queryXTag("#obj1").values, { 'name': 'Brandon',
+        'nums': [1, 22, 33] });
+    expect(queryXTag("#obj2").values, { "color": "Red" });
+    expect(queryXTag("#obj3").values, { 'movie': 'Buckaroo Banzai',
+        'DOB': '07/31/1978' });
+  });
+}
diff --git a/pkg/polymer/test/take_attributes_test.html b/pkg/polymer/test/take_attributes_test.html
new file mode 100644
index 0000000..c65f604
--- /dev/null
+++ b/pkg/polymer/test/take_attributes_test.html
@@ -0,0 +1,75 @@
+<!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>take attributes</title>
+    <script src="packages/polymer/boot.js"></script>
+    <script src="packages/unittest/test_controller.js"></script>
+  </head>
+  <body>
+
+    <polymer-element name="x-foo"></polymer-element>
+
+    <x-foo id="foo0" boolean="true"></x-foo>
+    <x-foo id="foo1" boolean="false"></x-foo>
+    <x-foo id="foo2" boolean></x-foo>
+    <x-foo id="foo3"></x-foo>
+    <x-foo id="foo4" boolean="squid"></x-foo>
+    <x-foo id="foo5" boolean="0"></x-foo>
+
+    <polymer-element name="x-bar" attributes="boolean number str">
+    </polymer-element>
+
+    <x-bar id="bar0" boolean="true"></x-bar>
+    <x-bar id="bar1" boolean="false"></x-bar>
+    <x-bar id="bar2" boolean></x-bar>
+    <x-bar id="bar3"></x-bar>
+    <x-bar id="bar4" boolean="squid"></x-bar>
+    <x-bar id="bar5" boolean="0"></x-bar>
+
+    <polymer-element name="x-zot" extends="x-bar" attributes="boolean">
+    </polymer-element>
+
+    <x-zot id="zot0" boolean="true"></x-zot>
+    <x-zot id="zot1" boolean="false"></x-zot>
+    <x-zot id="zot2" boolean></x-zot>
+    <x-zot id="zot3"></x-zot>
+    <x-zot id="zot4" boolean="squid"></x-zot>
+    <x-zot id="zot5" boolean="0"></x-zot>
+    <x-zot id="zot6" number="185"></x-zot>
+
+    <polymer-element name="x-date" attributes="value"></polymer-element>
+
+    <!--
+    TODO(jmesserly): Dart note: I changed these to dash "-" instead of slash "/"
+    as the year-month-day separator. Also the form "December 25, 2014" is not
+    supported in Dart.
+    -->
+    <x-date id="date1" value="2014-12-25"></x-date>
+    <x-date id="date2" value="December 25, 2014"></x-date>
+    <x-date id="date3" value="2014-12-25 11:45"></x-date>
+    <x-date id="date4" value="2014-12-25 11:45:30"></x-date>
+    <x-date id="date5" value="2014-12-25 11:45:30:33"></x-date>
+    <x-date id="dated" value="2014-12-25T11:45:30:33"></x-date>
+
+    <polymer-element name="x-array" attributes="values"></polymer-element>
+
+    <x-array id="arr1" values="[0, 1, 2]"></x-array>
+    <x-array id="arr2" values="[33]"></x-array>
+
+    <polymer-element name="x-obj" attributes="values"></polymer-element>
+
+    <x-obj id="obj1" values='{ "name": "Brandon", "nums": [1, 22, 33] }'>
+    </x-obj>
+    <x-obj id="obj2" values='{ "color": "Red" }'></x-obj>
+    <x-obj id="obj3"
+           values="{ 'movie': 'Buckaroo Banzai', 'DOB': '07/31/1978' }">
+    </x-obj>
+
+  <script type="application/dart" src="take_attributes_test.dart"></script>
+  </body>
+</html>
diff --git a/pkg/polymer_expressions/lib/expression.dart b/pkg/polymer_expressions/lib/expression.dart
index 0a5bb82..60b7548 100644
--- a/pkg/polymer_expressions/lib/expression.dart
+++ b/pkg/polymer_expressions/lib/expression.dart
@@ -8,7 +8,7 @@
 
 // Helper functions for building expression trees programmatically
 
-EmptyExpression empty() => new EmptyExpression();
+EmptyExpression empty() => const EmptyExpression();
 Literal literal(v) => new Literal(v);
 MapLiteral mapLiteral(List<MapLiteralEntry> entries) => new MapLiteral(entries);
 MapLiteralEntry mapLiteralEntry(Literal key, Expression value) =>
@@ -24,7 +24,7 @@
 
 
 class AstFactory {
-  EmptyExpression empty() => new EmptyExpression();
+  EmptyExpression empty() => const EmptyExpression();
 
   Literal literal(v) => new Literal(v);
 
@@ -52,12 +52,13 @@
 
 /// Base class for all expressions
 abstract class Expression {
+  const Expression();
   accept(Visitor v);
 }
 
 class EmptyExpression extends Expression {
+  const EmptyExpression();
   accept(Visitor v) => v.visitEmptyExpression(this);
-  bool operator ==(o) => o is EmptyExpression;
 }
 
 class Literal<T> extends Expression {
diff --git a/pkg/scheduled_test/lib/scheduled_process.dart b/pkg/scheduled_test/lib/scheduled_process.dart
index 4b28309..b0ceaa3 100644
--- a/pkg/scheduled_test/lib/scheduled_process.dart
+++ b/pkg/scheduled_test/lib/scheduled_process.dart
@@ -17,7 +17,9 @@
 /// synchronously. All operations on this class are scheduled.
 ///
 /// Before running the test, either [shouldExit] or [kill] must be called on
-/// this to ensure that the process terminates when expected.
+/// this to ensure that the process terminates when expected. Note that [kill]
+/// is using SIGKILL, to ensure the process is killed on Mac OS X (an early
+/// SIGTERM on Mac OS X may be ignored).
 ///
 /// If the test fails, this will automatically print out any stdout and stderr
 /// from the process to aid debugging.
@@ -220,7 +222,7 @@
       if (!_exitCode.hasValue) {
         killedPrematurely = true;
         _endExpected = true;
-        _process.value.kill();
+        _process.value.kill(ProcessSignal.SIGKILL);
         // Ensure that the onException queue waits for the process to actually
         // exit after being killed.
         wrapFuture(_process.value.exitCode, "waiting for process "
@@ -328,7 +330,9 @@
     _taskBeforeEnd = currentSchedule.tasks.contents.last;
     schedule(() {
       _endExpected = true;
-      return _process.then((p) => p.kill()).then((_) => _exitCode);
+      return _process
+          .then((p) => p.kill(ProcessSignal.SIGKILL))
+          .then((_) => _exitCode);
     }, "waiting for process '$description' to die");
   }
 
diff --git a/pkg/unittest/lib/html_config.dart b/pkg/unittest/lib/html_config.dart
index e4eba0f..860ec4f 100644
--- a/pkg/unittest/lib/html_config.dart
+++ b/pkg/unittest/lib/html_config.dart
@@ -10,6 +10,7 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:html';
+import 'dart:js' as js;
 import 'unittest.dart';
 
 /** Creates a table showing tests results in HTML. */
@@ -100,7 +101,12 @@
   void _installHandlers() {
     if (_onErrorSubscription == null) {
       _onErrorSubscription = window.onError.listen(
-        (e) => handleExternalError(e, '(DOM callback has errors)'));
+        (e) {
+          // Some tests may expect this and have no way to suppress the error.
+          if (js.context['testExpectsGlobalError'] != true) {
+            handleExternalError(e, '(DOM callback has errors)');
+          }
+        });
     }
     if (_onMessageSubscription == null) {
       _onMessageSubscription = window.onMessage.listen(
diff --git a/pkg/unittest/lib/test_controller.js b/pkg/unittest/lib/test_controller.js
index 4862e03..7cf6699 100644
--- a/pkg/unittest/lib/test_controller.js
+++ b/pkg/unittest/lib/test_controller.js
@@ -11,9 +11,20 @@
 if (typeof console == "object" && typeof console.clear == "function") {
   console.clear();
 }
+
+// Some tests may expect and have no way to suppress global errors.
+var testExpectsGlobalError = false;
+var testSuppressedGlobalErrors = [];
+
 // Set window onerror to make sure that we catch test harness errors across all
 // browsers.
 window.onerror = function (message, url, lineNumber) {
+  if (testExpectsGlobalError) {
+    testSuppressedGlobalErrors.push({
+      message: message
+    });
+    return;
+  }
   if (url) {
     showErrorAndExit(
         "\n\n" + url + ":" + lineNumber + ":\n" + message + "\n\n");
@@ -67,7 +78,7 @@
 
   // TODO(ricow): REMOVE, debug info, see issue 13292
   if (!testRunner) {
-    dartPrint('Calling notifyDone()');
+    printMessage('Calling notifyDone()');
   }
   // To support in browser launching of tests we post back start and result
   // messages to the window.opener.
@@ -80,7 +91,7 @@
 function processMessage(msg) {
   // TODO(ricow): REMOVE, debug info, see issue 13292
   if (!testRunner) {
-    dartPrint('processMessage(): ' + msg);
+    printMessage('processMessage(): ' + msg);
   }
   if (typeof msg != 'string') return;
   if (msg == 'unittest-suite-done') {
@@ -95,7 +106,7 @@
       window.postMessage('unittest-suite-success', '*');
     }
   } else if (msg == 'unittest-suite-success') {
-    dartPrint('PASS');
+    printMessage('PASS');
     notifyDone();
   } else if (msg == 'unittest-suite-fail') {
     showErrorAndExit('Some tests failed.');
@@ -114,11 +125,11 @@
 
 function showErrorAndExit(message) {
   if (message) {
-    dartPrint('Error: ' + String(message));
+    printMessage('Error: ' + String(message));
   }
   // dart/tools/testing/run_selenium.py is looking for either PASS or
   // FAIL and will continue polling until one of these words show up.
-  dartPrint('FAIL');
+  printMessage('FAIL');
   notifyDone();
 }
 
@@ -158,27 +169,50 @@
 });
 
 // dart2js will generate code to call this function to handle the Dart
-// [print] method. The base [Configuration] (config.html) calls
-// [print] with the secret messages "unittest-suite-success" and
-// "unittest-suite-wait-for-done". These messages are then posted so
-// processMessage above will see them.
+// [print] method.
+//
+// dartium will invoke this method for [print] calls if the environment variable
+// "DART_FORWARDING_PRINT" was set when launching dartium.
+//
+// Our tests will be wrapped, so we can detect when [main] is called and when
+// it has ended.
+// The wrapping happens either via "dartMainRunner" (for dart2js) or wrapped
+// tests for dartium.
+//
+// The following messages are handled specially:
+//   dart-calling-main:  signals that the dart [main] function will be invoked
+//   dart-main-done:  signals that the dart [main] function has finished
+//   unittest-suite-wait-for-done:  signals the start of an asynchronous test
+//   unittest-suite-success:  signals the end of an asynchrounous test
+//
+// These messages are used to communicate with the test and will be posted so
+// [processMessage] above can see it.
 function dartPrint(msg) {
   if ((msg === 'unittest-suite-success')
       || (msg === 'unittest-suite-done')
-      || (msg === 'unittest-suite-wait-for-done')) {
+      || (msg === 'unittest-suite-wait-for-done')
+      || (msg === 'dart-calling-main')
+      || (msg === 'dart-main-done')) {
     window.postMessage(msg, '*');
     return;
   }
+  printMessage(msg);
+}
+
+// Prints 'msg' to the console (if available) and to the body of the html
+// document.
+function printMessage(msg) {
   if (typeof console === 'object') console.warn(msg);
-  var pre = document.createElement("pre");
+  var pre = document.createElement('pre');
   pre.appendChild(document.createTextNode(String(msg)));
   document.body.appendChild(pre);
+  document.body.appendChild(document.createTextNode('\n'));
 }
 
 // dart2js will generate code to call this function instead of calling
 // Dart [main] directly. The argument is a closure that invokes main.
 function dartMainRunner(main) {
-  window.postMessage('dart-calling-main', '*');
+  dartPrint('dart-calling-main');
   try {
     main();
   } catch (e) {
@@ -187,5 +221,5 @@
     window.postMessage('unittest-suite-fail', '*');
     return;
   }
-  window.postMessage('dart-main-done', '*');
+  dartPrint('dart-main-done');
 }
diff --git a/pkg/unittest/lib/vm_config.dart b/pkg/unittest/lib/vm_config.dart
index 962ca97..e37cf72 100644
--- a/pkg/unittest/lib/vm_config.dart
+++ b/pkg/unittest/lib/vm_config.dart
@@ -21,8 +21,9 @@
   // We make this public so the user can turn it off if they want.
   bool useColor;
 
-  VMConfiguration() :
-    super(), useColor = stdioType(stdout) == StdioType.TERMINAL;
+  VMConfiguration()
+      : super(),
+        useColor = stdioType(stdout) == StdioType.TERMINAL;
 
   String formatResult(TestCase testCase) {
     String result = super.formatResult(testCase);
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc
index 182f2ff..2486c5b 100644
--- a/runtime/bin/builtin.cc
+++ b/runtime/bin/builtin.cc
@@ -35,7 +35,7 @@
     Dart_Handle patch_file_uri = DartUtils::NewString(patch_filename);
     free(patch_filename);
 
-    DART_CHECK_VALID(Dart_LoadPatch(library, patch_file_uri, patch_src));
+    DART_CHECK_VALID(Dart_LibraryLoadPatch(library, patch_file_uri, patch_src));
   }
 }
 
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 07cc545..48c10fb 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -13,6 +13,7 @@
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
 #include "bin/io_natives.h"
+#include "bin/platform.h"
 
 namespace dart {
 namespace bin {
@@ -26,7 +27,7 @@
   V(Directory_Create, 1)                                                       \
   V(Directory_Current, 0)                                                      \
   V(Directory_SetCurrent, 1)                                                   \
-  V(Directory_CreateTemp, 1)                                                   \
+  V(Directory_CreateTemp, 2)                                                   \
   V(Directory_Delete, 2)                                                       \
   V(Directory_Rename, 2)                                                       \
   V(Directory_List, 3)                                                         \
@@ -108,12 +109,10 @@
     // an isolate gets interrupted by the embedder in the middle of
     // Dart_StringToUTF8?  We need to make sure not to swallow the
     // interrupt.
-    fputs(Dart_GetError(result), stdout);
+    Platform::PrintBlocking(stdout, "%s\n", Dart_GetError(result));
   } else {
-    fwrite(chars, sizeof(*chars), length, stdout);
+    Platform::PrintBlocking(stdout, "%.*s\n", static_cast<int>(length), chars);
   }
-  fputc('\n', stdout);
-  fflush(stdout);
 }
 
 }  // namespace bin
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index 323b4a9..6aa4d09 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -78,7 +78,14 @@
 
 void FUNCTION_NAME(Directory_CreateTemp)(Dart_NativeArguments args) {
   Dart_Handle path = Dart_GetNativeArgument(args, 0);
-  char* result = Directory::CreateTemp(DartUtils::GetStringValue(path));
+  Dart_Handle system = Dart_GetNativeArgument(args, 1);
+  if (!Dart_IsString(path)) {
+    Dart_SetReturnValue(args, DartUtils::NewDartArgumentError(
+        "Template argument of CreateSystemTempSync is not a String"));
+    return;
+  }
+  char* result = Directory::CreateTemp(DartUtils::GetStringValue(path),
+                                       DartUtils::GetBooleanValue(system));
   if (result != NULL) {
     Dart_SetReturnValue(args, DartUtils::NewString(result));
     free(result);
@@ -188,7 +195,7 @@
 CObject* Directory::CreateTempRequest(const CObjectArray& request) {
   if (request.Length() == 1 && request[0]->IsString()) {
     CObjectString path(request[0]);
-    char* result = Directory::CreateTemp(path.CString());
+    char* result = Directory::CreateTemp(path.CString(), false);
     if (result != NULL) {
       CObject* temp_dir = new CObjectString(CObject::NewString(result));
       free(result);
@@ -200,6 +207,23 @@
   return CObject::IllegalArgumentError();
 }
 
+
+CObject* Directory::CreateSystemTempRequest(const CObjectArray& request) {
+  if (request.Length() == 1 && request[0]->IsString()) {
+    CObjectString path(request[0]);
+    char* result = Directory::CreateTemp(path.CString(), true);
+    if (result != NULL) {
+      CObject* temp_dir = new CObjectString(CObject::NewString(result));
+      free(result);
+      return temp_dir;
+    } else {
+      return CObject::NewOSError();
+    }
+  }
+  return CObject::IllegalArgumentError();
+}
+
+
 static CObject* CreateIllegalArgumentError() {
   // Respond with an illegal argument list error message.
   CObjectArray* error = new CObjectArray(CObject::NewArray(3));
@@ -210,6 +234,7 @@
   return error;
 }
 
+
 CObject* Directory::ListStartRequest(const CObjectArray& request) {
   if (request.Length() == 3 &&
       request[0]->IsString() &&
diff --git a/runtime/bin/directory.h b/runtime/bin/directory.h
index 210739e..57302a2 100644
--- a/runtime/bin/directory.h
+++ b/runtime/bin/directory.h
@@ -252,25 +252,12 @@
     DOES_NOT_EXIST
   };
 
-  // This enum must be kept in sync with the request values in
-  // directory_impl.dart.
-  enum DirectoryRequest {
-    kCreateRequest = 0,
-    kDeleteRequest = 1,
-    kExistsRequest = 2,
-    kCreateTempRequest = 3,
-    kListStartRequest = 4,
-    kListNextRequest = 5,
-    kListStopRequest = 6,
-    kRenameRequest = 7
-  };
-
   static void List(DirectoryListing* listing);
   static ExistsResult Exists(const char* path);
   static char* Current();
   static bool SetCurrent(const char* path);
   static bool Create(const char* path);
-  static char* CreateTemp(const char* const_template);
+  static char* CreateTemp(const char* const_template, bool system);
   static bool Delete(const char* path, bool recursive);
   static bool Rename(const char* path, const char* new_path);
 
@@ -278,6 +265,7 @@
   static CObject* DeleteRequest(const CObjectArray& request);
   static CObject* ExistsRequest(const CObjectArray& request);
   static CObject* CreateTempRequest(const CObjectArray& request);
+  static CObject* CreateSystemTempRequest(const CObjectArray& request);
   static CObject* ListStartRequest(const CObjectArray& request);
   static CObject* ListNextRequest(const CObjectArray& request);
   static CObject* ListStopRequest(const CObjectArray& request);
diff --git a/runtime/bin/directory_android.cc b/runtime/bin/directory_android.cc
index b48474d..6a2646a 100644
--- a/runtime/bin/directory_android.cc
+++ b/runtime/bin/directory_android.cc
@@ -382,33 +382,34 @@
 }
 
 
-char* Directory::CreateTemp(const char* const_template) {
+char* Directory::CreateTemp(const char* const_template, bool system) {
   // Returns a new, unused directory name, modifying the contents of
   // dir_template.  Creates the directory with the permissions specified
   // by the process umask.
   // The return value must be freed by the caller.
   PathBuffer path;
-  path.Add(const_template);
-  if (path.length() == 0) {
+  if (system) {
     // Android does not have a /tmp directory. A partial substitute,
     // suitable for bring-up work and tests, is to create a tmp
     // directory in /data/local/tmp.
     //
     // TODO(4413): In the long run, when running in an application we should
-    // probably use android.content.Context.getCacheDir().
+    // probably use the appropriate directory from the Android API,
+    // probably what File.createTempFile uses.
     #define ANDROID_TEMP_DIR "/data/local/tmp"
     struct stat st;
     if (stat(ANDROID_TEMP_DIR, &st) != 0) {
       mkdir(ANDROID_TEMP_DIR, 0777);
     }
-    path.Add(ANDROID_TEMP_DIR "/temp_dir1_");
-  } else if ((path.AsString())[path.length() - 1] == '/') {
-    path.Add("temp_dir_");
+    path.Add(ANDROID_TEMP_DIR "/");
   }
+
+  path.Add(const_template);
   if (!path.Add("XXXXXX")) {
     // Pattern has overflowed.
     return NULL;
   }
+
   char* result;
   do {
     result = MakeTempDirectory(path.AsString());
diff --git a/runtime/bin/directory_linux.cc b/runtime/bin/directory_linux.cc
index 88c6f7c..e12dbfd 100644
--- a/runtime/bin/directory_linux.cc
+++ b/runtime/bin/directory_linux.cc
@@ -9,6 +9,7 @@
 
 #include <dirent.h>  // NOLINT
 #include <errno.h>  // NOLINT
+#include <stdlib.h>  // NOLINT
 #include <string.h>  // NOLINT
 #include <sys/param.h>  // NOLINT
 #include <sys/stat.h>  // NOLINT
@@ -372,18 +373,27 @@
 }
 
 
-char* Directory::CreateTemp(const char* const_template) {
+char* Directory::CreateTemp(const char* const_template, bool system) {
   // Returns a new, unused directory name, modifying the contents of
   // dir_template.  Creates the directory with the permissions specified
   // by the process umask.
   // The return value must be freed by the caller.
   PathBuffer path;
-  path.Add(const_template);
-  if (path.length() == 0) {
-    path.Add("/tmp/temp_dir1_");
-  } else if ((path.AsString())[path.length() - 1] == '/') {
-    path.Add("temp_dir_");
+  if (system) {
+    const char* temp_dir = getenv("TMPDIR");
+    if (temp_dir == NULL) {
+      temp_dir = getenv("TMP");
+    }
+    if (temp_dir != NULL) {
+      path.Add(temp_dir);
+      if (temp_dir[strlen(temp_dir) - 1] != '/') {
+        path.Add("/");
+      }
+    } else {
+      path.Add("/tmp/");
+    }
   }
+  path.Add(const_template);
   if (!path.Add("XXXXXX")) {
     // Pattern has overflowed.
     return NULL;
diff --git a/runtime/bin/directory_macos.cc b/runtime/bin/directory_macos.cc
index 08232d5..5757a9c 100644
--- a/runtime/bin/directory_macos.cc
+++ b/runtime/bin/directory_macos.cc
@@ -361,18 +361,27 @@
 }
 
 
-char* Directory::CreateTemp(const char* const_template) {
+char* Directory::CreateTemp(const char* const_template, bool system) {
   // Returns a new, unused directory name, modifying the contents of
   // dir_template.  Creates the directory with the permissions specified
   // by the process umask.
   // The return value must be freed by the caller.
   PathBuffer path;
-  path.Add(const_template);
-  if (path.length() == 0) {
-    path.Add("/tmp/temp_dir1_");
-  } else if ((path.AsString())[path.length() - 1] == '/') {
-    path.Add("temp_dir_");
+  if (system) {
+    const char* temp_dir = getenv("TMPDIR");
+    if (temp_dir == NULL) {
+      temp_dir = getenv("TMP");
+    }
+    if (temp_dir != NULL) {
+      path.Add(temp_dir);
+      if (temp_dir[strlen(temp_dir) - 1] != '/') {
+        path.Add("/");
+      }
+    } else {
+      path.Add("/tmp/");
+    }
   }
+  path.Add(const_template);
   if (!path.Add("XXXXXX")) {
     // Pattern has overflowed.
     return NULL;
diff --git a/runtime/bin/directory_patch.dart b/runtime/bin/directory_patch.dart
index da4e014..f5961b9 100644
--- a/runtime/bin/directory_patch.dart
+++ b/runtime/bin/directory_patch.dart
@@ -5,7 +5,8 @@
 patch class _Directory {
   /* patch */ static _current() native "Directory_Current";
   /* patch */ static _setCurrent(path) native "Directory_SetCurrent";
-  /* patch */ static _createTemp(String template) native "Directory_CreateTemp";
+  /* patch */ static _createTemp(String template, bool system)
+      native "Directory_CreateTemp";
   /* patch */ static int _exists(String path) native "Directory_Exists";
   /* patch */ static _create(String path) native "Directory_Create";
   /* patch */ static _deleteNative(String path, bool recursive)
diff --git a/runtime/bin/directory_win.cc b/runtime/bin/directory_win.cc
index f5f77bd..c72f4ef 100644
--- a/runtime/bin/directory_win.cc
+++ b/runtime/bin/directory_win.cc
@@ -383,30 +383,26 @@
 }
 
 
-char* Directory::CreateTemp(const char* const_template) {
+char* Directory::CreateTemp(const char* const_template, bool system) {
   // Returns a new, unused directory name, modifying the contents of
   // dir_template.  Creates this directory, with a default security
   // descriptor inherited from its parent directory.
   // The return value must be freed by the caller.
   PathBuffer path;
-  if (0 == strncmp(const_template, "", 1)) {
+  if (system) {
     path.Reset(GetTempPathW(MAX_PATH, path.AsStringW()));
     if (path.length() == 0) {
       return NULL;
     }
-  } else {
-    const wchar_t* system_template = StringUtils::Utf8ToWide(const_template);
-    path.AddW(system_template);
-    free(const_cast<wchar_t*>(system_template));
   }
-  // Length of tempdir-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 44.
-  if (path.length() > MAX_PATH - 44) {
+  const wchar_t* system_template = StringUtils::Utf8ToWide(const_template);
+  path.AddW(system_template);
+  free(const_cast<wchar_t*>(system_template));
+
+  // Length of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 36.
+  if (path.length() > MAX_PATH - 36) {
     return NULL;
   }
-  if ((path.AsStringW())[path.length() - 1] == L'\\') {
-    // No base name for the directory - use "tempdir".
-    path.AddW(L"tempdir");
-  }
 
   UUID uuid;
   RPC_STATUS status = UuidCreateSequential(&uuid);
@@ -419,7 +415,6 @@
     return NULL;
   }
 
-  path.AddW(L"-");
   // RPC_WSTR is an unsigned short*, so we cast to wchar_t*.
   path.AddW(reinterpret_cast<wchar_t*>(uuid_string));
   RpcStringFreeW(&uuid_string);
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 59b2207..51e98ac 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -7,7 +7,6 @@
 
 #include "bin/eventhandler.h"
 
-#include <process.h>  // NOLINT
 #include <winsock2.h>  // NOLINT
 #include <ws2tcpip.h>  // NOLINT
 #include <mswsock.h>  // NOLINT
@@ -19,7 +18,7 @@
 #include "bin/log.h"
 #include "bin/socket.h"
 #include "bin/utils.h"
-#include "platform/thread.h"
+#include "vm/thread.h"
 
 
 namespace dart {
@@ -107,7 +106,6 @@
       pending_read_(NULL),
       pending_write_(NULL),
       last_error_(NOERROR),
-      thread_wrote_(0),
       flags_(0) {
   InitializeCriticalSection(&cs_);
 }
@@ -123,7 +121,6 @@
       pending_read_(NULL),
       pending_write_(NULL),
       last_error_(NOERROR),
-      thread_wrote_(0),
       flags_(0) {
   InitializeCriticalSection(&cs_);
 }
@@ -211,10 +208,9 @@
 }
 
 
-static unsigned int __stdcall ReadFileThread(void* args) {
+static void ReadFileThread(uword args) {
   Handle* handle = reinterpret_cast<Handle*>(args);
   handle->ReadSyncCompleteAsync();
-  return 0;
 }
 
 
@@ -273,11 +269,10 @@
   } else {
     // Completing asynchronously through thread.
     pending_read_ = buffer;
-    uint32_t tid;
-    uintptr_t thread_handle =
-        _beginthreadex(NULL, 32 * 1024, ReadFileThread, this, 0, &tid);
-    if (thread_handle == -1) {
-      FATAL("Failed to start read file thread");
+    int result = dart::Thread::Start(ReadFileThread,
+                                     reinterpret_cast<uword>(this));
+    if (result != 0) {
+      FATAL1("Failed to start read file thread %d", result);
     }
     return true;
   }
@@ -333,18 +328,6 @@
 }
 
 
-void FileHandle::DoClose() {
-  if (handle_ == GetStdHandle(STD_OUTPUT_HANDLE)) {
-    int fd = _open("NUL", _O_WRONLY);
-    ASSERT(fd >= 0);
-    _dup2(fd, _fileno(stdout));
-    close(fd);
-  } else {
-    Handle::DoClose();
-  }
-}
-
-
 void DirectoryWatchHandle::EnsureInitialized(
     EventHandlerImplementation* event_handler) {
   ScopedLock lock(this);
@@ -560,14 +543,46 @@
 }
 
 
-static unsigned int __stdcall WriteFileThread(void* args) {
-  Handle* handle = reinterpret_cast<Handle*>(args);
-  handle->WriteSyncCompleteAsync();
-  return 0;
+int Handle::Write(const void* buffer, int num_bytes) {
+  ScopedLock lock(this);
+  if (pending_write_ != NULL) return 0;
+  if (num_bytes > kBufferSize) num_bytes = kBufferSize;
+  ASSERT(SupportsOverlappedIO());
+  if (completion_port_ == INVALID_HANDLE_VALUE) return 0;
+  pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes);
+  pending_write_->Write(buffer, num_bytes);
+  if (!IssueWrite()) return -1;
+  return num_bytes;
 }
 
 
-void Handle::WriteSyncCompleteAsync() {
+static void WriteFileThread(uword args) {
+  StdHandle* handle = reinterpret_cast<StdHandle*>(args);
+  handle->RunWriteLoop();
+}
+
+
+void StdHandle::RunWriteLoop() {
+  write_monitor_->Enter();
+  write_thread_running_ = true;
+  // Notify we have started.
+  write_monitor_->Notify();
+
+  while (write_thread_running_) {
+    write_monitor_->Wait(Monitor::kNoTimeout);
+    if (pending_write_ != NULL) {
+      // We woke up and had a pending write. Execute it.
+      WriteSyncCompleteAsync();
+    }
+  }
+
+  write_thread_exists_ = false;
+  write_monitor_->Notify();
+  write_monitor_->Exit();
+}
+
+
+void StdHandle::WriteSyncCompleteAsync() {
   ASSERT(pending_write_ != NULL);
 
   DWORD bytes_written = -1;
@@ -593,39 +608,57 @@
   }
 }
 
-
-int Handle::Write(const void* buffer, int num_bytes) {
+int StdHandle::Write(const void* buffer, int num_bytes) {
   ScopedLock lock(this);
   if (pending_write_ != NULL) return 0;
   if (num_bytes > kBufferSize) num_bytes = kBufferSize;
-  if (SupportsOverlappedIO()) {
-    if (completion_port_ == INVALID_HANDLE_VALUE) return 0;
-    pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes);
-    pending_write_->Write(buffer, num_bytes);
-    if (!IssueWrite()) return -1;
+  // In the case of stdout and stderr, OverlappedIO is not supported.
+  // Here we'll instead use a thread, to make it async.
+  // This code is actually never exposed to the user, as stdout and stderr is
+  // not available as a RawSocket, but only wrapped in a Socket.
+  // Note that we return '0', unless a thread have already completed a write.
+  MonitorLocker locker(write_monitor_);
+  if (thread_wrote_ > 0) {
+    if (num_bytes > thread_wrote_) num_bytes = thread_wrote_;
+    thread_wrote_ -= num_bytes;
     return num_bytes;
+  }
+  if (!write_thread_exists_) {
+    write_thread_exists_ = true;
+    int result = dart::Thread::Start(WriteFileThread,
+                                     reinterpret_cast<uword>(this));
+    if (result != 0) {
+      FATAL1("Failed to start write file thread %d", result);
+    }
+    while (!write_thread_running_) {
+      // Wait until we the thread is running.
+      locker.Wait(Monitor::kNoTimeout);
+    }
+  }
+  // Create buffer and notify thread about the new handle.
+  pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes);
+  pending_write_->Write(buffer, num_bytes);
+  locker.Notify();
+  return 0;
+}
+
+
+void StdHandle::DoClose() {
+  MonitorLocker locker(write_monitor_);
+  if (write_thread_exists_) {
+    write_thread_running_ = false;
+    locker.Notify();
+    while (write_thread_exists_) {
+      locker.Wait(Monitor::kNoTimeout);
+    }
+  }
+  if (handle_ == GetStdHandle(STD_OUTPUT_HANDLE)) {
+    int fd = _open("NUL", _O_WRONLY);
+    ASSERT(fd >= 0);
+    _dup2(fd, _fileno(stdout));
+    close(fd);
   } else {
-    // In the case of stdout and stderr, OverlappedIO is not supported.
-    // Here we'll instead spawn a new thread for each write, to make it async.
-    // This code is actually never exposed to the user, as stdout and stderr is
-    // not available as a RawSocket, but only wrapped in a Socket.
-    // Note that we return '0', unless a thread have already completed a write.
-    // TODO(ajohnsen): Don't spawn a new thread per write. Issue 13541.
-    if (thread_wrote_ > 0) {
-      if (num_bytes > thread_wrote_) num_bytes = thread_wrote_;
-      thread_wrote_ -= num_bytes;
-      return num_bytes;
-    }
-    pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes);
-    pending_write_->Write(buffer, num_bytes);
-    // Completing asynchronously through thread.
-    uint32_t tid;
-    uintptr_t thread_handle =
-        _beginthreadex(NULL, 32 * 1024, WriteFileThread, this, 0, &tid);
-    if (thread_handle == -1) {
-      FATAL("Failed to start write file thread");
-    }
-    return 0;
+    Handle::DoClose();
   }
 }
 
diff --git a/runtime/bin/eventhandler_win.h b/runtime/bin/eventhandler_win.h
index 945277b..43562cd 100644
--- a/runtime/bin/eventhandler_win.h
+++ b/runtime/bin/eventhandler_win.h
@@ -13,6 +13,7 @@
 #include <mswsock.h>
 
 #include "bin/builtin.h"
+#include "platform/thread.h"
 
 
 namespace dart {
@@ -132,6 +133,7 @@
  public:
   enum Type {
     kFile,
+    kStd,
     kDirectoryWatch,
     kClientSocket,
     kListenSocket
@@ -156,7 +158,7 @@
   // Socket interface exposing normal socket operations.
   int Available();
   int Read(void* buffer, int num_bytes);
-  int Write(const void* buffer, int num_bytes);
+  virtual int Write(const void* buffer, int num_bytes);
 
   // Internal interface used by the event handler.
   virtual bool IssueRead();
@@ -211,7 +213,6 @@
   }
 
   void ReadSyncCompleteAsync();
-  void WriteSyncCompleteAsync();
 
   DWORD last_error() { return last_error_; }
   void set_last_error(DWORD last_error) { last_error_ = last_error; }
@@ -242,7 +243,6 @@
   OverlappedBuffer* pending_write_;  // Buffer for pending write
 
   DWORD last_error_;
-  DWORD thread_wrote_;
 
  private:
   int flags_;
@@ -259,7 +259,35 @@
 
   virtual void EnsureInitialized(EventHandlerImplementation* event_handler);
   virtual bool IsClosed();
+};
+
+
+class StdHandle : public FileHandle {
+ public:
+  explicit StdHandle(HANDLE handle)
+      : FileHandle(handle),
+        thread_wrote_(0),
+        write_thread_exists_(false),
+        write_thread_running_(false),
+        write_monitor_(new Monitor()) {
+    type_ = kStd;
+  }
+
+  ~StdHandle() {
+    delete write_monitor_;
+  }
+
   virtual void DoClose();
+  virtual int Write(const void* buffer, int num_bytes);
+
+  void WriteSyncCompleteAsync();
+  void RunWriteLoop();
+
+ private:
+  DWORD thread_wrote_;
+  bool write_thread_exists_;
+  bool write_thread_running_;
+  dart::Monitor* write_monitor_;
 };
 
 
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 6eec87a..41efb4c 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -60,35 +60,6 @@
     kOther = 4
   };
 
-  enum FileRequest {
-    kExistsRequest = 0,
-    kCreateRequest = 1,
-    kDeleteRequest = 2,
-    kRenameRequest = 3,
-    kOpenRequest = 4,
-    kResolveSymbolicLinksRequest = 5,
-    kCloseRequest = 6,
-    kPositionRequest = 7,
-    kSetPositionRequest = 8,
-    kTruncateRequest = 9,
-    kLengthRequest = 10,
-    kLengthFromPathRequest = 11,
-    kLastModifiedRequest = 12,
-    kFlushRequest = 13,
-    kReadByteRequest = 14,
-    kWriteByteRequest = 15,
-    kReadRequest = 16,
-    kReadIntoRequest = 17,
-    kWriteFromRequest = 18,
-    kCreateLinkRequest = 19,
-    kDeleteLinkRequest = 20,
-    kRenameLinkRequest = 21,
-    kLinkTargetRequest = 22,
-    kTypeRequest = 23,
-    kIdenticalRequest = 24,
-    kStatRequest = 25
-  };
-
   enum FileStat {
     // These match the constants in FileStat in file_system_entity.dart.
     kType = 0,
diff --git a/runtime/bin/file_system_watcher_win.cc b/runtime/bin/file_system_watcher_win.cc
index 014d861..e08c28d 100644
--- a/runtime/bin/file_system_watcher_win.cc
+++ b/runtime/bin/file_system_watcher_win.cc
@@ -49,8 +49,13 @@
   }
   if (events & kModifyContent) list_events |= FILE_NOTIFY_CHANGE_LAST_WRITE;
 
-  return reinterpret_cast<intptr_t>(
-      new DirectoryWatchHandle(dir, list_events, recursive));
+  DirectoryWatchHandle* handle =
+      new DirectoryWatchHandle(dir, list_events, recursive);
+  // Issue a read directly, to be sure events are tracked from now on. This is
+  // okay, since in Dart, we create the socket and start reading immidiately.
+  handle->EnsureInitialized(EventHandler::delegate());
+  handle->IssueRead();
+  return reinterpret_cast<intptr_t>(handle);
 }
 
 
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 0612f15..9f70743 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -143,8 +143,8 @@
 static void WriteSnapshotFile(const uint8_t* buffer, const intptr_t size) {
   File* file = File::Open(snapshot_filename, File::kWriteTruncate);
   ASSERT(file != NULL);
-  for (intptr_t i = 0; i < size; i++) {
-    file->WriteByte(buffer[i]);
+  if (!file->WriteFully(buffer, size)) {
+    Log::PrintErr("Error: Failed to write full snapshot.\n\n");
   }
   delete file;
 }
diff --git a/runtime/bin/io_service.h b/runtime/bin/io_service.h
index 0559039..8c1ba9f 100644
--- a/runtime/bin/io_service.h
+++ b/runtime/bin/io_service.h
@@ -12,6 +12,7 @@
 namespace dart {
 namespace bin {
 
+// This list must be kept in sync with the list in sdk/lib/io/io_service.dart
 #define IO_SERVICE_REQUEST_LIST(V)                                             \
   V(File, Exists, 0)                                                           \
   V(File, Create, 1)                                                           \
@@ -46,11 +47,12 @@
   V(Directory, Delete, 30)                                                     \
   V(Directory, Exists, 31)                                                     \
   V(Directory, CreateTemp, 32)                                                 \
-  V(Directory, ListStart, 33)                                                  \
-  V(Directory, ListNext, 34)                                                   \
-  V(Directory, ListStop, 35)                                                   \
-  V(Directory, Rename, 36)                                                     \
-  V(SSLFilter, ProcessFilter, 37)
+  V(Directory, CreateSystemTemp, 33)                                           \
+  V(Directory, ListStart, 34)                                                  \
+  V(Directory, ListNext, 35)                                                   \
+  V(Directory, ListStop, 36)                                                   \
+  V(Directory, Rename, 37)                                                     \
+  V(SSLFilter, ProcessFilter, 38)
 
 #define DECLARE_REQUEST(type, method, id)                                      \
   k##type##method##Request = id,
@@ -68,4 +70,3 @@
 }  // namespace dart
 
 #endif  // BIN_IO_SERVICE_H_
-
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index ca723ae3..16be960 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -62,6 +62,9 @@
     return argv_;
   }
 
+  static void PrintBlocking(FILE* file, const char* format, ...)
+      PRINTF_ATTRIBUTE(2, 3);
+
  private:
   static const char* executable_name_;
   static const char* package_root_;
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index dfa2e27..445ea01 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -11,6 +11,8 @@
 #include <string.h>  // NOLINT
 #include <unistd.h>  // NOLINT
 
+#include "bin/fdutils.h"
+
 
 namespace dart {
 namespace bin {
@@ -64,6 +66,18 @@
   delete[] env;
 }
 
+
+void Platform::PrintBlocking(FILE* file, const char* format, ...) {
+  int fd = fileno(file);
+  FDUtils::SetBlocking(fd);
+  va_list args;
+  va_start(args, format);
+  vfprintf(file, format, args);
+  fflush(file);
+  va_end(args);
+  FDUtils::SetNonBlocking(fd);
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index af557af..80aa0af 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -11,6 +11,8 @@
 #include <string.h>  // NOLINT
 #include <unistd.h>  // NOLINT
 
+#include "bin/fdutils.h"
+
 
 namespace dart {
 namespace bin {
@@ -64,6 +66,18 @@
   delete[] env;
 }
 
+
+void Platform::PrintBlocking(FILE* file, const char* format, ...) {
+  int fd = fileno(file);
+  FDUtils::SetBlocking(fd);
+  va_list args;
+  va_start(args, format);
+  vfprintf(file, format, args);
+  fflush(file);
+  va_end(args);
+  FDUtils::SetNonBlocking(fd);
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 0576c34..5af6c5a 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -12,6 +12,8 @@
 #include <string.h>  // NOLINT
 #include <unistd.h>  // NOLINT
 
+#include "bin/fdutils.h"
+
 
 namespace dart {
 namespace bin {
@@ -68,6 +70,18 @@
   delete[] env;
 }
 
+
+void Platform::PrintBlocking(FILE* file, const char* format, ...) {
+  int fd = fileno(file);
+  FDUtils::SetBlocking(fd);
+  va_list args;
+  va_start(args, format);
+  vfprintf(file, format, args);
+  fflush(file);
+  va_end(args);
+  FDUtils::SetNonBlocking(fd);
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc
index 85b6694..cd0f0f2 100644
--- a/runtime/bin/platform_win.cc
+++ b/runtime/bin/platform_win.cc
@@ -64,6 +64,16 @@
   delete[] env;
 }
 
+
+void Platform::PrintBlocking(FILE* file, const char* format, ...) {
+  // No need to set blocking, as it's always blocking on Windows.
+  va_list args;
+  va_start(args, format);
+  vfprintf(file, format, args);
+  fflush(file);
+  va_end(args);
+}
+
 }  // namespace bin
 }  // namespace dart
 
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index d6f9b0d..63fc5ef 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -52,7 +52,7 @@
     ADDRESS_LAST = ADDRESS_ANY_IP_V6,
   };
 
-  explicit SocketAddress(struct sockaddr* sockaddr);
+  explicit SocketAddress(struct sockaddr* sa);
 
   ~SocketAddress() {}
 
@@ -101,9 +101,9 @@
 
 class InterfaceSocketAddress {
  public:
-  explicit InterfaceSocketAddress(struct sockaddr* sockaddr,
+  explicit InterfaceSocketAddress(struct sockaddr* sa,
                                   const char* interface_name)
-      : socket_address_(new SocketAddress(sockaddr)),
+      : socket_address_(new SocketAddress(sa)),
         interface_name_(interface_name) {}
 
   ~InterfaceSocketAddress() {
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc
index 18b2bd8..38c1c7f 100644
--- a/runtime/bin/socket_android.cc
+++ b/runtime/bin/socket_android.cc
@@ -22,26 +22,19 @@
 namespace dart {
 namespace bin {
 
-SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
+SocketAddress::SocketAddress(struct sockaddr* sa) {
   ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
-  RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
-  const char* result;
-  if (sockaddr->sa_family == AF_INET) {
-    result = inet_ntop(sockaddr->sa_family,
-                       &raw->in.sin_addr,
-                       as_string_,
-                       INET_ADDRSTRLEN);
-  } else {
-    ASSERT(sockaddr->sa_family == AF_INET6);
-    result = inet_ntop(sockaddr->sa_family,
-                       &raw->in6.sin6_addr,
-                       as_string_,
-                       INET6_ADDRSTRLEN);
+  socklen_t salen = GetAddrLength(reinterpret_cast<RawAddr*>(sa));
+  if (TEMP_FAILURE_RETRY(getnameinfo(sa,
+                                     salen,
+                                     as_string_,
+                                     INET6_ADDRSTRLEN,
+                                     NULL,
+                                     0,
+                                     NI_NUMERICHOST)) != 0) {
+    as_string_[0] = 0;
   }
-  if (result == NULL) as_string_[0] = 0;
-  memmove(reinterpret_cast<void *>(&addr_),
-          sockaddr,
-          GetAddrLength(raw));
+  memmove(reinterpret_cast<void *>(&addr_), sa, salen);
 }
 
 
@@ -157,20 +150,17 @@
     Log::PrintErr("Error getpeername: %s\n", error_message);
     return false;
   }
-  const void* src;
-  if (raw.ss.ss_family == AF_INET6) {
-    src = reinterpret_cast<const void*>(&raw.in6.sin6_addr);
-  } else {
-    src = reinterpret_cast<const void*>(&raw.in.sin_addr);
-  }
-  if (inet_ntop(raw.ss.ss_family,
-                src,
-                host,
-                INET_ADDRSTRLEN) == NULL) {
+  if (TEMP_FAILURE_RETRY(getnameinfo(&raw.addr,
+                                     size,
+                                     host,
+                                     INET6_ADDRSTRLEN,
+                                     NULL,
+                                     0,
+                                     NI_NUMERICHOST)) != 0) {
     const int kBufferSize = 1024;
     char error_message[kBufferSize];
     strerror_r(errno, error_message, kBufferSize);
-    Log::PrintErr("Error inet_ntop: %s\n", error_message);
+    Log::PrintErr("Error getnameinfo: %s\n", error_message);
     return false;
   }
   *port = SocketAddress::GetAddrPort(&raw);
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
index 24e688d..b9431e1 100644
--- a/runtime/bin/socket_linux.cc
+++ b/runtime/bin/socket_linux.cc
@@ -23,26 +23,19 @@
 namespace dart {
 namespace bin {
 
-SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
+SocketAddress::SocketAddress(struct sockaddr* sa) {
   ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
-  RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
-  const char* result;
-  if (sockaddr->sa_family == AF_INET) {
-    result = inet_ntop(sockaddr->sa_family,
-                       &raw->in.sin_addr,
-                       as_string_,
-                       INET_ADDRSTRLEN);
-  } else {
-    ASSERT(sockaddr->sa_family == AF_INET6);
-    result = inet_ntop(sockaddr->sa_family,
-                       &raw->in6.sin6_addr,
-                       as_string_,
-                       INET6_ADDRSTRLEN);
+  socklen_t salen = GetAddrLength(reinterpret_cast<RawAddr*>(sa));
+  if (TEMP_FAILURE_RETRY(getnameinfo(sa,
+                                     salen,
+                                     as_string_,
+                                     INET6_ADDRSTRLEN,
+                                     NULL,
+                                     0,
+                                     NI_NUMERICHOST)) != 0) {
+    as_string_[0] = 0;
   }
-  if (result == NULL) as_string_[0] = 0;
-  memmove(reinterpret_cast<void *>(&addr_),
-          sockaddr,
-          GetAddrLength(raw));
+  memmove(reinterpret_cast<void *>(&addr_), sa, salen);
 }
 
 
@@ -158,19 +151,16 @@
                   strerror_r(errno, error_buf, kBufferSize));
     return false;
   }
-  const void* src;
-  if (raw.ss.ss_family == AF_INET6) {
-    src = reinterpret_cast<const void*>(&raw.in6.sin6_addr);
-  } else {
-    src = reinterpret_cast<const void*>(&raw.in.sin_addr);
-  }
-  if (inet_ntop(raw.ss.ss_family,
-                src,
-                host,
-                INET_ADDRSTRLEN) == NULL) {
+  if (TEMP_FAILURE_RETRY(getnameinfo(&raw.addr,
+                                     size,
+                                     host,
+                                     INET6_ADDRSTRLEN,
+                                     NULL,
+                                     0,
+                                     NI_NUMERICHOST)) != 0) {
     const int kBufferSize = 1024;
     char error_buf[kBufferSize];
-    Log::PrintErr("Error inet_ntop: %s\n",
+    Log::PrintErr("Error getnameinfo: %s\n",
                   strerror_r(errno, error_buf, kBufferSize));
     return false;
   }
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index 2b6138f..be7beca 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -23,26 +23,19 @@
 namespace dart {
 namespace bin {
 
-SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
+SocketAddress::SocketAddress(struct sockaddr* sa) {
   ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
-  RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
-  const char* result;
-  if (sockaddr->sa_family == AF_INET) {
-    result = inet_ntop(sockaddr->sa_family,
-                       &raw->in.sin_addr,
-                       as_string_,
-                       INET_ADDRSTRLEN);
-  } else {
-    ASSERT(sockaddr->sa_family == AF_INET6);
-    result = inet_ntop(sockaddr->sa_family,
-                       &raw->in6.sin6_addr,
-                       as_string_,
-                       INET6_ADDRSTRLEN);
+  socklen_t salen = GetAddrLength(reinterpret_cast<RawAddr*>(sa));
+  if (TEMP_FAILURE_RETRY(getnameinfo(sa,
+                                     salen,
+                                     as_string_,
+                                     INET6_ADDRSTRLEN,
+                                     NULL,
+                                     0,
+                                     NI_NUMERICHOST)) != 0) {
+    as_string_[0] = 0;
   }
-  if (result == NULL) as_string_[0] = 0;
-  memmove(reinterpret_cast<void *>(&addr_),
-          sockaddr,
-          GetAddrLength(raw));
+  memmove(reinterpret_cast<void *>(&addr_), sa, salen);
 }
 
 
@@ -158,20 +151,17 @@
     Log::PrintErr("Error getpeername: %s\n", error_message);
     return false;
   }
-  const void* src;
-  if (raw.ss.ss_family == AF_INET6) {
-    src = reinterpret_cast<const void*>(&raw.in6.sin6_addr);
-  } else {
-    src = reinterpret_cast<const void*>(&raw.in.sin_addr);
-  }
-  if (inet_ntop(raw.ss.ss_family,
-                src,
-                host,
-                INET_ADDRSTRLEN) == NULL) {
+  if (TEMP_FAILURE_RETRY(getnameinfo(&raw.addr,
+                                     size,
+                                     host,
+                                     INET6_ADDRSTRLEN,
+                                     NULL,
+                                     0,
+                                     NI_NUMERICHOST)) != 0) {
     const int kBufferSize = 1024;
     char error_message[kBufferSize];
     strerror_r(errno, error_message, kBufferSize);
-    Log::PrintErr("Error inet_ntop: %s\n", error_message);
+    Log::PrintErr("Error getnameinfo: %s\n", error_message);
     return false;
   }
   *port = SocketAddress::GetAddrPort(&raw);
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 0042aed..4fffbf7 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -484,7 +484,9 @@
           continue;
         }
         if (i == ERROR_EVENT) {
-          reportError(nativeGetError(), "");
+          if (!isClosing) {
+            reportError(nativeGetError(), "");
+          }
         } else if (!isClosed) {
           // If the connection is closed right after it's accepted, there's a
           // chance the close-handler is not set.
@@ -711,6 +713,8 @@
 
   int get port => _socket.port;
 
+  InternetAddress get address => _socket.address;
+
   Future close() => _socket.close().then((_) => this);
 
   void _pause() {
@@ -921,6 +925,8 @@
 
   int get port => _socket.port;
 
+  InternetAddress get address => _socket.address;
+
   Future close() => _socket.close().then((_) => this);
 }
 
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index 87a0b30..a5d55a9 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -198,11 +198,11 @@
   if (handle == INVALID_HANDLE_VALUE) {
     return -1;
   }
-  FileHandle* file_handle = new FileHandle(handle);
-  if (file_handle == NULL) return -1;
-  file_handle->MarkDoesNotSupportOverlappedIO();
-  file_handle->EnsureInitialized(EventHandler::delegate());
-  return reinterpret_cast<intptr_t>(file_handle);
+  StdHandle* std_handle = new StdHandle(handle);
+  if (std_handle == NULL) return -1;
+  std_handle->MarkDoesNotSupportOverlappedIO();
+  std_handle->EnsureInitialized(EventHandler::delegate());
+  return reinterpret_cast<intptr_t>(std_handle);
 }
 
 
diff --git a/runtime/dart-runtime.gyp b/runtime/dart-runtime.gyp
index 7c4f4c4..f89950a 100644
--- a/runtime/dart-runtime.gyp
+++ b/runtime/dart-runtime.gyp
@@ -15,20 +15,9 @@
     'version_in_cc_file': 'vm/version_in.cc',
     'version_cc_file': '<(gen_source_dir)/version.cc',
 
-    # Disable the OpenGLUI embedder by default on desktop OSes.  Note,
-    # to build this on the desktop, you need GLUT installed.
-    'enable_openglui%': 0,
     'libdart_deps': ['libdart_lib_withcore', 'libdart_lib', 'libdart_vm',
                      'libjscre', 'libdouble_conversion',],
   },
-  'conditions': [
-    ['OS=="android" or enable_openglui==1', {
-        'includes': [
-          'embedders/openglui/openglui_embedder.gypi',
-        ],
-      },
-    ],
-  ],
   'targets': [
     {
       'target_name': 'libdart',
diff --git a/runtime/embedders/openglui/android/android_graphics_handler.cc b/runtime/embedders/openglui/android/android_graphics_handler.cc
deleted file mode 100644
index f2c0ea2..0000000
--- a/runtime/embedders/openglui/android/android_graphics_handler.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/android/android_graphics_handler.h"
-#include "embedders/openglui/common/log.h"
-
-AndroidGraphicsHandler::AndroidGraphicsHandler(android_app* application,
-                                               const char* resource_path)
-    : GraphicsHandler(resource_path),
-      application_(application),
-      display_(EGL_NO_DISPLAY),
-      surface_(EGL_NO_SURFACE),
-      context_(EGL_NO_CONTEXT) {
-}
-
-int32_t AndroidGraphicsHandler::Start() {
-  EGLint format, numConfigs;
-  EGLConfig config;
-  const EGLint attributes[] = {
-      EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-      EGL_NONE
-  };
-  static const EGLint ctx_attribs[] = {
-    EGL_CONTEXT_CLIENT_VERSION, 2,
-    EGL_NONE
-  };
-
-  display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-  if (display_ != EGL_NO_DISPLAY) {
-    LOGI("eglInitialize");
-    if (eglInitialize(display_, NULL, NULL)) {
-      LOGI("eglChooseConfig");
-      if (eglChooseConfig(display_, attributes, &config, 1, &numConfigs) &&
-          numConfigs > 0) {
-        LOGI("eglGetConfigAttrib returned %d configs\n", numConfigs);
-        if (eglGetConfigAttrib(display_, config,
-                               EGL_NATIVE_VISUAL_ID, &format)) {
-          ANativeWindow_setBuffersGeometry(application_->window, 0, 0, format);
-          surface_ = eglCreateWindowSurface(display_, config,
-                              (EGLNativeWindowType)application_->window, NULL);
-          if (surface_ != EGL_NO_SURFACE) {
-            LOGI("eglCreateContext");
-            context_ = eglCreateContext(display_, config, EGL_NO_CONTEXT,
-                                        ctx_attribs);
-            if (context_ != EGL_NO_CONTEXT) {
-              if (eglMakeCurrent(display_, surface_, surface_, context_) &&
-                  eglQuerySurface(display_, surface_, EGL_WIDTH, &width_) &&
-                  width_ > 0 &&
-                  eglQuerySurface(display_, surface_, EGL_HEIGHT, &height_) &&
-                  height_ > 0) {
-                LOGI("Got dimensions %d x %d\n", width_, height_);
-                SetViewport(0, 0, width_, height_);
-                LOGI("GL version %s\n", glGetString(GL_VERSION));
-                LOGI("GLSL version: %s\n",
-                    glGetString(GL_SHADING_LANGUAGE_VERSION));
-                return GraphicsHandler::Start();
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-  LOGE("Error starting graphics");
-  Stop();
-  return -1;
-}
-
-void AndroidGraphicsHandler::Stop() {
-  LOGI("Stopping graphics");
-  GraphicsHandler::Stop();
-  if (display_ != EGL_NO_DISPLAY) {
-    eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    if (context_ != EGL_NO_CONTEXT) {
-      eglDestroyContext(display_, context_);
-      context_ = EGL_NO_CONTEXT;
-    }
-    if (surface_ != EGL_NO_SURFACE) {
-      eglDestroySurface(display_, surface_);
-      surface_ = EGL_NO_SURFACE;
-    }
-    eglTerminate(display_);
-    display_ = EGL_NO_DISPLAY;
-  }
-}
-
diff --git a/runtime/embedders/openglui/android/android_graphics_handler.h b/runtime/embedders/openglui/android/android_graphics_handler.h
deleted file mode 100644
index c157d95..0000000
--- a/runtime/embedders/openglui/android/android_graphics_handler.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_ANDROID_ANDROID_GRAPHICS_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_ANDROID_ANDROID_GRAPHICS_HANDLER_H_
-
-#include <android_native_app_glue.h>
-#include "embedders/openglui/common/graphics_handler.h"
-
-class AndroidGraphicsHandler : public GraphicsHandler {
-  public:
-    AndroidGraphicsHandler(android_app* application,
-                           const char* resource_path);
-
-    int32_t Start();
-    void Stop();
-
-  private:
-    android_app* application_;
-    EGLDisplay display_;
-    EGLSurface surface_;
-    EGLContext context_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_ANDROID_ANDROID_GRAPHICS_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/android/android_input_handler.h b/runtime/embedders/openglui/android/android_input_handler.h
deleted file mode 100644
index 420e459..0000000
--- a/runtime/embedders/openglui/android/android_input_handler.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_ANDROID_ANDROID_INPUT_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_ANDROID_ANDROID_INPUT_HANDLER_H_
-
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/input_handler.h"
-
-class AndroidInputHandler : public InputHandler {
-  public:
-    AndroidInputHandler(VMGlue* vm_glue,
-                        GraphicsHandler* graphics_handler)
-      : InputHandler(vm_glue),
-        graphics_handler_(graphics_handler) {
-    }
-
-  public:
-    int32_t Start() {
-      if (graphics_handler_->width() == 0 ||
-          graphics_handler_->height() == 0) {
-        return -1;
-      }
-      return 0;
-    }
-
-    void Stop() {
-    }
-
-  private:
-    GraphicsHandler* graphics_handler_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_ANDROID_ANDROID_INPUT_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/android/android_log.h b/runtime/embedders/openglui/android/android_log.h
deleted file mode 100644
index ff82d0b..0000000
--- a/runtime/embedders/openglui/android/android_log.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_ANDROID_ANDROID_LOG_H_
-#define EMBEDDERS_OPENGLUI_ANDROID_ANDROID_LOG_H_
-
-#include <android/log.h>
-
-#define LOGX(LOG_LEVEL, ...) do { \
-    __android_log_print(LOG_LEVEL, "DartExt", __VA_ARGS__); \
-  } while (0)
-#define LOGI(...) LOGX(ANDROID_LOG_INFO, __VA_ARGS__)
-#define LOGE(...) LOGX(ANDROID_LOG_ERROR, __VA_ARGS__)
-
-#endif  // EMBEDDERS_OPENGLUI_ANDROID_ANDROID_LOG_H_
-
diff --git a/runtime/embedders/openglui/android/android_resource.h b/runtime/embedders/openglui/android/android_resource.h
deleted file mode 100644
index 85e0614..0000000
--- a/runtime/embedders/openglui/android/android_resource.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_ANDROID_ANDROID_RESOURCE_H_
-#define EMBEDDERS_OPENGLUI_ANDROID_ANDROID_RESOURCE_H_
-
-#include <android_native_app_glue.h>
-
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/resource.h"
-
-class AndroidResource : public Resource {
-  public:
-    AndroidResource(android_app* application, const char* path)
-        : Resource(path),
-          asset_manager_(application->activity->assetManager),
-          asset_(NULL) {
-    }
-
-    int32_t descriptor() {
-      if (Open() == 0) {
-        descriptor_ = AAsset_openFileDescriptor(asset_, &start_, &length_);
-        LOGI("%s has start %d, length %d, fd %d",
-             path_, static_cast<int>(start_), static_cast<int>(length_),
-             descriptor_);
-        return descriptor_;
-      }
-      return -1;
-    }
-
-    off_t length() {
-      if (length_ < 0) {
-        length_ = AAsset_getLength(asset_);
-      }
-      return length_;
-    }
-
-    int32_t Open() {
-      LOGI("Attempting to open asset %s", path_);
-      asset_ = AAssetManager_open(asset_manager_, path_, AASSET_MODE_UNKNOWN);
-      if (asset_ != NULL) {
-        return 0;
-      }
-      LOGE("Could not open asset %s", path_);
-      return -1;
-    }
-
-    void Close() {
-      if (asset_ != NULL) {
-        AAsset_close(asset_);
-        asset_ = NULL;
-      }
-    }
-
-    int32_t Read(void* buffer, size_t count) {
-      size_t actual = AAsset_read(asset_, buffer, count);
-      return (actual == count) ? 0 : -1;
-    }
-
-  private:
-    AAssetManager* asset_manager_;
-    AAsset* asset_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_ANDROID_ANDROID_RESOURCE_H_
-
diff --git a/runtime/embedders/openglui/android/android_sound_handler.cc b/runtime/embedders/openglui/android/android_sound_handler.cc
deleted file mode 100644
index de9e977..0000000
--- a/runtime/embedders/openglui/android/android_sound_handler.cc
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/android/android_sound_handler.h"
-
-#include "embedders/openglui/android/android_resource.h"
-#include "embedders/openglui/common/log.h"
-
-AndroidSoundHandler::AndroidSoundHandler(android_app* application)
-    : SoundHandler(),
-      application_(application),
-      engine_(NULL),
-      engine_if_(NULL),
-      output_mix_(NULL),
-      background_player_(NULL),
-      background_player_if_(NULL),
-      background_player_seek_if_(NULL),
-      sample_player_(NULL),
-      sample_player_if_(NULL),
-      sample_player_queue_(NULL) {
-}
-
-int32_t AndroidSoundHandler::Start() {
-  LOGI("Starting SoundService");
-
-  const SLInterfaceID k_engine_mix_IIDs[] = { SL_IID_ENGINE };
-  const SLboolean k_engine_mix_reqs[] = { SL_BOOLEAN_TRUE };
-  const SLInterfaceID k_output_mix_IIDs[] = {};
-  const SLboolean k_output_mix_reqs[] = {};
-  int32_t res = slCreateEngine(&engine_, 0, NULL, 1,
-                               k_engine_mix_IIDs, k_engine_mix_reqs);
-  if (res == SL_RESULT_SUCCESS) {
-    res = (*engine_)->Realize(engine_, SL_BOOLEAN_FALSE);
-    if (res == SL_RESULT_SUCCESS) {
-      res = (*engine_)->GetInterface(engine_, SL_IID_ENGINE, &engine_if_);
-      if (res == SL_RESULT_SUCCESS) {
-        res = (*engine_if_)->CreateOutputMix(engine_if_, &output_mix_, 0,
-                                  k_output_mix_IIDs, k_output_mix_reqs);
-        if (res == SL_RESULT_SUCCESS) {
-          res = (*output_mix_)->Realize(output_mix_, SL_BOOLEAN_FALSE);
-          if (res == SL_RESULT_SUCCESS) {
-            if (StartSamplePlayer() == 0) {
-              return 0;
-            }
-          }
-        }
-      }
-    }
-  }
-  LOGI("Failed to start SoundService");
-  Stop();
-  return -1;
-}
-
-void AndroidSoundHandler::Stop() {
-  LOGI("Stopping SoundService");
-  if (sample_player_ != NULL) {
-    LOGI("Destroying sample player");
-    (*sample_player_)->Destroy(sample_player_);
-    sample_player_ = NULL;
-    sample_player_if_ = NULL;
-    sample_player_queue_ = NULL;
-  }
-  samples_.clear();
-  if (output_mix_ != NULL) {
-    LOGI("Destroying output mix");
-    (*output_mix_)->Destroy(output_mix_);
-    output_mix_ = NULL;
-  }
-  if (engine_ != NULL) {
-    LOGI("Destroying engine");
-    (*engine_)->Destroy(engine_);
-    engine_ = NULL;
-    engine_if_ = NULL;
-  }
-}
-
-int32_t AndroidSoundHandler::SetBackgroundPlayerState(int state) {
-  if (background_player_if_ != NULL) {
-    SLuint32 state;
-    (*background_player_)->GetState(background_player_, &state);
-    if (state == SL_OBJECT_STATE_REALIZED) {
-      (*background_player_if_)->SetPlayState(background_player_if_,
-                                             state);
-      return 0;
-    }
-  }
-  return -1;
-}
-
-int32_t AndroidSoundHandler::Pause() {
-  return SetBackgroundPlayerState(SL_PLAYSTATE_PAUSED);
-}
-
-
-int32_t AndroidSoundHandler::Resume() {
-  return SetBackgroundPlayerState(SL_PLAYSTATE_PLAYING);
-}
-
-int32_t AndroidSoundHandler::CreateAudioPlayer(SLEngineItf engine_if,
-                                        const SLInterfaceID extra_if,
-                                        SLDataSource data_source,
-                                        SLDataSink data_sink,
-                                        SLObjectItf& player_out,
-                                        SLPlayItf& player_if_out) {
-  const SLuint32 SoundPlayerIIDCount = 2;
-  const SLInterfaceID SoundPlayerIIDs[] = { SL_IID_PLAY, extra_if };
-  const SLboolean SoundPlayerReqs[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
-  int32_t res = (*engine_if)->CreateAudioPlayer(engine_if,
-                                                &player_out,
-                                                &data_source,
-                                                &data_sink,
-                                                SoundPlayerIIDCount,
-                                                SoundPlayerIIDs,
-                                                SoundPlayerReqs);
-
-  if (res == SL_RESULT_SUCCESS) {
-    res = (*player_out)->Realize(player_out, SL_BOOLEAN_FALSE);
-    if (res == SL_RESULT_SUCCESS) {
-      res = (*player_out)->GetInterface(sample_player_,
-                                            SL_IID_PLAY,
-                                            &player_if_out);
-      if (res == SL_RESULT_SUCCESS) {
-        return 0;
-      }
-    }
-  }
-  return -1;
-}
-
-int32_t AndroidSoundHandler::PlayBackground(const char* path) {
-  LOGI("Creating audio player");
-
-  Resource resource(path);
-  int fd = resource.descriptor();
-  if (fd < 0) {
-    LOGI("Could not open file %s", path);
-    return -1;
-  }
-
-  SLDataLocator_AndroidFD data_locator_in = {
-      SL_DATALOCATOR_ANDROIDFD,
-      fd,
-      resource.start(),
-      resource.length()
-  };
-  SLDataFormat_MIME data_format = {
-      SL_DATAFORMAT_MIME,
-      NULL,
-      SL_CONTAINERTYPE_UNSPECIFIED
-  };
-  SLDataSource data_source = { &data_locator_in, &data_format };
-
-  resource.Close();
-
-  SLDataLocator_OutputMix data_locator_out =
-      { SL_DATALOCATOR_OUTPUTMIX, output_mix_ };
-  SLDataSink data_sink = { &data_locator_out, NULL };
-
-  int32_t res = CreateAudioPlayer(engine_if_,
-                                  SL_IID_SEEK,
-                                  data_source,
-                                  data_sink,
-                                  background_player_,
-                                  background_player_if_);
-
-  if (res != SL_RESULT_SUCCESS) {
-    LOGE("Couldn't create audio player");
-    return -1;
-  }
-
-  if ((*background_player_)->
-          GetInterface(background_player_, SL_IID_SEEK,
-                       &background_player_seek_if_) != SL_RESULT_SUCCESS) {
-    LOGE("Couldn't get seek interface");
-    return -1;
-  }
-  LOGI("Got seek interface");
-  if ((*background_player_seek_if_)->
-          SetLoop(background_player_seek_if_, SL_BOOLEAN_TRUE, 0,
-                  SL_TIME_UNKNOWN) != SL_RESULT_SUCCESS) {
-    LOGE("Couldn't set loop");
-    return -1;
-  }
-  LOGI("Set loop");
-  if ((*background_player_if_)->
-          SetPlayState(background_player_if_, SL_PLAYSTATE_PLAYING) !=
-          SL_RESULT_SUCCESS) {
-    LOGE("Couldn't start playing");
-    return -1;
-  }
-  LOGI("Started playing");
-  return 0;
-}
-
-void AndroidSoundHandler::StopBackground() {
-  if (Pause() == 0) {
-    (*background_player_)->Destroy(background_player_);
-    background_player_ = NULL;
-    background_player_if_ = NULL;
-    background_player_seek_if_ = NULL;
-  }
-}
-
-int32_t AndroidSoundHandler::StartSamplePlayer() {
-  SLDataLocator_AndroidSimpleBufferQueue data_locator_in = {
-    SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
-    1
-  };
-
-  SLDataFormat_PCM data_format= {
-    SL_DATAFORMAT_PCM,
-    1,
-    SL_SAMPLINGRATE_44_1,
-    SL_PCMSAMPLEFORMAT_FIXED_16,
-    SL_PCMSAMPLEFORMAT_FIXED_16,
-    SL_SPEAKER_FRONT_CENTER,
-    SL_BYTEORDER_LITTLEENDIAN
-  };
-
-  SLDataSource data_source = { &data_locator_in, &data_format };
-
-  SLDataLocator_OutputMix data_locator_out =
-      { SL_DATALOCATOR_OUTPUTMIX, output_mix_ };
-  SLDataSink data_sink = { &data_locator_out, NULL };
-
-  int32_t res = CreateAudioPlayer(engine_if_, SL_IID_BUFFERQUEUE,
-                                  data_source,
-                                  data_sink,
-                                  sample_player_, sample_player_if_);
-
-  if (res == SL_RESULT_SUCCESS) {
-    res = (*sample_player_)->GetInterface(sample_player_,
-                                          SL_IID_BUFFERQUEUE,
-                                          &sample_player_queue_);
-    if (res == SL_RESULT_SUCCESS) {
-      res = (*sample_player_if_)->SetPlayState(sample_player_if_,
-                                               SL_PLAYSTATE_PLAYING);
-      if (res == SL_RESULT_SUCCESS) {
-        return 0;
-      }
-    }
-  }
-  LOGE("Error while starting sample player");
-  return -1;
-}
-
-int32_t AndroidSoundHandler::PlaySample(const char* path) {
-  SLuint32 state;
-  (*sample_player_)->GetState(sample_player_, &state);
-  if (state != SL_OBJECT_STATE_REALIZED) {
-    LOGE("Sample player has not been realized");
-  } else {
-    Sample* sample = GetSample(path);
-    if (sample != NULL) {
-      int16_t* buffer = reinterpret_cast<int16_t*>(sample->buffer());
-      off_t len = sample->length();
-
-      // Remove any current sample.
-      int32_t res = (*sample_player_queue_)->Clear(sample_player_queue_);
-      if (res == SL_RESULT_SUCCESS) {
-        res = (*sample_player_queue_)->Enqueue(sample_player_queue_,
-                                               buffer, len);
-        if (res == SL_RESULT_SUCCESS) {
-          LOGE("Enqueued sample %s of length %d", path,
-            static_cast<int>(len));
-          return 0;
-        }
-        LOGE("Enqueueing sample failed");
-      }
-    }
-  }
-  return -1;
-}
-
-
diff --git a/runtime/embedders/openglui/android/android_sound_handler.h b/runtime/embedders/openglui/android/android_sound_handler.h
deleted file mode 100644
index e699a69..0000000
--- a/runtime/embedders/openglui/android/android_sound_handler.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_ANDROID_ANDROID_SOUND_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_ANDROID_ANDROID_SOUND_HANDLER_H_
-
-#include <android_native_app_glue.h>
-#include <SLES/OpenSLES.h>
-#include <SLES/OpenSLES_Android.h>
-#include <SLES/OpenSLES_AndroidConfiguration.h>
-#include <vector>
-
-#include "embedders/openglui/common/sample.h"
-#include "embedders/openglui/common/sound_handler.h"
-#include "embedders/openglui/common/types.h"
-
-class AndroidSoundHandler : public SoundHandler {
-  public:
-    explicit AndroidSoundHandler(android_app* application);
-    int32_t Start();
-    void Stop();
-    int32_t Pause();
-    int32_t Resume();
-
-    int32_t PlayBackground(const char* path);
-    void StopBackground();
-
-    int32_t PlaySample(const char* path);
-
-  private:
-    int32_t CreateAudioPlayer(SLEngineItf engine_if,
-                              const SLInterfaceID extra_if,
-                              SLDataSource data_source,
-                              SLDataSink data_sink,
-                              SLObjectItf& player_out,
-                              SLPlayItf& player_if_out);
-
-    int32_t SetBackgroundPlayerState(int state);
-    int32_t StartSamplePlayer();
-
-    android_app* application_;
-    SLObjectItf engine_;
-    SLEngineItf engine_if_;
-    SLObjectItf output_mix_;
-    SLObjectItf background_player_;
-    SLPlayItf background_player_if_;
-    SLSeekItf background_player_seek_if_;
-    SLObjectItf sample_player_;
-    SLPlayItf sample_player_if_;
-    SLBufferQueueItf sample_player_queue_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_ANDROID_ANDROID_SOUND_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/android/eventloop.cc b/runtime/embedders/openglui/android/eventloop.cc
deleted file mode 100644
index ed1645e..0000000
--- a/runtime/embedders/openglui/android/eventloop.cc
+++ /dev/null
@@ -1,464 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/android/eventloop.h"
-
-#include <time.h>
-#include "embedders/openglui/common/log.h"
-
-/*
- * The Android lifecycle events are:
- *
- * OnCreate: In NDK this is the call to android_main
- *
- * OnStart: technically, called to initiate the “visible” lifespan of the
- *     app; at any time between OnStart and OnStop, the app may be visible.
- *     We can either be OnResume’d or OnStop’ped from this state. Note that
- *     there is also an event for OnRestart, which is called before OnStart
- *     if the application is transitioning from OnStop to OnStart instead of
- *     being started from scratch.
- *
- * OnResume: technically, the start of the “foreground” lifespan of the app, 
- *     but this does not mean that the app is fully visible and should be 
- *     rendering – more on that later
- *
- * OnPause: the app is losing its foregrounded state; this is normally an 
- *     indication that something is fully covering the app. On versions of 
- *     Android before Honeycomb, once we returned from this callback, we 
- *     could be killed at any time with no further app code called. We can
- *     either be OnResume’d or OnStop’ped from this state. OnPause halts the 
- *     visible UI thread and so should be handled as quickly as possible.
- *
- * OnStop: the end of the current visible lifespan of the app – we may
- *     transition to On(Re)Start to become visible again, or to OnDestroy if
- *      we are shutting down entirely. Once we return from this callback, we
- *      can be killed at any time with no further app code called on any
- *      version of Android.
- *
- * OnDestroy: this can only be followed by the application being killed or
- *     restarted with OnCreate.
- *
- * The above events occur in fixed orders. The events below can occur at 
- * various times:
- *
- * OnGainedFocus: happens between OnResume and OnPause.
- * OnLostFocus:  may occur at arbitrary times, and may in fact not happen
- *     at all if the app is being destroyed. So OnPause and OnGainedFocus/
- *     OnLostFocus must be used together to determine the visible and
- *     interactable state of the app.
- *
- * OnCreateWindow: usually happens in the resumed state
- * OnDestroyWindow: can happen after OnPause or OnDestroy, so apps may
- *     need to handle shutting down EGL before their surfaces are
- *     destroyed.
- * OnConfigurationChanged: typically means the size has changed
- *
- * An application's EGL surface may only exist between the OnCreateWindow
- * and OnDestroyWindow callbacks.
- *
- * An application is "killable" after OnStop or OnDestroy (in earlier 
- * Android versions, after OnPause too). That means any critical state
- * or resources must be handled by any of these callbacks.
- *
- * These callbacks run on the main thread. If they block any event
- * processing for more than 5 seconds this will result in an ANR
- * (Application Not Responding message).
- *
- * On application launch, this sequence will occur:
- *
- * - OnCreate
- * - OnStart
- * - OnResume
- * - OnCreateWindow
- * - OnConfigurationChanged
- * - OnGainedFocus
- *
- * If the back button is pressed, and the app does not handle it,
- * Android will pop the app of the UI stack and destroy the application's
- * activity:
- *
- * - OnPause
- * - OnLostFocus
- * - OnDestroyWindow
- * - OnStop
- * - OnDestroy
- *
- * If the home button is pressed, the app is sent down in the UI stack.
- * The app's Activity still exists but may be killed at any time, and
- * it loses its rendering surface:
- *
- * - OnPause
- * - OnLostFocus
- * - OnDestroyWindow
- * - OnStop
- *
- * If the app is then restarted (without having been killed in between):
- *
- * - OnRestart
- * - OnStart
- * - OnResume
- * - OnCreateWindow
- * - OnConfigurationChanged
- * - OnGainedFocus
- *
- * If a status icon pop up is opened, the app is still visible and can render
- * but is not focused and cannot receive input:
- *
- * - OnLostFocus
- *
- * When the popup is dismissed, the app regains focus:
- *
- * - OnGainedFocus
- *
- * When the device is suspended (power button or screen saver), the application
- * will typically be paused and lose focus:
- *
- * - OnPause
- * - OnLostFocus (sometimes this will only come when the device is resumed
- *       to the lock screen)
- *
- * The application should have stopped all rendering and sound and any
- * non-critical background processing.
- *
- * When the device is resumed but not yet unlocked, the app will be resumed:
- * 
- * - OnResume
- *
- * The application should not perform sound or graphics yet. If the lock 
- * screen times out, the app will be paused again. If the screen is
- * unlocked, the app will regain focus.
- *
- * Turning all of this into a general framework, we can use the following:
- *
- * 1. In OnCreate/android_main, set up the main classes and possibly
- *    load some lightweight resources.
- * 2. In OnCreateWindow, create the EGLSurface, bind the context, load 
- *    OpenGL resources. No rendering.
- * 3. When we are between OnResume and OnPause, and between OnCreateWindow
- *    and OnDestroyWindow, and between OnGainedFocus and OnLostFocus,
- *    we can render and process input.
- * 4. In OnLostFocus, stop sounds from playing, and stop rendering.
- * 5. In OnPause, stop all rendering
- * 6. In OnResume, prepare to start rendering again, but don't render.
- * 7. In OnGainedFocus after OnResume, start rendering and sound again.
- * 8. In OnStop, free all graphic resources, either through GLES calls
- *    if the EGLContext is still bound, or via eglDestroyContext if the
- *    context has been unbound because the rendering surface was destroyed.
- * 9. In OnDestroy, release all other resources.
- */
-EventLoop::EventLoop(android_app* application)
-    : enabled_(false),
-      quit_(false),
-      isResumed_(false),
-      hasSurface_(false),
-      hasFocus_(false),
-      application_(application),
-      lifecycle_handler_(NULL),
-      input_handler_(NULL),
-      sensor_manager_(NULL),
-      sensor_event_queue_(NULL),
-      sensor_poll_source_() {
-  application_->onAppCmd = ActivityCallback;
-  application_->onInputEvent = InputCallback;
-  application_->userData = this;
-}
-
-static int64_t getTimeInMillis() {
-  struct timespec res;
-  clock_gettime(CLOCK_REALTIME, &res);
-  return 1000 * res.tv_sec + res.tv_nsec / 1000000;
-}
-
-void EventLoop::Run(LifeCycleHandler* lifecycle_handler,
-                    InputHandler* input_handler) {
-  int32_t result;
-  int32_t events;
-  android_poll_source* source;
-
-  lifecycle_handler_ = lifecycle_handler;
-  input_handler_ = input_handler;
-  int64_t last_frame_time = getTimeInMillis();
-  if (lifecycle_handler_->OnStart() == 0) {
-    LOGI("Starting event loop");
-    while (!quit_) {
-      // If not enabled, block indefinitely on events. If enabled, block
-      // briefly so we can do useful work in onStep, but only long
-      // enough that we can still do work at 60fps if possible.
-      int64_t next_frame_time = last_frame_time + (1000/60);
-      int64_t next_frame_delay = next_frame_time - getTimeInMillis();
-      if (next_frame_delay < 0) next_frame_delay = 0;
-      while ((result = ALooper_pollAll(enabled_ ? next_frame_delay : -1, NULL,
-          &events, reinterpret_cast<void**>(&source))) >= 0) {
-        if (source != NULL) {
-          source->process(application_, source);
-        }
-        if (application_->destroyRequested) {
-          return;
-        }
-      }
-      if (enabled_ && !quit_) {
-        int64_t now = getTimeInMillis();
-        if (now >= next_frame_time) {
-          LOGI("step");
-          last_frame_time = now;
-          if (lifecycle_handler_->OnStep() != 0) {
-            quit_ = true;
-          }
-        }
-      }
-    }
-  }
-  ANativeActivity_finish(application_->activity);
-}
-
-void EventLoop::EnableSensorEvents() {
-  sensor_poll_source_.id = LOOPER_ID_USER;
-  sensor_poll_source_.app = application_;
-  sensor_poll_source_.process = SensorCallback;
-  sensor_manager_ = ASensorManager_getInstance();
-  if (sensor_manager_ != NULL) {
-    sensor_event_queue_ = ASensorManager_createEventQueue(
-        sensor_manager_, application_->looper,
-        LOOPER_ID_USER, NULL, &sensor_poll_source_);
-
-    sensor_ = ASensorManager_getDefaultSensor(sensor_manager_,
-        ASENSOR_TYPE_ACCELEROMETER);
-    if (sensor_ != NULL) {
-      int32_t min_delay = ASensor_getMinDelay(sensor_);
-      if (ASensorEventQueue_enableSensor(sensor_event_queue_, sensor_) < 0 ||
-          ASensorEventQueue_setEventRate(sensor_event_queue_, sensor_,
-              min_delay) < 0) {
-        LOGE("Error while activating sensor.");
-        DisableSensorEvents();
-        return;
-      }
-      LOGI("Activating sensor:");
-      LOGI("Name       : %s", ASensor_getName(sensor_));
-      LOGI("Vendor     : %s", ASensor_getVendor(sensor_));
-      LOGI("Resolution : %f", ASensor_getResolution(sensor_));
-      LOGI("Min Delay  : %d", min_delay);
-    } else {
-      LOGI("No sensor");
-    }
-  }
-}
-
-void EventLoop::DisableSensorEvents() {
-  if (sensor_ != NULL) {
-    if (ASensorEventQueue_disableSensor(sensor_event_queue_, sensor_) < 0) {
-      LOGE("Error while deactivating sensor.");
-    }
-    sensor_ = NULL;
-  }
-  if (sensor_event_queue_ != NULL) {
-    ASensorManager_destroyEventQueue(sensor_manager_,
-                    sensor_event_queue_);
-    sensor_event_queue_ = NULL;
-  }
-  sensor_manager_ = NULL;
-}
-
-void EventLoop::ProcessActivityEvent(int32_t command) {
-  switch (command) {
-    case APP_CMD_INIT_WINDOW:
-      if (lifecycle_handler_->Activate() != 0) {
-        quit_ = true;
-      } else {
-        hasSurface_ = true;
-      }
-      break;
-    case APP_CMD_CONFIG_CHANGED:
-      lifecycle_handler_->OnConfigurationChanged();
-      break;
-    case APP_CMD_DESTROY:
-      hasFocus_ = false;
-      lifecycle_handler_->FreeAllResources();
-      break;
-    case APP_CMD_GAINED_FOCUS:
-      hasFocus_ = true;
-      if (hasSurface_ && isResumed_ && hasFocus_) {
-        enabled_ = (lifecycle_handler_->Resume() == 0);
-        if (enabled_) {
-          EnableSensorEvents();
-        }
-      }
-      break;
-    case APP_CMD_LOST_FOCUS:
-      hasFocus_ = false;
-      enabled_ = false;
-      DisableSensorEvents();
-      lifecycle_handler_->Pause();
-      break;
-    case APP_CMD_LOW_MEMORY:
-      lifecycle_handler_->OnLowMemory();
-      break;
-    case APP_CMD_PAUSE:
-      isResumed_ = false;
-      enabled_ = false;
-      DisableSensorEvents();
-      lifecycle_handler_->Pause();
-      break;
-    case APP_CMD_RESUME:
-      isResumed_ = true;
-      break;
-    case APP_CMD_SAVE_STATE:
-      lifecycle_handler_->OnSaveState(&application_->savedState,
-                                    &application_->savedStateSize);
-      break;
-    case APP_CMD_START:
-      break;
-    case APP_CMD_STOP:
-      hasFocus_ = false;
-      lifecycle_handler_->Deactivate();
-      break;
-    case APP_CMD_TERM_WINDOW:
-      hasFocus_ = false;
-      hasSurface_ = false;
-      enabled_ = false;
-      DisableSensorEvents();
-      lifecycle_handler_->Pause();
-      break;
-    default:
-      break;
-  }
-}
-
-void EventLoop::ProcessSensorEvent() {
-  ASensorEvent event;
-  while (ASensorEventQueue_getEvents(sensor_event_queue_, &event, 1) > 0) {
-    switch (event.type) {
-      case ASENSOR_TYPE_ACCELEROMETER:
-        input_handler_->OnAccelerometerEvent(event.vector.x,
-            event.vector.y, event.vector.z);
-        break;
-    }
-  }
-}
-
-bool EventLoop::OnTouchEvent(AInputEvent* event) {
-  int32_t type = AMotionEvent_getAction(event);
-  MotionEvent motion_event;
-  switch (type) {
-    case AMOTION_EVENT_ACTION_DOWN:
-      motion_event = kMotionDown;
-      break;
-    case AMOTION_EVENT_ACTION_UP:
-      motion_event = kMotionUp;
-      break;
-    case AMOTION_EVENT_ACTION_MOVE:
-      motion_event = kMotionMove;
-      break;
-    case AMOTION_EVENT_ACTION_CANCEL:
-      motion_event = kMotionCancel;
-      break;
-    case AMOTION_EVENT_ACTION_OUTSIDE:
-      motion_event = kMotionOutside;
-      break;
-    case AMOTION_EVENT_ACTION_POINTER_DOWN:
-      motion_event = kMotionPointerDown;
-      break;
-    case AMOTION_EVENT_ACTION_POINTER_UP:
-      motion_event = kMotionPointerUp;
-      break;
-    default:
-      return false;
-  }
-  // For now we just get the last coords.
-  float move_x = AMotionEvent_getX(event, 0);
-  float move_y = AMotionEvent_getY(event, 0);
-  int64_t when = AMotionEvent_getEventTime(event);
-  LOGI("Got motion event %d at %f, %f", type, move_x, move_y);
-
-  if (input_handler_->OnMotionEvent(motion_event, when, move_x, move_y) != 0) {
-    return false;
-  }
-  return true;
-}
-
-bool EventLoop::OnKeyEvent(AInputEvent* event) {
-  int32_t type = AKeyEvent_getAction(event);
-  KeyEvent key_event;
-  switch (type) {
-    case AKEY_EVENT_ACTION_DOWN:
-      key_event = kKeyDown;
-      break;
-    case AKEY_EVENT_ACTION_UP:
-      key_event = kKeyUp;
-      break;
-    case AKEY_EVENT_ACTION_MULTIPLE:
-      key_event = kKeyMultiple;
-      break;
-    default:
-      return false;
-  }
-  /* Get the key code of the key event.
-   * This is the physical key that was pressed, not the Unicode character. */
-  int32_t key_code = AKeyEvent_getKeyCode(event);
-  /* Get the meta key state. */
-  int32_t meta_state = AKeyEvent_getMetaState(event);
-  /* Get the repeat count of the event.
-   * For both key up an key down events, this is the number of times the key
-   * has repeated with the first down starting at 0 and counting up from
-   * there.  For multiple key events, this is the number of down/up pairs
-   * that have occurred. */
-  int32_t repeat = AKeyEvent_getRepeatCount(event);
-
-  /* Get the time of the most recent key down event, in the	
-   * java.lang.System.nanoTime() time base.  If this is a down event,	
-   * this will be the same as eventTime.	
-   * Note that when chording keys, this value is the down time of the most	
-   * recently pressed key, which may not be the same physical key of this	
-   * event. */	
-  // TODO(gram): Use or remove this.
-  // int64_t key_down_time = AKeyEvent_getDownTime(event);
-
-  /* Get the time this event occurred, in the
-   * java.lang.System.nanoTime() time base. */
-  int64_t when = AKeyEvent_getEventTime(event);
-  bool isAltKeyDown = (meta_state & AMETA_ALT_ON) != 0;
-  bool isShiftKeyDown = (meta_state & AMETA_SHIFT_ON) != 0;
-  bool isCtrlKeyDown = key_code < 32;
-
-  LOGI("Got key event %d %d", type, key_code);
-
-  if (input_handler_->OnKeyEvent(key_event, when, key_code,
-                                 isAltKeyDown, isCtrlKeyDown, isShiftKeyDown,
-                                 repeat) != 0) {
-    return false;
-  }
-  return true;
-}
-
-int32_t EventLoop::ProcessInputEvent(AInputEvent* event) {
-  int32_t event_type = AInputEvent_getType(event);
-  LOGI("Got input event type %d", event_type);
-  switch (event_type) {
-    case AINPUT_EVENT_TYPE_MOTION:
-      if (AInputEvent_getSource(event) == AINPUT_SOURCE_TOUCHSCREEN) {
-          return OnTouchEvent(event);
-      }
-      break;
-    case AINPUT_EVENT_TYPE_KEY:
-      return OnKeyEvent(event);
-  }
-  return 0;
-}
-
-void EventLoop::ActivityCallback(android_app* application, int32_t command) {
-  EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData);
-  event_loop->ProcessActivityEvent(command);
-}
-
-int32_t EventLoop::InputCallback(android_app* application,
-                                 AInputEvent* event) {
-  EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData);
-  return event_loop->ProcessInputEvent(event);
-}
-
-void EventLoop::SensorCallback(android_app* application,
-    android_poll_source* source) {
-  EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData);
-  event_loop->ProcessSensorEvent();
-}
-
diff --git a/runtime/embedders/openglui/android/eventloop.h b/runtime/embedders/openglui/android/eventloop.h
deleted file mode 100644
index 031bf69..0000000
--- a/runtime/embedders/openglui/android/eventloop.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_ANDROID_EVENTLOOP_H_
-#define EMBEDDERS_OPENGLUI_ANDROID_EVENTLOOP_H_
-
-#include <android_native_app_glue.h>
-#include <android/sensor.h>
-#include "embedders/openglui/common/events.h"
-#include "embedders/openglui/common/input_handler.h"
-#include "embedders/openglui/common/lifecycle_handler.h"
-
-class EventLoop {
-  public:
-    explicit EventLoop(android_app* application);
-    void Run(LifeCycleHandler* activity_handler,
-             InputHandler* input_handler);
-
-  protected:
-    void EnableSensorEvents();
-    void DisableSensorEvents();
-
-    void ProcessActivityEvent(int32_t command);
-    int32_t ProcessInputEvent(AInputEvent* event);
-    void ProcessSensorEvent();
-
-    bool OnTouchEvent(AInputEvent* event);
-    bool OnKeyEvent(AInputEvent* event);
-
-    static void ActivityCallback(android_app* application, int32_t command);
-    static int32_t InputCallback(android_app* application, AInputEvent* event);
-    static void SensorCallback(android_app* application,
-        android_poll_source* source);
-
-  private:
-    friend class Sensor;
-
-    bool enabled_, quit_;
-    bool isResumed_, hasSurface_, hasFocus_;
-    android_app* application_;
-    LifeCycleHandler* lifecycle_handler_;
-    InputHandler* input_handler_;
-    const ASensor* sensor_;
-    ASensorManager* sensor_manager_;
-    ASensorEventQueue* sensor_event_queue_;
-    android_poll_source sensor_poll_source_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_ANDROID_EVENTLOOP_H_
-
diff --git a/runtime/embedders/openglui/android/main.cc b/runtime/embedders/openglui/android/main.cc
deleted file mode 100644
index c0c386b..0000000
--- a/runtime/embedders/openglui/android/main.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/android/android_graphics_handler.h"
-#include "embedders/openglui/android/android_input_handler.h"
-#include "embedders/openglui/android/android_resource.h"
-#include "embedders/openglui/android/android_sound_handler.h"
-#include "embedders/openglui/android/eventloop.h"
-#include "embedders/openglui/common/context.h"
-#include "embedders/openglui/common/dart_host.h"
-#include "embedders/openglui/common/vm_glue.h"
-
-android_app* application_ = NULL;
-
-Resource* MakePlatformResource(const char *path) {
-  return new AndroidResource(application_, path);
-}
-
-void android_main(android_app* application) {
-  application_ = application;
-  app_dummy();  // Link in native_app_glue.
-  const char* resource_path = "/data/data/com.google.dartndk/app_dart";
-  EventLoop eventLoop(application);
-  AndroidGraphicsHandler graphics_handler(application, resource_path);
-  VMGlue vm_glue(&graphics_handler, resource_path);
-  AndroidInputHandler input_handler(&vm_glue, &graphics_handler);
-  AndroidSoundHandler sound_handler(application);
-  Timer timer;
-  Context app_context;
-  app_context.graphics_handler = &graphics_handler;
-  app_context.input_handler = &input_handler;
-  app_context.sound_handler = &sound_handler;
-  app_context.timer = &timer;
-  app_context.vm_glue = &vm_glue;
-  DartHost host(&app_context);
-  eventLoop.Run(&host, &input_handler);
-}
-
diff --git a/runtime/embedders/openglui/android/support_android.cc b/runtime/embedders/openglui/android/support_android.cc
deleted file mode 100644
index 6755f15..0000000
--- a/runtime/embedders/openglui/android/support_android.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Provide atexit, not part of Android libc or linker.
-
-extern "C" int atexit(void (*function)(void)) {
-  // Return error code.
-  return 1;
-}
-
-// Provide __dso_handle, not part of Android libc or linker.
-
-__attribute__((weak)) void *__dso_handle;
-
diff --git a/runtime/embedders/openglui/build_skia.sh b/runtime/embedders/openglui/build_skia.sh
deleted file mode 100755
index 42710a8..0000000
--- a/runtime/embedders/openglui/build_skia.sh
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/bin/bash
-
-function usage {
-  echo "usage: $0 [ --help ] [ --android ] [ --arm | --x86] [ --debug ] [--clean] [<Dart directory>]"
-  echo
-  echo "Sync up Skia and build"
-  echo
-  echo " --android: Build for Android"
-  echo " --x86 : Build for Intel"
-  echo " --arm : Cross-compile for ARM (implies --android)"
-  echo " --debug : Build a debug version"
-  echo
-}
-
-DO_ANDROID=0
-TARGET_ARCH=x86
-CLEAN=0
-BUILD=Release
-DART_DIR=../../..
-
-while [ ! -z "$1" ] ; do
-  case $1 in
-    "-h"|"-?"|"-help"|"--help")
-      usage
-      exit 1
-    ;;
-    "--android")
-      DO_ANDROID=1
-    ;;
-    "--arm")
-      TARGET_ARCH=arm
-      DO_ANDROID=1
-    ;;
-    "--x86")
-      TARGET_ARCH=x86
-    ;;
-    "--clean")
-      CLEAN=1
-    ;;
-    "--debug")
-      BUILD=Debug
-    ;;
-    "--release")
-      BUILD=Release
-    ;;
-    *)
-      if [ ! -d "$1" ]
-      then
-        echo "Unrecognized argument: $1"
-        usage
-        exit 1
-      fi
-      DART_DIR="$1"
-    ;;
-  esac
-  shift
-done
-
-mkdir -p "${DART_DIR}/third_party/skia"
-pushd "${DART_DIR}/third_party/skia"
-
-if [ ${DO_ANDROID} != 0 ] ; then
-  echo "Building for Android ${TARGET_ARCH}"
-  curl http://skia.googlecode.com/svn/trunk/platform_tools/android/gclient.config -o .gclient
-  gclient sync
-
-  export ANDROID_SDK_ROOT=`readlink -f ../android_tools/sdk`
-  export GSUTIL_LOCATION=`readlink -f ../gsutil`
-
-  cd trunk
-
-  echo "Using SDK ${ANDROID_SDK_ROOT}"
-  if [ ${CLEAN} != 0 ] ; then
-    ./platform_tools/android/bin/android_make -d $TARGET_ARCH -j clean
-  else
-    echo env -i BUILDTYPE=$BUILD ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT}" PATH="${PATH}:${GSUTIL_LOCATION}" ../android/bin/android_make BUILDTYPE=$BUILD -d $TARGET_ARCH -j --debug=j
-    env -i BUILDTYPE=$BUILD ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT}" PATH="${PATH}:${GSUTIL_LOCATION}" ./platform_tools/android/bin/android_make BUILDTYPE=$BUILD -d $TARGET_ARCH -j --debug=j
-  fi
-
-else
-
-  echo "Building for desktop in `pwd`"
-  # Desktop build. Requires svn client and Python.
-
-  # Note that on Linux these packages should be installed first:
-  #
-  # libfreetype6
-  # libfreetype6-dev
-  # libpng12-0, libpng12-dev
-  # libglu1-mesa-dev
-  # mesa-common-dev
-  # freeglut3-dev
-
-  SKIA_INSTALLDIR=`pwd`
-  svn checkout http://skia.googlecode.com/svn/trunk
-  cd trunk
-  if [ ${CLEAN} != 0 ] ; then
-    echo 'Cleaning'
-    make clean
-  else
-    # Dart sets BUILDTYPE to DebugX64 which breaks Skia build.
-    make BUILDTYPE=$BUILD
-  fi
-  cd ..
-
-fi
-
-popd
-# TODO(gram) We should really propogate the make exit code here.
-exit 0
-
-
diff --git a/runtime/embedders/openglui/common/canvas_context.cc b/runtime/embedders/openglui/common/canvas_context.cc
deleted file mode 100644
index 24c0f7d..0000000
--- a/runtime/embedders/openglui/common/canvas_context.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/common/canvas_context.h"
-
-#include <ctype.h>
-#include <string.h>
-#include "core/SkStream.h"
-#include "embedders/openglui/common/image_cache.h"
-#include "embedders/openglui/common/support.h"
-
-// TODO(gram): this should be dynamic.
-#define MAX_CONTEXTS 256
-CanvasContext* contexts[MAX_CONTEXTS] = { 0 };
-
-CanvasContext* Context2D(int handle) {
-  if (handle < 0 || handle >= MAX_CONTEXTS) {
-    LOGE("Request for out-of-range handle %d", handle);
-    return NULL;
-  }
-  if (contexts[handle] == NULL) {
-    LOGE("Warning: request for context with handle %d returns NULL", handle);
-  }
-  return contexts[handle];
-}
-
-void FreeContexts() {
-  extern CanvasContext* display_context;
-  for (int i = 0; i < MAX_CONTEXTS; i++) {
-    delete contexts[i];
-    contexts[i] = NULL;
-  }
-  display_context = NULL;
-}
-
-
-CanvasContext::CanvasContext(int handle, int16_t widthp, int16_t heightp)
-  : canvas_(NULL),
-    width_(widthp),
-    height_(heightp),
-    imageSmoothingEnabled_(true),
-    state_(NULL) {
-  if (handle >= MAX_CONTEXTS) {
-    LOGE("Max contexts exceeded");
-    exit(-1);
-  }
-  if (handle == 0) {
-    canvas_ = graphics->CreateDisplayCanvas();
-  } else {
-    canvas_ = graphics->CreateBitmapCanvas(widthp, heightp);
-  }
-  state_ = new CanvasState(canvas_);
-  contexts[handle] = this;
-  LOGI("Created context with handle %d", handle);
-}
-
-CanvasContext::~CanvasContext() {
-  delete state_;
-  delete canvas_;
-}
-
-void CanvasContext::Save() {
-  state_ = state_->Save();
-}
-
-void CanvasContext::Restore() {
-  CanvasState* popped_state = state_;
-  state_ = state_->Restore();
-  if (state_ == NULL) {
-    LOGE("Popping last state!");
-    state_ = popped_state;
-  }
-  if (state_ != popped_state) {
-    // Only delete if the pop was successful.
-    delete popped_state;
-  }
-}
-
-void CanvasContext::DrawImage(const char* src_url,
-                              int sx, int sy,
-                              bool has_src_dimensions, int sw, int sh,
-                              int dx, int dy,
-                              bool has_dst_dimensions, int dw, int dh) {
-  const SkBitmap* bm = ImageCache::GetImage(src_url);
-  if (bm == NULL) return;
-  if (!has_src_dimensions) {
-    sw = bm->width();
-    sh = bm->height();
-  }
-  if (!has_dst_dimensions) {
-    dw = bm->width();
-    dh = bm->height();
-  }
-  state_->DrawImage(*bm, sx, sy, sw, sh, dx, dy, dw, dh);
-  isDirty_ = true;
-}
-
-void CanvasContext::ClearRect(float left, float top,
-                              float width, float height) {
-  SkPaint paint;
-  paint.setStyle(SkPaint::kFill_Style);
-  paint.setColor(0xFFFFFFFF);
-  canvas_->drawRectCoords(left, top, left + width, top + height, paint);
-  isDirty_ = true;
-}
-
diff --git a/runtime/embedders/openglui/common/canvas_context.h b/runtime/embedders/openglui/common/canvas_context.h
deleted file mode 100644
index a45b574..0000000
--- a/runtime/embedders/openglui/common/canvas_context.h
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_CANVAS_CONTEXT_H_
-#define EMBEDDERS_OPENGLUI_COMMON_CANVAS_CONTEXT_H_
-
-#include "embedders/openglui/common/canvas_state.h"
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/opengl.h"
-#include "embedders/openglui/common/support.h"
-
-typedef struct ImageData {
-  int width;
-  int height;
-  GLubyte* pixels;
-
-  ImageData(int wp, int hp, GLubyte* pp)
-    : width(wp), height(hp), pixels(pp) {
-  }
-  ImageData()
-    : width(0), height(0), pixels(NULL) {
-  }
-} ImageData;
-
-class CanvasContext {
- protected:
-  SkCanvas* canvas_;
-  int16_t width_, height_;
-  bool imageSmoothingEnabled_;
-  bool isDirty_;
-  CanvasState* state_;
-
-  static inline float Radians2Degrees(float angle) {
-    return 180.0 * angle / M_PI;
-  }
-
-  inline void NotImplemented(const char* method) {
-    LOGE("Method CanvasContext::%s is not yet implemented", method);
-  }
-
- public:
-  CanvasContext(int handle, int16_t width, int16_t height);
-  virtual ~CanvasContext();
-
-  inline bool isDirty() {
-    return isDirty_;
-  }
-
-  inline void clearDirty() {
-    isDirty_ = false;
-  }
-
-  inline void setGlobalAlpha(float alpha) {
-    state_->setGlobalAlpha(alpha);
-  }
-
-  inline void setFillColor(const char* color) {
-    state_->setFillColor(color);
-  }
-
-  inline void setStrokeColor(const char* color) {
-    state_->setStrokeColor(color);
-  }
-
-  inline void setShadowBlur(float blur) {
-    state_->setShadowBlur(blur);
-  }
-
-  inline void setShadowColor(const char* color) {
-    state_->setShadowColor(color);
-  }
-
-  inline void setShadowOffsetX(float offset) {
-    state_->setShadowOffsetX(offset);
-  }
-
-  inline void setShadowOffsetY(float offset) {
-    state_->setShadowOffsetY(offset);
-  }
-
-  // For now, we don't allow resizing.
-  // TODO(gram): fix this or remove these.
-  inline int setWidth(int widthp) {
-    return width_;
-  }
-
-  inline int setHeight(int heightp) {
-    return height_;
-  }
-
-  inline bool imageSmoothingEnabled() {
-    return imageSmoothingEnabled_;
-  }
-
-  inline void setImageSmoothingEnabled(bool enabled) {
-    // TODO(gram): We're not actually doing anything with this yet.
-    imageSmoothingEnabled_ = enabled;
-  }
-
-  inline void setGlobalCompositeOperation(const char* op) {
-    state_->setGlobalCompositeOperation(op);
-  }
-
-  void Save();
-  void Restore();
-
-  inline void Rotate(float angle) {
-    canvas_->rotate(Radians2Degrees(angle));
-  }
-
-  inline void Translate(float x, float y) {
-    canvas_->translate(x, y);
-  }
-
-  inline void Scale(float x, float y) {
-    canvas_->scale(x, y);
-  }
-
-  inline void Transform(float a, float b,
-                        float c, float d,
-                        float e, float f) {
-    SkMatrix t;
-    // Our params are for a 3 x 2 matrix in column order:
-    //
-    // a c e
-    // b d f
-    //
-    // We need to turn this into a 3x3 matrix:
-    //
-    // a c e
-    // b d f
-    // 0 0 1
-    //
-    // and pass the params in row order:
-    t.setAll(a, c, e, b, d, f, 0, 0, 1);
-    canvas_->concat(t);
-  }
-
-  inline void setTransform(float a, float b,
-                           float c, float d,
-                           float e, float f) {
-    SkMatrix t;
-    t.setAll(a, c, e, b, d, f, 0, 0, 1);
-    canvas_->setMatrix(t);
-  }
-
-  ImageData* GetImageData(float sx, float sy, float sw, float sh) {
-    NotImplemented("GetImageData");
-    return NULL;
-  }
-
-  void PutImageData(ImageData* imageData, float  dx, float dy) {
-    NotImplemented("PutImageData");
-  }
-
-  void DrawImage(const char* src_url,
-                 int sx, int sy, bool has_src_dimensions, int sw, int sh,
-                 int dx, int dy, bool has_dst_dimensions, int dw, int dh);
-
-  inline void Clear() {
-    canvas_->drawColor(0xFFFFFFFF);
-    isDirty_ = true;
-  }
-
-  void ClearRect(float left, float top, float width, float height);
-
-  inline void FillRect(float left, float top, float width, float height) {
-    // Does not affect the path.
-    state_->FillRect(left, top, width, height);
-    isDirty_ = true;
-  }
-
-  inline void StrokeRect(float left, float top, float width, float height) {
-    // Does not affect the path.
-    state_->StrokeRect(left, top, width, height);
-    isDirty_ = true;
-  }
-
-  inline void BeginPath() {
-    state_->BeginPath();
-  }
-
-  inline void Fill() {
-    state_->Fill();
-    isDirty_ = true;
-  }
-
-  inline void Stroke() {
-    state_->Stroke();
-    isDirty_ = true;
-  }
-
-  inline void ClosePath() {
-    state_->ClosePath();
-  }
-
-  inline void MoveTo(float x, float y) {
-    state_->MoveTo(x, y);
-  }
-
-  inline void LineTo(float x, float y) {
-    state_->LineTo(x, y);
-  }
-
-  inline void QuadraticCurveTo(float cpx, float cpy, float x, float y) {
-    state_->QuadraticCurveTo(cpx, cpy, x, y);
-  }
-
-  inline void BezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y,
-                     float x, float y) {
-    state_->BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
-  }
-
-  inline void ArcTo(float x1, float y1, float x2, float y2, float radius) {
-    state_->ArcTo(x1, y1, x2, y2, radius);
-  }
-
-  inline void Rect(float x, float y, float w, float h) {
-    state_->Rect(x, y, w, h);
-  }
-
-  inline void Arc(float x, float y, float radius,
-                  float startAngle, float endAngle,
-                  bool antiClockwise) {
-    state_->Arc(x, y, radius, startAngle, endAngle, antiClockwise);
-  }
-
-  inline void setLineWidth(double w) {
-    state_->setLineWidth(w);
-  }
-
-  inline void setLineCap(const char* lc) {
-    state_->setLineCap(lc);
-  }
-
-  inline void setLineDash(float* dashes, int len) {
-    state_->setLineDash(dashes, len);
-  }
-
-  inline void setLineDashOffset(float offset) {
-    state_->setLineDashOffset(offset);
-  }
-
-  inline void setLineJoin(const char* lj) {
-    state_->setLineJoin(lj);
-  }
-
-  inline void setMiterLimit(float limit) {
-    state_->setMiterLimit(limit);
-  }
-
-  inline const char* setFont(const char* font) {
-    return state_->setFont(font);
-  }
-
-  inline const char* setTextAlign(const char* align) {
-    return state_->setTextAlign(align);
-  }
-
-  const char* setTextBaseline(const char* baseline) {
-    return state_->setTextBaseline(baseline);
-  }
-
-  inline const char* setDirection(const char* direction) {
-    return state_->setTextDirection(direction);
-  }
-
-  inline void FillText(const char* text, float x, float y,
-                       float maxWidth = -1) {
-    state_->FillText(text, x, y, maxWidth);
-    isDirty_ = true;
-  }
-
-  inline void StrokeText(const char* text, float x, float y,
-                         float maxWidth = -1) {
-    state_->StrokeText(text, x, y, maxWidth);
-    isDirty_ = true;
-  }
-
-  inline float MeasureText(const char *text) {
-    return state_->MeasureText(text);
-  }
-
-  inline void Clip() {
-    state_->Clip();
-  }
-
-  inline void ResetClip() {
-    // TODO(gram): Check this. Is it affected by the transform?
-    canvas_->clipRect(SkRect::MakeLTRB(0, 0, width_, height_),
-                      SkRegion::kReplace_Op);
-  }
-
-  virtual void Flush() {
-    canvas_->flush();
-  }
-
-  inline void SetFillGradient(bool is_radial, double x0, double y0, double r0,
-      double x1, double y1, double r1,
-      int stops, float* positions, char** colors) {
-    state_->SetFillGradient(is_radial, x0, y0, r0, x1, y1, r1,
-        stops, positions, colors);
-  }
-
-  inline void SetStrokeGradient(bool is_radial, double x0, double y0, double r0,
-      double x1, double y1, double r1,
-      int stops, float* positions, char** colors) {
-    state_->SetStrokeGradient(is_radial, x0, y0, r0, x1, y1, r1,
-        stops, positions, colors);
-  }
-
-  inline const SkBitmap* GetBitmap() {
-    SkDevice* device = canvas_->getDevice();
-    return &device->accessBitmap(false);
-  }
-};
-
-CanvasContext* Context2D(int handle);
-void FreeContexts();
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_CANVAS_CONTEXT_H_
-
diff --git a/runtime/embedders/openglui/common/canvas_state.cc b/runtime/embedders/openglui/common/canvas_state.cc
deleted file mode 100644
index 8d927c8..0000000
--- a/runtime/embedders/openglui/common/canvas_state.cc
+++ /dev/null
@@ -1,411 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/common/canvas_state.h"
-
-#include <ctype.h>
-#include <string.h>
-
-#include "embedders/openglui/common/support.h"
-
-// Float parser. Does not handle exponents. This is
-// used to parse font sizes so it doesn't need to be full-blown.
-float ParseFloat(const char* s, int& pos) {
-  int len = strlen(s);
-  float rtn = 0.0;
-  while (pos < len && s[pos] != '.' && !isdigit(s[pos])) {
-    ++pos;
-  }
-  while (pos < len && isdigit(s[pos])) {
-    rtn = rtn * 10.0 + s[pos] - '0';
-    ++pos;
-  }
-  if (pos < len && s[pos] == '.') {
-    pos++;
-    float div = 1.0;
-    while (pos < len && isdigit(s[pos])) {
-      rtn = rtn * 10.0 + s[pos] - '0';
-      ++pos;
-      div *= 10.0;
-    }
-    rtn /= div;
-  }
-  return rtn;
-}
-
-int ParseInt(const char* s, int& pos) {
-  int len = strlen(s);
-  int rtn = 0;
-  while (pos < len && !isdigit(s[pos])) {
-    ++pos;
-  }
-  while (pos < len && isdigit(s[pos])) {
-    rtn = rtn * 10 + s[pos] - '0';
-    ++pos;
-  }
-  return rtn;
-}
-
-CanvasState* CanvasState::Restore() {
-  if (next_ != NULL) {
-    // If the state we are popping has a non-empty path,
-    // apply the state's transform to the path, then
-    // add the path to the previous state's path.
-    if (path_->countPoints() > 0) {
-      path_->transform(canvas_->getTotalMatrix());
-      next_->path_->addPath(*path_);
-    }
-    canvas_->restore();
-    return next_;
-  }
-  canvas_->restore();
-  return next_;  // TODO(gram): Should we assert/throw?
-}
-
-void CanvasState::setLineCap(const char* lc) {
-  if (strcmp(lc, "round") == 0) {
-    paint_.setStrokeCap(SkPaint::kRound_Cap);
-  } else if (strcmp(lc, "square") == 0) {
-    paint_.setStrokeCap(SkPaint::kSquare_Cap);
-  } else {
-    paint_.setStrokeCap(SkPaint::kButt_Cap);
-  }
-}
-
-void CanvasState::setLineJoin(const char* lj) {
-  if (strcmp(lj, "round") == 0) {
-    paint_.setStrokeJoin(SkPaint::kRound_Join);
-  } else if (strcmp(lj, "bevel") == 0) {
-    paint_.setStrokeJoin(SkPaint::kBevel_Join);
-  } else {
-    paint_.setStrokeJoin(SkPaint::kMiter_Join);
-  }
-}
-
-const char* CanvasState::setFont(const char*name, float size) {
-  // Font names have the form "<modifier> <size> <family>".
-  // Modifiers are "normal", "italic", "bold".
-  // Sizes have magnitude and units; e.g. "10pt", "20px".
-  const char* rtn = name;
-  if (size < 0) {
-    int pos = 0;
-    // TODO(gram): need to handle these modifiers.
-    if (strncmp(name, "normal", 6) == 0) {
-      pos = 6;
-    } else if (strncmp(name, "italic", 6) == 0) {
-      pos = 6;
-    } else if (strncmp(name, "bold", 4) == 0) {
-      pos = 4;
-    }
-    size = ParseFloat(name, pos);
-    // Font size units: px, etc. For now just px.
-    // TODO(gram): Handle other units.
-    if (strncmp(name + pos, "px", 2) == 0) {
-      pos += 2;
-    }
-    int len = strlen(name);
-    while (pos < len && isspace(name[pos])) {
-      ++pos;
-    }
-    name = name + pos;
-  }
-  SkTypeface *pTypeface = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
-  paint_.setTypeface(pTypeface);
-  paint_.setTextSize(size);
-  // TODO(gram): Must return a normalized font name incorporating size, so
-  // callers can set the Dart canvas font name to an appropriate value.
-  // Actually this may not be necessary in which case we can change this
-  // method to return void.
-  return rtn;
-}
-
-const char* CanvasState::setTextAlign(const char* align) {
-  // TODO(gram): What about "start" and "end"?
-  // I don't see any an analogs in Skia.
-  if (strcmp(align, "left") == 0) {
-    paint_.setTextAlign(SkPaint::kLeft_Align);
-  } else if (strcmp(align, "right") == 0) {
-    paint_.setTextAlign(SkPaint::kRight_Align);
-  } else {
-    paint_.setTextAlign(SkPaint::kCenter_Align);
-  }
-  return align;
-}
-
-const char* CanvasState::setTextBaseline(const char* baseline) {
-  // TODO(gram): Does skia support this? It doesn't seem like
-  // it. Right now we don't use the textBaseline value, but we
-  // may have to implement this ourselves, by adjusting the y
-  // values passed to StrokeText/FillText using the font metrics.
-  if (strcmp(baseline, "top") == 0) {
-  } else if (strcmp(baseline, "middle") == 0) {
-  } else if (strcmp(baseline, "bottom") == 0) {
-  } else if (strcmp(baseline, "hanging") == 0) {
-  } else if (strcmp(baseline, "alphabetic") == 0) {
-  } else if (strcmp(baseline, "ideographic") == 0) {
-  }
-  return baseline;
-}
-
-const char* CanvasState::setTextDirection(const char* direction) {
-    // TODO(gram): Add support for this if Skia does.
-  return direction;
-}
-
-void CanvasState::setMode(SkPaint::Style style, ColorRGBA color,
-    SkShader* shader) {
-  paint_.setStyle(style);
-  paint_.setColor(color.v);
-  paint_.setShader(shader);
-  uint8_t alpha = static_cast<uint8_t>(
-      globalAlpha_ * static_cast<float>(color.alpha()));
-  paint_.setAlpha(alpha);
-  bool drawShadow = (shadowOffsetX_ != 0 ||
-                     shadowOffsetY_ != 0 ||
-                     shadowBlur_ != 0) &&
-                     shadowColor_.alpha() > 0;
-  if (drawShadow) {
-    // TODO(gram): should we mult shadowColor by globalAlpha?
-    paint_.setLooper(new SkBlurDrawLooper(SkFloatToScalar(shadowBlur_),
-                                          SkFloatToScalar(shadowOffsetX_),
-                                          SkFloatToScalar(shadowOffsetY_),
-                                          shadowColor_.v))->unref();
-  } else {
-    paint_.setLooper(NULL);
-  }
-}
-
-void CanvasState::setGlobalCompositeOperation(const char* op) {
-  SkXfermode::Mode mode;
-  static const struct CompositOpToXfermodeMode {
-    const char* mCompositOp;
-    uint8_t m_xfermodeMode;
-  } gMapCompositOpsToXfermodeModes[] = {
-     { "clear",            SkXfermode::kClear_Mode },
-     { "copy",             SkXfermode::kSrc_Mode },
-     { "source-over",      SkXfermode::kSrcOver_Mode },
-     { "source-in",        SkXfermode::kSrcIn_Mode },
-     { "source-out",       SkXfermode::kSrcOut_Mode },
-     { "source-atop",      SkXfermode::kSrcATop_Mode },
-     { "destination-over", SkXfermode::kDstOver_Mode },
-     { "destination-in",   SkXfermode::kDstIn_Mode },
-     { "destination-out",  SkXfermode::kDstOut_Mode },
-     { "destination-atop", SkXfermode::kDstATop_Mode },
-     { "xor",              SkXfermode::kXor_Mode },
-     { "darker",           SkXfermode::kDarken_Mode },
-     { "lighter",          SkXfermode::kPlus_Mode }
-  };
-  for (unsigned i = 0;
-       i < SK_ARRAY_COUNT(gMapCompositOpsToXfermodeModes);
-       i++) {
-    if (strcmp(op, gMapCompositOpsToXfermodeModes[i].mCompositOp) == 0) {
-      mode = (SkXfermode::Mode)gMapCompositOpsToXfermodeModes[i].m_xfermodeMode;
-      paint_.setXfermodeMode(mode);
-      return;
-    }
-  }
-  LOGE("Unknown CompositeOperator %s\n", op);
-  paint_.setXfermodeMode(SkXfermode::kSrcOver_Mode);  // fall-back
-}
-
-void CanvasState::Arc(float x, float y, float radius,
-                      float startAngle, float endAngle,
-                      bool antiClockwise) {
-  SkRect rect;
-  rect.set(x - radius, y - radius, x + radius, y + radius);
-  bool doCircle = false;
-
-  static float twoPi = 2 * M_PI;
-
-  float sweep = endAngle - startAngle;
-  if (sweep >= twoPi || sweep <= -twoPi) {
-    doCircle = true;
-  }
-
-  if (!antiClockwise && endAngle <= startAngle) {
-    endAngle += 2 * M_PI;
-  } else if (antiClockwise && startAngle <= endAngle) {
-    startAngle += 2 * M_PI;
-  }
-  sweep = endAngle - startAngle;
-
-  startAngle = fmodf(startAngle, twoPi);
-  float sa = Radians2Degrees(startAngle);
-  float ea = Radians2Degrees(sweep);
-  path_->arcTo(rect, sa, ea, false);
-  if (doCircle) {
-    SkPath tmp;
-    tmp.addOval(rect);
-    tmp.addPath(*path_);
-    path_->swap(tmp);
-  }
-}
-
-int hexDigit(char c) {
-  if (c >= '0' && c <= '9') return c - '0';
-  if (c <= 'Z') return c - 'A' + 10;
-  return c - 'a' + 10;
-}
-
-// Color parser.
-// See http://www.w3.org/TR/CSS21/syndata.html#color-units.
-// There is also another format: hsl(240,100%,100%) (and hsla)
-// TODO(gram): We probably eventually want to use a table rather
-// than a big if statement; see setGlobalCompositeOperation for
-// an example.
-ColorRGBA CanvasState::GetColor(const char* color) {
-  if (color[0] == '#') {
-    int r = 0, g = 0, b = 0;
-    if (strlen(color) == 7) {
-      r = hexDigit(color[1]) * 16 + hexDigit(color[2]);
-      g = hexDigit(color[3]) * 16 + hexDigit(color[4]);
-      b = hexDigit(color[5]) * 16 + hexDigit(color[6]);
-    } else if (strlen(color) == 4) {
-      r = hexDigit(color[1]) * 16 + hexDigit(color[1]);
-      g = hexDigit(color[2]) * 16 + hexDigit(color[2]);
-      b = hexDigit(color[3]) * 16 + hexDigit(color[3]);
-    }
-    return ColorRGBA(r, g, b);
-  } else if (strcmp(color, "maroon") == 0) {
-    return ColorRGBA(0x80, 0x00, 0x00);
-  } else if (strcmp(color, "red") == 0) {
-    return ColorRGBA(0xFF, 0x00, 0x00);
-  } else if (strcmp(color, "orange") == 0) {
-    return ColorRGBA(0xFF, 0xA5, 0x00);
-  } else if (strcmp(color, "yellow") == 0) {
-    return ColorRGBA(0xFF, 0xFF, 0x00);
-  } else if (strcmp(color, "olive") == 0) {
-    return ColorRGBA(0x80, 0x80, 0x00);
-  } else if (strcmp(color, "purple") == 0) {
-    return ColorRGBA(0x80, 0x00, 0x80);
-  } else if (strcmp(color, "fuschia") == 0) {
-    return ColorRGBA(0xFF, 0x00, 0xFF);
-  } else if (strcmp(color, "white") == 0) {
-    return ColorRGBA(0xFF, 0xFF, 0xFF);
-  } else if (strcmp(color, "lime") == 0) {
-    return ColorRGBA(0x00, 0xFF, 0x00);
-  } else if (strcmp(color, "green") == 0) {
-    return ColorRGBA(0x00, 0x80, 0x00);
-  } else if (strcmp(color, "navy") == 0) {
-    return ColorRGBA(0x00, 0x00, 0x80);
-  } else if (strcmp(color, "blue") == 0) {
-    return ColorRGBA(0x00, 0x00, 0xFF);
-  } else if (strcmp(color, "aqua") == 0) {
-    return ColorRGBA(0x00, 0xFF, 0xFF);
-  } else if (strcmp(color, "teal") == 0) {
-    return ColorRGBA(0x00, 0x80, 0x80);
-  } else if (strcmp(color, "silver") == 0) {
-    return ColorRGBA(0xC0, 0xC0, 0xC0);
-  } else if (strcmp(color, "gray") == 0) {
-    return ColorRGBA(0x80, 0x80, 0x80);
-  } else if (strncmp(color, "rgb(", 4) == 0) {
-    int pos = 4;
-    int r = ParseInt(color, pos);
-    ++pos;
-    int g = ParseInt(color, pos);
-    ++pos;
-    int b = ParseInt(color, pos);
-    return ColorRGBA(r, g, b);
-  } else if (strncmp(color, "rgba(", 5) == 0) {
-    int pos = 5;
-    int r = ParseInt(color, pos);
-    ++pos;
-    int g = ParseInt(color, pos);
-    ++pos;
-    int b = ParseInt(color, pos);
-    ++pos;
-    float a = ParseFloat(color, pos);
-    return ColorRGBA(r, g, b, static_cast<int>(a * 255.0));
-  }
-  // Default to black.
-  return ColorRGBA(0x00, 0x00, 0x00);
-}
-
-void CanvasState::DrawImage(const SkBitmap& bm,
-                            int sx, int sy, int sw, int sh,
-                            int dx, int dy, int dw, int dh) {
-  if (sw < 0) sw = bm.width();
-  if (dw < 0) dw = bm.width();
-  if (sh < 0) sh = bm.height();
-  if (dh < 0) dh = bm.height();
-  SkIRect src = SkIRect::MakeXYWH(sx, sy, sw, sh);
-  SkRect dst = SkRect::MakeXYWH(dx, dy, dw, dh);
-  LOGI("DrawImage(_,%d,%d,%d,%d,%d,%d,%d,%d)", sx, sy, sw, sh, dx, dy, dw, dh);
-  canvas_->drawBitmapRect(bm, &src, dst);
-}
-
-void CanvasState::SetFillGradient(bool is_radial,
-    double x0, double y0, double r0,
-    double x1, double y1, double r1,
-    int stops, float* positions, char** colors) {
-  if (fillShader_ != NULL) {
-    fillShader_->unref();
-  }
-  if (is_radial) {
-    fillShader_ = CreateRadialGradient(x0, y0, r0, x1, y1, r1,
-        stops, positions, colors);
-  } else {
-    fillShader_ = CreateLinearGradient(x0, y0, x1, y1,
-        stops, positions, colors);
-  }
-  fillShader_->validate();
-}
-
-void CanvasState::SetStrokeGradient(bool is_radial,
-    double x0, double y0, double r0,
-    double x1, double y1, double r1,
-    int stops, float* positions, char** colors) {
-  if (strokeShader_ != NULL) {
-    strokeShader_->unref();
-  }
-  if (is_radial) {
-    strokeShader_ = CreateRadialGradient(x0, y0, r0, x1, y1, r1,
-        stops, positions, colors);
-  } else {
-    strokeShader_ = CreateLinearGradient(x0, y0, x1, y1,
-        stops, positions, colors);
-  }
-  strokeShader_->validate();
-}
-
-SkShader* CanvasState::CreateRadialGradient(
-      double x0, double y0, double r0,
-      double x1, double y1, double r1,
-      int stops, float* positions, char** colors) {
-  SkScalar* p = new SkScalar[stops];
-  SkColor* c = new SkColor[stops];
-  for (int i = 0; i < stops; i++) {
-    p[i] = positions[i];
-    c[i] = GetColor(colors[i]).v;
-  }
-  LOGI("CreateRadialGradient(%f,%f,%f,%f,%f,%f,%d,[%f,%f],[%s,%s]",
-    x0, y0, r0, x1, y1, r1, stops, positions[0], positions[1],
-    colors[0], colors[1]);
-  SkShader* shader = SkGradientShader::CreateTwoPointRadial(
-      SkPoint::Make(x0, y0), r0, SkPoint::Make(x1, y1), r1,
-      c, p, stops, SkShader::kClamp_TileMode);
-  delete[] c;
-  delete[] p;
-  return shader;
-}
-
-SkShader* CanvasState::CreateLinearGradient(
-      double x0, double y0, double x1, double y1,
-      int stops, float* positions, char** colors) {
-  SkScalar* p = new SkScalar[stops];
-  SkColor* c = new SkColor[stops];
-  for (int i = 0; i < stops; i++) {
-    p[i] = positions[i];
-    c[i] = GetColor(colors[i]).v;
-  }
-  SkPoint pts[2];
-  pts[0] = SkPoint::Make(x0, y0);
-  pts[1] = SkPoint::Make(x1, y1);
-  SkShader* shader =  SkGradientShader::CreateLinear(pts, c, p, stops,
-      SkShader::kClamp_TileMode);
-  delete[] c;
-  delete[] p;
-  return shader;
-}
-
diff --git a/runtime/embedders/openglui/common/canvas_state.h b/runtime/embedders/openglui/common/canvas_state.h
deleted file mode 100644
index fc0e095..0000000
--- a/runtime/embedders/openglui/common/canvas_state.h
+++ /dev/null
@@ -1,312 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_
-#define EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_
-
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/opengl.h"
-#include "embedders/openglui/common/support.h"
-
-typedef struct CanvasState {
-  SkPaint paint_;
-  float globalAlpha_;
-  float miterLimit_;
-  ColorRGBA fillColor_;
-  ColorRGBA strokeColor_;
-  ColorRGBA shadowColor_;
-  float shadowBlur_;
-  float shadowOffsetX_;
-  float shadowOffsetY_;
-  float* lineDash_;
-  int lineDashCount_;
-  int lineDashOffset_;
-  SkShader* fillShader_;
-  SkShader* strokeShader_;
-
-  SkPath* path_;
-  SkCanvas* canvas_;
-  CanvasState* next_;  // For stack.
-
-  CanvasState(SkCanvas* canvas)
-    : paint_(),
-      globalAlpha_(1.0),
-      miterLimit_(10),
-      fillColor_(ColorRGBA(255, 0, 0, 255)),
-      strokeColor_(fillColor_),
-      shadowColor_(ColorRGBA(0, 0, 0, 0)),
-      shadowBlur_(0.0),
-      shadowOffsetX_(0.0),
-      shadowOffsetY_(0.0),
-      lineDash_(NULL),
-      lineDashCount_(0),
-      lineDashOffset_(0),
-      fillShader_(NULL),
-      strokeShader_(NULL),
-      path_(new SkPath()),
-      canvas_(canvas),
-      next_(NULL) {
-    paint_.setStrokeCap(SkPaint::kButt_Cap);
-    paint_.setStrokeJoin(SkPaint::kMiter_Join);
-    paint_.setStrokeWidth(1);
-    paint_.setTextAlign(SkPaint::kLeft_Align);
-    paint_.setAntiAlias(true);
-    paint_.setStyle(SkPaint::kStroke_Style);
-    setFont("Helvetica", 10);
-  }
-
-  CanvasState(const CanvasState& state)
-    : paint_(state.paint_),
-      globalAlpha_(state.globalAlpha_),
-      miterLimit_(state.miterLimit_),
-      fillColor_(state.fillColor_),
-      strokeColor_(state.strokeColor_),
-      shadowColor_(state.shadowColor_),
-      shadowBlur_(state.shadowBlur_),
-      shadowOffsetX_(state.shadowOffsetX_),
-      shadowOffsetY_(state.shadowOffsetY_),
-      lineDash_(NULL),
-      lineDashCount_(state.lineDashCount_),
-      lineDashOffset_(state.lineDashOffset_),
-      fillShader_(state.fillShader_),
-      strokeShader_(state.strokeShader_),
-      path_(new SkPath()),
-      canvas_(state.canvas_),
-      next_(NULL) {
-    setLineDash(state.lineDash_, lineDashCount_);
-    if (fillShader_ != NULL) fillShader_->ref();
-    if (strokeShader_ != NULL) strokeShader_->ref();
-  }
-
-  ~CanvasState() {
-    if (fillShader_ != NULL) fillShader_->unref();
-    if (strokeShader_ != NULL) strokeShader_->unref();
-    delete path_;
-    delete[] lineDash_;
-  }
-
-  static ColorRGBA GetColor(const char* color);
-
-  inline CanvasState* Save() {
-    canvas_->save();  // For clip and transform.
-    CanvasState *new_state = new CanvasState(*this);
-    new_state->next_ = this;
-    // If the old state has a non-empty path, use its
-    // last point as the new states first point.
-    int np = path_->countPoints();
-    if (np > 0) {
-      new_state->path_->moveTo(path_->getPoint(np-1));
-    }
-    return new_state;
-  }
-
-  CanvasState* Restore();
-
-  inline float Radians2Degrees(float angle) {
-    return 180.0 * angle / M_PI;
-  }
-
-  inline void setGlobalAlpha(float alpha) {
-    globalAlpha_ = alpha;
-  }
-
-  inline void setFillColor(const char* color) {
-    if (fillShader_ != NULL) {
-      fillShader_->unref();
-      fillShader_ = NULL;
-    }
-    fillColor_ = GetColor(color);
-  }
-
-  inline void setStrokeColor(const char* color) {
-    if (strokeShader_ != NULL) {
-      strokeShader_->unref();
-      strokeShader_ = NULL;
-    }
-    strokeColor_ = GetColor(color);
-  }
-
-  const char* setFont(const char*name, float size = -1);
-  void setLineCap(const char* lc);
-  void setLineJoin(const char* lj);
-
-  inline void setMiterLimit(float limit) {
-    miterLimit_ = limit;
-  }
-
-  const char* setTextAlign(const char* align);
-  const char* setTextBaseline(const char* baseline);
-  const char* setTextDirection(const char* direction);
-
-  inline void FillText(const char* text, float x, float y, float maxWidth) {
-    setFillMode();
-    canvas_->drawText(text, strlen(text), x, y, paint_);
-  }
-
-  inline void StrokeText(const char* text, float x, float y, float maxWidth) {
-    setStrokeMode();
-    canvas_->drawText(text, strlen(text), x, y, paint_);
-  }
-
-  inline float MeasureText(const char *text) {
-    // TODO(gram): make sure this is not supposed to be affected
-    // by the canvas transform.
-    return paint_.measureText(text, strlen(text));
-  }
-
-  inline void setLineWidth(float w) {
-    paint_.setStrokeWidth(w);
-  }
-
-  void setMode(SkPaint::Style style, ColorRGBA color, SkShader* shader);
-
-  inline void setLineDashEffect() {
-    if (lineDashCount_ > 0) {
-      SkDashPathEffect* dashPathEffect =
-        new SkDashPathEffect(lineDash_, lineDashCount_, lineDashOffset_);
-        paint_.setPathEffect(dashPathEffect)->unref();
-    } else {
-      paint_.setPathEffect(NULL);
-    }
-  }
-
-  inline void setLineDash(float* dashes, int len) {
-    if (len == 0) {
-      lineDashCount_ = 0;
-      delete[] lineDash_;
-      lineDash_ = NULL;
-    } else {
-      lineDash_ = new float[lineDashCount_ = len];
-      for (int i = 0; i < len; i++) {
-        lineDash_[i] = dashes[i];
-      }
-    }
-    setLineDashEffect();
-  }
-
-  inline void setLineDashOffset(int offset) {
-    if (offset != lineDashOffset_) {
-      lineDashOffset_ = offset;
-      setLineDashEffect();
-    }
-  }
-
-  inline void setShadowColor(const char* color) {
-    shadowColor_ = GetColor(color);
-  }
-
-  inline void setShadowBlur(float blur) {
-    shadowBlur_ = blur;
-  }
-
-  inline void setShadowOffsetX(float ox) {
-    shadowOffsetX_ = ox;
-  }
-
-  inline void setShadowOffsetY(float oy) {
-    shadowOffsetY_ = oy;
-  }
-
-  inline void setFillMode() {
-    setMode(SkPaint::kFill_Style, fillColor_, fillShader_);
-  }
-
-  inline void setStrokeMode() {
-    setMode(SkPaint::kStroke_Style, strokeColor_, strokeShader_);
-  }
-
-  inline void FillRect(float left, float top,
-                       float width, float height) {
-    // Does not affect the path.
-    setFillMode();
-    canvas_->drawRectCoords(left, top, left + width, top + height, paint_);
-  }
-
-  inline void StrokeRect(float left, float top,
-                         float width, float height) {
-    // Does not affect the path.
-    setStrokeMode();
-    canvas_->drawRectCoords(left, top, left + width, top + height, paint_);
-  }
-
-  inline void BeginPath() {
-    path_->rewind();
-  }
-
-  inline void Fill() {
-    setFillMode();
-    canvas_->drawPath(*path_, paint_);
-  }
-
-  inline void Stroke() {
-    setStrokeMode();
-    canvas_->drawPath(*path_, paint_);
-  }
-
-  inline void ClosePath() {
-    path_->close();
-  }
-
-  inline void MoveTo(float x, float y) {
-    path_->moveTo(x, y);
-  }
-
-  inline void LineTo(float x, float y) {
-    path_->lineTo(x, y);
-  }
-
-  void Arc(float x, float y, float radius, float startAngle, float endAngle,
-           bool antiClockwise);
-
-  inline void QuadraticCurveTo(float cpx, float cpy, float x, float y) {
-    path_->quadTo(cpx, cpy, x, y);
-  }
-
-  inline void BezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y,
-                     float x, float y) {
-    path_->cubicTo(cp1x, cp1y, cp2x, cp2y, x, y);
-  }
-
-  inline void ArcTo(float x1, float y1, float x2, float y2, float radius) {
-    path_->arcTo(x1, y1, x2, y2, radius);
-  }
-
-  inline void Rect(float x, float y, float w, float h) {
-    // TODO(gram): Should we draw this directly? If so, what happens with the
-    // path?
-    path_->addRect(x, y, x + w, y + h);
-  }
-
-  void setGlobalCompositeOperation(const char* op);
-
-  void DrawImage(const SkBitmap& bm,
-                 int sx, int sy, int sw, int sh,
-                 int dx, int dy, int dw, int dh);
-
-  inline void Clip() {
-    canvas_->clipPath(*path_);
-  }
-
-  void SetFillGradient(bool is_radial, double x0, double y0, double r0,
-      double x1, double y1, double r1,
-      int stops, float* positions, char** colors);
-
-  void SetStrokeGradient(bool is_radial, double x0, double y0, double r0,
-      double x1, double y1, double r1,
-      int stops, float* positions, char** colors);
-
- private:
-  SkShader* CreateRadialGradient(
-      double x0, double y0, double r0,
-      double x1, double y1, double r1,
-      int stops, float* positions, char** colors);
-
-  SkShader* CreateLinearGradient(
-      double x0, double y0, double x1, double y1,
-      int stops, float* positions, char** colors);
-} CanvasState;
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_
-
diff --git a/runtime/embedders/openglui/common/context.h b/runtime/embedders/openglui/common/context.h
deleted file mode 100644
index 54148fc..0000000
--- a/runtime/embedders/openglui/common/context.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_CONTEXT_H_
-#define EMBEDDERS_OPENGLUI_COMMON_CONTEXT_H_
-
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/input_handler.h"
-#include "embedders/openglui/common/sound_handler.h"
-#include "embedders/openglui/common/timer.h"
-#include "embedders/openglui/common/vm_glue.h"
-
-struct Context {
-  GraphicsHandler* graphics_handler;
-  InputHandler* input_handler;
-  SoundHandler* sound_handler;
-  Timer* timer;
-  VMGlue* vm_glue;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_CONTEXT_H_
-
diff --git a/runtime/embedders/openglui/common/dart_host.cc b/runtime/embedders/openglui/common/dart_host.cc
deleted file mode 100644
index dd2c1cd..0000000
--- a/runtime/embedders/openglui/common/dart_host.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/common/dart_host.h"
-
-#include <math.h>
-#include <unistd.h>
-
-#include "embedders/openglui/common/image_cache.h"
-#include "embedders/openglui/common/log.h"
-
-DartHost::DartHost(Context *context)
-    : graphics_handler_(context->graphics_handler),
-      input_handler_(context->input_handler),
-      sound_handler_(context->sound_handler),
-      timer_(context->timer),
-      vm_glue_(context->vm_glue),
-      has_context_(false),
-      started_(false),
-      active_(false) {
-  ImageCache::Init(graphics_handler_->resource_path());
-}
-
-DartHost::~DartHost() {
-}
-
-int32_t DartHost::OnStart() {
-  int result = vm_glue_->StartMainIsolate();
-  if (result != 0) {
-    LOGE("startMainIsolate returned %d", result);
-    return -1;
-  }
-  started_ = true;
-  return 0;
-}
-
-int32_t DartHost::Activate() {
-  if (!has_context_) {
-    if (graphics_handler_->Start() != 0) {
-      return -1;
-    }
-    if (sound_handler_->Start() != 0) {
-      graphics_handler_->Stop();
-      return -1;
-    }
-    if (input_handler_->Start() != 0) {
-      sound_handler_->Stop();
-      graphics_handler_->Stop();
-      return -1;
-    }
-    int32_t rtn = vm_glue_->CallSetup(true);
-    timer_->Reset();
-    has_context_ = true;
-    return rtn;
-  }
-  return 0;
-}
-
-void DartHost::Deactivate() {
-  Pause();
-  if (has_context_) {
-    vm_glue_->CallShutdown();
-    input_handler_->Stop();
-    sound_handler_->Stop();
-    graphics_handler_->Stop();
-    has_context_ = false;
-  }
-}
-
-int32_t DartHost::OnStep() {
-  if (active_) {
-    timer_->Update();
-    if (vm_glue_->CallUpdate() != 0 ||
-        graphics_handler_->Update() != 0) {
-      return -1;
-    }
-  }
-  return 0;
-}
-
-int32_t DartHost::Resume() {
-  if (!active_) {
-    if (Activate() == 0) {
-      sound_handler_->Resume();
-      active_ = true;
-    }
-  }
-  return 0;
-}
-
-void DartHost::Pause() {
-  if (active_) {
-    active_ = false;  // This stops update() calls.
-    sound_handler_->Suspend();
-  }
-}
-
-void DartHost::FreeAllResources() {
-  if (started_) {
-    vm_glue_->FinishMainIsolate();
-    started_ = false;
-  }
-}
-
-void DartHost::OnSaveState(void** data, size_t* size) {
-  LOGI("Saving DartHost state");
-}
-
-void DartHost::OnConfigurationChanged() {
-  LOGI("DartHost config changed");
-}
-
-void DartHost::OnLowMemory() {
-  LOGI("DartHost low on memory");
-}
-
diff --git a/runtime/embedders/openglui/common/dart_host.h b/runtime/embedders/openglui/common/dart_host.h
deleted file mode 100644
index 9233aa2f..0000000
--- a/runtime/embedders/openglui/common/dart_host.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_DART_HOST_H_
-#define EMBEDDERS_OPENGLUI_COMMON_DART_HOST_H_
-
-#include "embedders/openglui/common/context.h"
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/input_handler.h"
-#include "embedders/openglui/common/lifecycle_handler.h"
-#include "embedders/openglui/common/sound_handler.h"
-#include "embedders/openglui/common/timer.h"
-#include "embedders/openglui/common/vm_glue.h"
-#include "include/dart_api.h"
-
-class DartHost : public LifeCycleHandler {
- public:
-  explicit DartHost(Context* context);
-  virtual ~DartHost();
-
-  int32_t OnStart();
-  void OnSaveState(void** data, size_t* size);
-  void OnConfigurationChanged();
-  void OnLowMemory();
-  int32_t Activate();
-  void Deactivate();
-  void Pause();
-  int32_t Resume();
-  void FreeAllResources();
-  int32_t OnStep();
-
- private:
-  void Clear();
-
-  GraphicsHandler* graphics_handler_;
-  InputHandler* input_handler_;
-  SoundHandler* sound_handler_;
-  Timer* timer_;
-  VMGlue* vm_glue_;
-  bool has_context_;
-  bool started_;
-  bool active_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_DART_HOST_H_
-
diff --git a/runtime/embedders/openglui/common/events.h b/runtime/embedders/openglui/common/events.h
deleted file mode 100644
index 64c6951..0000000
--- a/runtime/embedders/openglui/common/events.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_EVENTS_H_
-#define EMBEDDERS_OPENGLUI_COMMON_EVENTS_H_
-
-typedef enum {
-  kStart,
-  kStop,
-  kGainedFocus,
-  kLostFocus,
-  kPause,
-  kResume,
-  kSaveState,
-  kConfigChanged,
-  kInitWindow,
-  kTermWindow,
-  kDestroy
-} LifecycleEvent;
-
-typedef enum {
-  kKeyDown,
-  kKeyUp,
-  kKeyMultiple
-} KeyEvent;
-
-typedef enum {
-  kMotionDown,
-  kMotionUp,
-  kMotionMove,
-  kMotionCancel,
-  kMotionOutside,
-  kMotionPointerDown,
-  kMotionPointerUp
-} MotionEvent;
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_EVENTS_H_
-
diff --git a/runtime/embedders/openglui/common/extension.cc b/runtime/embedders/openglui/common/extension.cc
deleted file mode 100644
index 6304c3b..0000000
--- a/runtime/embedders/openglui/common/extension.cc
+++ /dev/null
@@ -1,1737 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/common/extension.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "embedders/openglui/common/canvas_context.h"
-#include "embedders/openglui/common/image_cache.h"
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/opengl.h"
-#include "include/dart_api.h"
-#include "include/dart_native_api.h"
-
-Dart_Handle HandleError(Dart_Handle handle) {
-  if (Dart_IsError(handle)) Dart_PropagateError(handle);
-  return handle;
-}
-
-void CheckGLError(const char *function) {
-  int error = glGetError();
-  if (error != GL_NO_ERROR) {
-    if (error == GL_INVALID_ENUM) {
-      LOGE("%s: An unacceptable value is given for an enumerated argument.",
-           function);
-    } else if (error == GL_INVALID_VALUE) {
-      LOGE("%s: A numeric argument is out of range.", function);
-    } else if (error == GL_INVALID_OPERATION) {
-      LOGE("%s: The specified operation is not allowed in the current state.",
-           function);
-    } else if (error == GL_INVALID_FRAMEBUFFER_OPERATION) {
-      LOGE("%s: The framebuffer object is not complete.", function);
-    } else if (error == GL_OUT_OF_MEMORY) {
-      LOGE("%s: There is not enough memory left to execute the command.",
-          function);
-    } else {
-      LOGE("ERROR!: %s returns %d", function, error);
-    }
-  }
-}
-
-const char* GetArgAsString(Dart_NativeArguments arguments, int idx) {
-  Dart_Handle handle = HandleError(Dart_GetNativeArgument(arguments, idx));
-  uint8_t* str;
-  intptr_t length;
-  HandleError(Dart_StringLength(handle, &length));
-  HandleError(Dart_StringToUTF8(handle, &str, &length));
-  str[length] = 0;
-  return  const_cast<const char*>(reinterpret_cast<char*>(str));
-}
-
-double GetArgAsDouble(Dart_NativeArguments arguments, int index) {
-  Dart_Handle handle = HandleError(Dart_GetNativeArgument(arguments, index));
-  if (Dart_IsDouble(handle)) {
-    double v;
-    HandleError(Dart_DoubleValue(handle, &v));
-    return v;
-  }
-  if (Dart_IsInteger(handle)) {
-    int64_t v;
-    HandleError(Dart_IntegerToInt64(handle, &v));
-    return static_cast<double>(v);
-  }
-  LOGE("Argument at index %d has non-numeric type", index);
-  Dart_ThrowException(Dart_NewStringFromCString("Numeric argument expected."));
-  return 0;
-}
-
-int64_t GetArgAsInt(Dart_NativeArguments arguments, int index) {
-  Dart_Handle handle = HandleError(Dart_GetNativeArgument(arguments, index));
-  if (Dart_IsDouble(handle)) {
-    double v;
-    HandleError(Dart_DoubleValue(handle, &v));
-    return static_cast<int64_t>(v);
-  }
-  if (Dart_IsInteger(handle)) {
-    int64_t v;
-    HandleError(Dart_IntegerToInt64(handle, &v));
-    return v;
-  }
-  LOGE("Argument at index %d has non-numeric type", index);
-  Dart_ThrowException(Dart_NewStringFromCString("Numeric argument expected."));
-  return 0;
-}
-
-bool GetArgAsBool(Dart_NativeArguments arguments, int index) {
-  Dart_Handle handle = HandleError(Dart_GetNativeArgument(arguments, index));
-  if (Dart_IsBoolean(handle)) {
-    bool v;
-    HandleError(Dart_BooleanValue(handle, &v));
-    return v;
-  }
-  LOGI("Argument at index %d has non-Boolean type", index);
-  Dart_ThrowException(Dart_NewStringFromCString("Boolean argument expected."));
-  return false;
-}
-
-int GetListLength(Dart_NativeArguments arguments, int index,
-    Dart_Handle& argHandle) {
-  argHandle = HandleError(Dart_GetNativeArgument(arguments, index));
-  if (Dart_IsList(argHandle)) {
-    intptr_t len;
-    HandleError(Dart_ListLength(argHandle, &len));
-    return len;
-  }
-  LOGI("Argument at index %d has non-List type", index);
-  Dart_ThrowException(Dart_NewStringFromCString("List argument expected."));
-  return -1;
-}
-
-GLint* GetArgsAsGLintList(Dart_NativeArguments arguments, int index,
-                          int* len_out) {
-  Dart_Handle argHandle;
-  int len = GetListLength(arguments, index, argHandle);
-  if (len < 0) return NULL;
-  GLint* list = new GLint[len];
-  for (int i = 0; i < len; i++) {
-    Dart_Handle vHandle = Dart_ListGetAt(argHandle, i);
-    int64_t v;
-    HandleError(Dart_IntegerToInt64(vHandle, &v));
-    list[i] = v;
-  }
-  *len_out = len;
-  return list;
-}
-
-GLfloat* GetArgsAsFloatList(Dart_NativeArguments arguments, int index,
-                            int* len_out) {
-  Dart_Handle argHandle;
-  int len = GetListLength(arguments, index, argHandle);
-  if (len < 0) return NULL;
-  GLfloat* list = new GLfloat[len];
-  for (int i = 0; i < len; i++) {
-    Dart_Handle vHandle = Dart_ListGetAt(argHandle, i);
-    double v;
-    HandleError(Dart_DoubleValue(vHandle, &v));
-    list[i] = v;
-  }
-  *len_out = len;
-  return list;
-}
-
-char** GetArgsAsStringList(Dart_NativeArguments arguments, int index,
-                            int* len_out) {
-  Dart_Handle argHandle;
-  int len = GetListLength(arguments, index, argHandle);
-  if (len < 0) return NULL;
-  char** list = new char*[len];
-  for (int i = 0; i < len; i++) {
-    Dart_Handle vHandle = Dart_ListGetAt(argHandle, i);
-    uint8_t* str;
-    intptr_t length;
-    HandleError(Dart_StringLength(vHandle, &length));
-    HandleError(Dart_StringToUTF8(vHandle, &str, &length));
-    str[length] = 0;
-    list[i] = reinterpret_cast<char*>(str);
-  }
-  *len_out = len;
-  return list;
-}
-
-void SetBoolReturnValue(Dart_NativeArguments arguments, bool b) {
-  Dart_Handle result = HandleError(Dart_NewBoolean(b));
-  Dart_SetReturnValue(arguments, result);
-}
-
-void SetIntReturnValue(Dart_NativeArguments arguments, int v) {
-  Dart_Handle result = HandleError(Dart_NewInteger(v));
-  Dart_SetReturnValue(arguments, result);
-}
-
-void SetDoubleReturnValue(Dart_NativeArguments arguments, double v) {
-  Dart_Handle result = HandleError(Dart_NewDouble(v));
-  Dart_SetReturnValue(arguments, result);
-}
-
-void SetStringReturnValue(Dart_NativeArguments arguments, const char* s) {
-  Dart_Handle result = HandleError(Dart_NewStringFromCString(s));
-  Dart_SetReturnValue(arguments, result);
-}
-
-void Log(Dart_NativeArguments arguments) {
-  Dart_EnterScope();
-  LOGI("%s", GetArgAsString(arguments, 0));
-  Dart_ExitScope();
-}
-
-void LogError(Dart_NativeArguments arguments) {
-  Dart_EnterScope();
-  LOGE("%s", GetArgAsString(arguments, 0));
-  Dart_ExitScope();
-}
-
-void SystemRand(Dart_NativeArguments arguments) {
-  Dart_EnterScope();
-  SetIntReturnValue(arguments, rand());
-  Dart_ExitScope();
-}
-
-void SystemSrand(Dart_NativeArguments arguments) {
-  Dart_EnterScope();
-  bool success = false;
-  Dart_Handle seed_object = HandleError(Dart_GetNativeArgument(arguments, 0));
-  if (Dart_IsInteger(seed_object)) {
-    bool fits;
-    HandleError(Dart_IntegerFitsIntoInt64(seed_object, &fits));
-    if (fits) {
-      int64_t seed;
-      HandleError(Dart_IntegerToInt64(seed_object, &seed));
-      srand(static_cast<unsigned>(seed));
-      success = true;
-    }
-  }
-  SetBoolReturnValue(arguments, success);
-  Dart_ExitScope();
-}
-
-void GetDeviceScreenWidth(Dart_NativeArguments arguments) {
-  LOGI("GetDeviceScreenWidth");
-  Dart_EnterScope();
-  SetIntReturnValue(arguments, graphics->width());
-  Dart_ExitScope();
-}
-
-void GetDeviceScreenHeight(Dart_NativeArguments arguments) {
-  LOGI("GetDeviceScreenHeight");
-  Dart_EnterScope();
-  SetIntReturnValue(arguments, graphics->height());
-  Dart_ExitScope();
-}
-
-void SwapBuffers(Dart_NativeArguments arguments) {
-  LOGI("SwapBuffers");
-  Dart_EnterScope();
-  GLSwapBuffers();
-  CheckGLError("GLSwapBuffers");
-  Dart_ExitScope();
-}
-
-void GLAttachShader(Dart_NativeArguments arguments) {
-  LOGI("GLAttachShader");
-  Dart_EnterScope();
-
-  int64_t program = GetArgAsInt(arguments, 0);
-  int64_t shader = GetArgAsInt(arguments, 1);
-
-  glAttachShader(program, shader);
-  CheckGLError("glAttachShader");
-  Dart_ExitScope();
-}
-
-void GLBindBuffer(Dart_NativeArguments arguments) {
-  LOGI("GLBindBuffer");
-  Dart_EnterScope();
-
-  int64_t target = GetArgAsInt(arguments, 0);
-  int64_t buffer = GetArgAsInt(arguments, 1);
-
-  glBindBuffer(target, buffer);
-  CheckGLError("glBindBuffer");
-  Dart_ExitScope();
-}
-
-void GLBufferData(Dart_NativeArguments arguments) {
-  LOGI("GLBufferData");
-  Dart_EnterScope();
-
-  int64_t target = GetArgAsInt(arguments, 0);
-
-  Dart_Handle dataHandle = HandleError(Dart_GetNativeArgument(arguments, 1));
-  intptr_t size;
-  HandleError(Dart_ListLength(dataHandle, &size));
-
-  LOGI("Size: %d", static_cast<int>(size));
-
-  // TODO(vsm): No guarantee that this is a float!
-  float* data = new float[size];
-  for (int i = 0; i < size; i++) {
-    Dart_Handle elemHandle = HandleError(Dart_ListGetAt(dataHandle, i));
-    double value;
-    Dart_DoubleValue(elemHandle, &value);
-    data[i] = static_cast<float>(value);
-    LOGI("Value[%d]: %f", i, data[i]);
-  }
-
-  Dart_Handle usageHandle = HandleError(Dart_GetNativeArgument(arguments, 2));
-  int64_t usage;
-  HandleError(Dart_IntegerToInt64(usageHandle, &usage));
-
-  glBufferData(target, size * sizeof(data[0]), data, usage);
-  CheckGLError("glBufferData");
-  delete[] data;
-  Dart_ExitScope();
-}
-
-void GLCompileShader(Dart_NativeArguments arguments) {
-  LOGI("GLCompileShader");
-  Dart_EnterScope();
-  int64_t shader = GetArgAsInt(arguments, 0);
-  glCompileShader(shader);
-  CheckGLError("glCompileShader");
-  Dart_ExitScope();
-}
-
-void GLCreateBuffer(Dart_NativeArguments arguments) {
-  LOGI("GLCreateBuffer");
-  Dart_EnterScope();
-  GLuint buffer;
-  glGenBuffers(1, &buffer);
-  CheckGLError("glGenBuffers");
-  SetIntReturnValue(arguments, buffer);
-  Dart_ExitScope();
-}
-
-void GLCreateProgram(Dart_NativeArguments arguments) {
-  LOGI("GLCreateProgram");
-  Dart_EnterScope();
-  int64_t program = glCreateProgram();
-  CheckGLError("glCreateProgram");
-  SetIntReturnValue(arguments, program);
-  Dart_ExitScope();
-}
-
-void GLCreateShader(Dart_NativeArguments arguments) {
-  LOGI("GLCreateShader");
-  Dart_EnterScope();
-  int64_t type = GetArgAsInt(arguments, 0);
-  int64_t shader = glCreateShader((GLenum)type);
-  CheckGLError("glCreateShader");
-  SetIntReturnValue(arguments, shader);
-  Dart_ExitScope();
-}
-
-void GLDrawArrays(Dart_NativeArguments arguments) {
-  LOGI("GLDrawArrays");
-  Dart_EnterScope();
-
-  int64_t mode = GetArgAsInt(arguments, 0);
-  int64_t first = GetArgAsInt(arguments, 1);
-  int64_t count = GetArgAsInt(arguments, 2);
-
-  glDrawArrays(mode, first, count);
-  CheckGLError("glDrawArrays");
-  Dart_ExitScope();
-  LOGI("Done GLDrawArrays");
-}
-
-void GLEnableVertexAttribArray(Dart_NativeArguments arguments) {
-  LOGI("GLEnableVertexAttribArray");
-  Dart_EnterScope();
-
-  int64_t location = GetArgAsInt(arguments, 0);
-
-  glEnableVertexAttribArray(location);
-  CheckGLError("glEnableVertexAttribArray");
-  Dart_ExitScope();
-}
-
-void GLGetAttribLocation(Dart_NativeArguments arguments) {
-  LOGI("GLGetAttribLocation");
-  Dart_EnterScope();
-
-  int64_t program = GetArgAsInt(arguments, 0);
-
-  Dart_Handle nameHandle = HandleError(Dart_GetNativeArgument(arguments, 1));
-  intptr_t length;
-  HandleError(Dart_StringLength(nameHandle, &length));
-  uint8_t* str;
-  HandleError(Dart_StringToUTF8(nameHandle, &str, &length));
-  str[length] = 0;
-
-  int64_t location = glGetAttribLocation(program,
-      const_cast<const GLchar*>(reinterpret_cast<GLchar*>(str)));
-  CheckGLError("glGetAttribLocation");
-  SetIntReturnValue(arguments, location);
-  Dart_ExitScope();
-}
-
-void GLGetError(Dart_NativeArguments arguments) {
-  LOGI("GLGetError");
-  Dart_EnterScope();
-  SetIntReturnValue(arguments, glGetError());
-  Dart_ExitScope();
-}
-
-void GLGetProgramParameter(Dart_NativeArguments arguments) {
-  LOGI("GLGetProgramParameter");
-  Dart_EnterScope();
-
-  int64_t program = GetArgAsInt(arguments, 0);
-  int64_t param = GetArgAsInt(arguments, 1);
-
-  GLint value = -1;
-  glGetProgramiv(program, param, &value);
-  CheckGLError("glGetProgramiv");
-
-  SetIntReturnValue(arguments, value);
-  Dart_ExitScope();
-}
-
-void GLGetShaderParameter(Dart_NativeArguments arguments) {
-  LOGI("GLGetShaderParameter");
-  Dart_EnterScope();
-
-  int64_t shader = GetArgAsInt(arguments, 0);
-  int64_t param = GetArgAsInt(arguments, 1);
-
-  GLint value = -1;
-  glGetShaderiv((GLuint)shader, (GLenum)param, &value);
-  CheckGLError("glGetShaderiv");
-
-  SetIntReturnValue(arguments, value);
-  Dart_ExitScope();
-}
-
-void GLGetShaderInfoLog(Dart_NativeArguments arguments) {
-  LOGI("GLGetShaderInfoLog");
-  Dart_EnterScope();
-
-  int64_t shader = GetArgAsInt(arguments, 0);
-
-  GLint infoLogLength = 0;
-  glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
-  GLchar* strInfoLog = new GLchar[infoLogLength + 1];
-  glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
-  strInfoLog[infoLogLength] = 0;
-
-  SetStringReturnValue(arguments, strInfoLog);
-  Dart_ExitScope();
-  delete[] strInfoLog;
-}
-
-void GLGetProgramInfoLog(Dart_NativeArguments arguments) {
-  LOGI("GLGetProgramInfoLog");
-  Dart_EnterScope();
-
-  int64_t program = GetArgAsInt(arguments, 0);
-
-  GLint infoLogLength;
-  glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
-
-  GLchar* strInfoLog = new GLchar[infoLogLength + 1];
-  glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
-  strInfoLog[infoLogLength] = 0;
-
-  SetStringReturnValue(arguments, strInfoLog);
-  Dart_ExitScope();
-  delete[] strInfoLog;
-}
-
-void GLGetUniformLocation(Dart_NativeArguments arguments) {
-  LOGI("GLGetUniformLocation");
-  Dart_EnterScope();
-
-  int64_t program = GetArgAsInt(arguments, 0);
-
-
-  Dart_Handle nameHandle = HandleError(Dart_GetNativeArgument(arguments, 1));
-  intptr_t length;
-  HandleError(Dart_StringLength(nameHandle, &length));
-  uint8_t* str;
-  HandleError(Dart_StringToUTF8(nameHandle, &str, &length));
-  str[length] = 0;
-
-  int64_t location = glGetUniformLocation(program,
-      const_cast<const GLchar*>(reinterpret_cast<GLchar*>(str)));
-  CheckGLError("glGetUniformLocation");
-  SetIntReturnValue(arguments, location);
-  Dart_ExitScope();
-}
-
-void GLLinkProgram(Dart_NativeArguments arguments) {
-  LOGI("GLLinkProgram");
-  Dart_EnterScope();
-  int64_t program = GetArgAsInt(arguments, 0);
-  glLinkProgram(program);
-  CheckGLError("glLinkProgram");
-  Dart_ExitScope();
-}
-
-void GLShaderSource(Dart_NativeArguments arguments) {
-  LOGI("GLShaderSource");
-  Dart_EnterScope();
-
-  int64_t shader = GetArgAsInt(arguments, 0);
-
-  Dart_Handle sourceHandle = HandleError(Dart_GetNativeArgument(arguments, 1));
-  intptr_t length[1];
-  HandleError(Dart_StringLength(sourceHandle, length));
-  LOGI("Source length is %d", static_cast<int>(length[0]));
-  uint8_t* str[1];
-  HandleError(Dart_StringToUTF8(sourceHandle, &str[0], length));
-  LOGI("Converted length is %d", static_cast<int>(length[0]));
-  str[0][*length] = 0;
-
-  LOGI("Source: %s",
-      const_cast<const GLchar*>(reinterpret_cast<GLchar*>(str[0])));
-  glShaderSource(shader, 1,
-      const_cast<const GLchar**>(reinterpret_cast<GLchar**>(str)), NULL);
-  CheckGLError("glShaderSource");
-  Dart_ExitScope();
-}
-
-void GLUseProgram(Dart_NativeArguments arguments) {
-  LOGI("GLUseProgram");
-  Dart_EnterScope();
-  int64_t program = GetArgAsInt(arguments, 0);
-  glUseProgram(program);
-  CheckGLError("glUseProgram");
-  Dart_ExitScope();
-}
-
-void GLUniform1i(Dart_NativeArguments arguments) {
-  LOGI("GLUniform1i");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  int64_t v0 = GetArgAsInt(arguments, 1);
-  glUniform1i(location, v0);
-  CheckGLError("glUniform1i");
-  Dart_ExitScope();
-}
-
-void GLUniform2i(Dart_NativeArguments arguments) {
-  LOGI("GLUniform2i");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  int64_t v0 = GetArgAsInt(arguments, 1);
-  int64_t v1 = GetArgAsInt(arguments, 2);
-  glUniform2i(location, v0, v1);
-  CheckGLError("glUniform2i");
-  Dart_ExitScope();
-}
-
-void GLUniform3i(Dart_NativeArguments arguments) {
-  LOGI("GLUniform3i");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  int64_t v0 = GetArgAsInt(arguments, 1);
-  int64_t v1 = GetArgAsInt(arguments, 2);
-  int64_t v2 = GetArgAsInt(arguments, 3);
-  glUniform3i(location, v0, v1, v2);
-  CheckGLError("glUniform3i");
-  Dart_ExitScope();
-}
-
-void GLUniform4i(Dart_NativeArguments arguments) {
-  LOGI("GLUniform4i");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  int64_t v0 = GetArgAsInt(arguments, 1);
-  int64_t v1 = GetArgAsInt(arguments, 2);
-  int64_t v2 = GetArgAsInt(arguments, 3);
-  int64_t v3 = GetArgAsInt(arguments, 4);
-  glUniform4i(location, v0, v1, v2, v3);
-  CheckGLError("glUniform4i");
-  Dart_ExitScope();
-}
-
-void GLUniform1f(Dart_NativeArguments arguments) {
-  LOGI("GLUniform1f");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  double v0 = GetArgAsDouble(arguments, 1);
-  glUniform1f(location, v0);
-  CheckGLError("glUniform1f");
-  Dart_ExitScope();
-}
-
-void GLUniform2f(Dart_NativeArguments arguments) {
-  LOGI("GLUniform2f");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  double v0 = GetArgAsDouble(arguments, 1);
-  double v1 = GetArgAsDouble(arguments, 2);
-  glUniform2f(location, v0, v1);
-  CheckGLError("glUniform2f");
-  Dart_ExitScope();
-}
-
-void GLUniform3f(Dart_NativeArguments arguments) {
-  LOGI("GLUniform3f");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  double v0 = GetArgAsDouble(arguments, 1);
-  double v1 = GetArgAsDouble(arguments, 2);
-  double v2 = GetArgAsDouble(arguments, 3);
-  glUniform3f(location, v0, v1, v2);
-  CheckGLError("glUniform3f");
-  Dart_ExitScope();
-}
-
-void GLUniform4f(Dart_NativeArguments arguments) {
-  LOGI("GLUniform4f");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  double v0 = GetArgAsDouble(arguments, 1);
-  double v1 = GetArgAsDouble(arguments, 2);
-  double v2 = GetArgAsDouble(arguments, 3);
-  double v3 = GetArgAsDouble(arguments, 4);
-  glUniform4f(location, v0, v1, v2, v3);
-  CheckGLError("glUniform4f");
-  Dart_ExitScope();
-}
-
-void GLUniform1iv(Dart_NativeArguments arguments) {
-  LOGI("GLUniform1iv");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  int len;
-  GLint* list = GetArgsAsGLintList(arguments, 1, &len);
-  if (list != NULL) {
-    glUniform1iv(location, len, list);
-    delete [] list;
-    CheckGLError("glUniform1iv");
-  }
-  Dart_ExitScope();
-}
-
-void GLUniform2iv(Dart_NativeArguments arguments) {
-  LOGI("GLUniform2iv");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  int len;
-  GLint* list = GetArgsAsGLintList(arguments, 1, &len);
-  if (list != NULL) {
-    glUniform2iv(location, len / 2, list);
-    delete [] list;
-    CheckGLError("glUniform2iv");
-  }
-  Dart_ExitScope();
-}
-
-void GLUniform3iv(Dart_NativeArguments arguments) {
-  LOGI("GLUniform3iv");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  int len;
-  GLint* list = GetArgsAsGLintList(arguments, 1, &len);
-  if (list != NULL) {
-    glUniform3iv(location, len / 3, list);
-    delete [] list;
-    CheckGLError("glUniform3iv");
-  }
-  Dart_ExitScope();
-}
-
-void GLUniform4iv(Dart_NativeArguments arguments) {
-  LOGI("GLUniform4iv");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  int len;
-  GLint* list = GetArgsAsGLintList(arguments, 1, &len);
-  if (list != NULL) {
-    glUniform1iv(location, len / 4, list);
-    delete [] list;
-    CheckGLError("glUniform4iv");
-  }
-  Dart_ExitScope();
-}
-
-void GLUniform1fv(Dart_NativeArguments arguments) {
-  LOGI("GLUniform1fv");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  int len;
-  GLfloat* list = GetArgsAsFloatList(arguments, 1, &len);
-  if (list != NULL) {
-    glUniform1fv(location, len, list);
-    delete [] list;
-    CheckGLError("glUniform1fv");
-  }
-  Dart_ExitScope();
-}
-
-void GLUniform2fv(Dart_NativeArguments arguments) {
-  LOGI("GLUniform2fv");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  int len;
-  GLfloat* list = GetArgsAsFloatList(arguments, 1, &len);
-  if (list != NULL) {
-    glUniform2fv(location, len / 2, list);
-    delete [] list;
-    CheckGLError("glUniform2fv");
-  }
-  Dart_ExitScope();
-}
-
-void GLUniform3fv(Dart_NativeArguments arguments) {
-  LOGI("GLUniform3fv");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  int len;
-  GLfloat* list = GetArgsAsFloatList(arguments, 1, &len);
-  if (list != NULL) {
-    glUniform3fv(location, len / 3, list);
-    delete [] list;
-    CheckGLError("glUniform3fv");
-  }
-  Dart_ExitScope();
-}
-
-void GLUniform4fv(Dart_NativeArguments arguments) {
-  LOGI("In GLUniform4fv");
-  Dart_EnterScope();
-  int64_t location = GetArgAsInt(arguments, 0);
-  int len;
-  GLfloat* list = GetArgsAsFloatList(arguments, 1, &len);
-  if (list != NULL) {
-    glUniform4fv(location, len / 4, list);
-    delete [] list;
-    CheckGLError("glUniform4fv");
-  }
-  Dart_ExitScope();
-}
-
-void GLViewport(Dart_NativeArguments arguments) {
-  LOGI("GLViewport");
-  Dart_EnterScope();
-  int64_t x = GetArgAsInt(arguments, 0);
-  int64_t y = GetArgAsInt(arguments, 1);
-  int64_t width = GetArgAsInt(arguments, 2);
-  int64_t height = GetArgAsInt(arguments, 3);
-  glViewport(x, y, width, height);
-  CheckGLError("glViewPort");
-  Dart_ExitScope();
-}
-
-void GLVertexAttribPointer(Dart_NativeArguments arguments) {
-  LOGI("GLVertexAttribPointer");
-  Dart_EnterScope();
-  int64_t index = GetArgAsInt(arguments, 0);
-  int64_t size = GetArgAsInt(arguments, 1);
-  int64_t type = GetArgAsInt(arguments, 2);
-  bool normalized = GetArgAsBool(arguments, 3);
-  int64_t stride = GetArgAsInt(arguments, 4);
-
-  Dart_Handle pointerHandle = HandleError(Dart_GetNativeArgument(arguments, 5));
-  int64_t pointerValue;
-  HandleError(Dart_IntegerToInt64(pointerHandle, &pointerValue));
-  const void* pointer;
-  pointer = const_cast<const void*>(reinterpret_cast<void*>(pointerValue));
-
-  glVertexAttribPointer(index, size, type, normalized, stride, pointer);
-  CheckGLError("glVertexAttribPointer");
-  Dart_ExitScope();
-}
-
-void GLClearColor(Dart_NativeArguments arguments) {
-  LOGI("GLClearColor");
-  Dart_EnterScope();
-  double red = GetArgAsDouble(arguments, 0);
-  double green = GetArgAsDouble(arguments, 1);
-  double blue = GetArgAsDouble(arguments, 2);
-  double alpha = GetArgAsDouble(arguments, 3);
-  glClearColor(red, green, blue, alpha);
-  CheckGLError("glClearColor");
-  Dart_ExitScope();
-}
-
-void GLClearDepth(Dart_NativeArguments arguments) {
-  LOGI("GLClearDepth");
-  Dart_EnterScope();
-  double depth = GetArgAsDouble(arguments, 0);
-#if defined(__ANDROID__)
-  glClearDepthf(depth);
-#else
-  glClearDepth(depth);
-#endif
-  CheckGLError("glClearDepth");
-  Dart_ExitScope();
-}
-
-void GLClear(Dart_NativeArguments arguments) {
-  LOGI("GLClear");
-  Dart_EnterScope();
-  Dart_Handle maskHandle = HandleError(Dart_GetNativeArgument(arguments, 0));
-  int64_t mask;
-  HandleError(Dart_IntegerToInt64(maskHandle, &mask));
-  glClear(mask);
-  CheckGLError("glClear");
-  Dart_ExitScope();
-}
-
-void ReturnGLIntConstant(Dart_NativeArguments arguments, int c) {
-  Dart_EnterScope();
-  SetIntReturnValue(arguments, c);
-  Dart_ExitScope();
-}
-
-void GLArrayBuffer(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_ARRAY_BUFFER);
-}
-
-void GLColorBufferBit(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_COLOR_BUFFER_BIT);
-}
-
-void GLCompileStatus(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_COMPILE_STATUS);
-}
-
-void GLDeleteStatus(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_DELETE_STATUS);
-}
-
-void GLDepthBufferBit(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_DEPTH_BUFFER_BIT);
-}
-
-void GLFloat(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_FLOAT);
-}
-
-void GLFragmentShader(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_FRAGMENT_SHADER);
-}
-
-void GLLinkStatus(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_LINK_STATUS);
-}
-
-void GLStaticDraw(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_STATIC_DRAW);
-}
-
-void GLTriangleStrip(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_TRIANGLE_STRIP);
-}
-
-void GLTriangles(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_TRIANGLES);
-}
-
-void GLTrue(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_TRUE);
-}
-
-void GLValidateStatus(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_VALIDATE_STATUS);
-}
-
-void GLVertexShader(Dart_NativeArguments arguments) {
-  ReturnGLIntConstant(arguments, GL_VERTEX_SHADER);
-}
-
-uint8_t* RandomArray(int seed, int length) {
-  if (length <= 0 || length > 10000000) return NULL;
-  uint8_t* values = reinterpret_cast<uint8_t*>(malloc(length));
-  if (NULL == values) return NULL;
-  srand(seed);
-  for (int i = 0; i < length; ++i) {
-    values[i] = rand() % 256;
-  }
-  return values;
-}
-
-void WrappedRandomArray(Dart_Port dest_port_id,
-                        Dart_Port reply_port_id,
-                        Dart_CObject* message) {
-  if (message->type == Dart_CObject_kArray &&
-      2 == message->value.as_array.length) {
-    // Use .as_array and .as_int32 to access the data in the Dart_CObject.
-    Dart_CObject* param0 = message->value.as_array.values[0];
-    Dart_CObject* param1 = message->value.as_array.values[1];
-    if (param0->type == Dart_CObject_kInt32 &&
-        param1->type == Dart_CObject_kInt32) {
-      int length = param0->value.as_int32;
-      int seed = param1->value.as_int32;
-
-      uint8_t* values = RandomArray(seed, length);
-
-      if (values != NULL) {
-        Dart_CObject result;
-        result.type = Dart_CObject_kTypedData;
-        result.value.as_typed_data.type = Dart_TypedData_kUint8;
-        result.value.as_typed_data.values = values;
-        result.value.as_typed_data.length = length;
-        Dart_PostCObject(reply_port_id, &result);
-        free(values);
-        // It is OK that result is destroyed when function exits.
-        // Dart_PostCObject has copied its data.
-        return;
-      }
-    }
-  }
-  Dart_CObject result;
-  result.type = Dart_CObject_kNull;
-  Dart_PostCObject(reply_port_id, &result);
-}
-
-void RandomArrayServicePort(Dart_NativeArguments arguments) {
-  Dart_EnterScope();
-  Dart_SetReturnValue(arguments, Dart_Null());
-  Dart_Port service_port =
-      Dart_NewNativePort("RandomArrayService", WrappedRandomArray, true);
-  if (service_port != ((Dart_Port)0)) {
-    Dart_Handle send_port = HandleError(Dart_NewSendPort(service_port));
-    Dart_SetReturnValue(arguments, send_port);
-  }
-  Dart_ExitScope();
-}
-
-void PlayBackground(Dart_NativeArguments arguments) {
-  LOGI("PlayBackground");
-  Dart_EnterScope();
-  const char* what = GetArgAsString(arguments, 0);
-  int rtn = PlayBackgroundSound(what);
-  SetIntReturnValue(arguments, rtn);
-  Dart_ExitScope();
-}
-
-void StopBackground(Dart_NativeArguments arguments) {
-  LOGI("StopBackground");
-  Dart_EnterScope();
-  StopBackgroundSound();
-  Dart_ExitScope();
-}
-
-void LoadSample(Dart_NativeArguments arguments) {
-  LOGI("LoadSample");
-  Dart_EnterScope();
-  const char* what = GetArgAsString(arguments, 0);
-  int rtn = LoadSoundSample(what);
-  SetIntReturnValue(arguments, rtn);
-  Dart_ExitScope();
-}
-
-void PlaySample(Dart_NativeArguments arguments) {
-  LOGI("PlaySample");
-  Dart_EnterScope();
-  const char* what = GetArgAsString(arguments, 0);
-  int rtn = PlaySoundSample(what);
-  SetIntReturnValue(arguments, rtn);
-  Dart_ExitScope();
-}
-
-// 2D Canvas.
-
-CanvasContext* display_context = NULL;
-
-void C2DCreateNativeContext(Dart_NativeArguments arguments) {
-  LOGI("In C2DCreateNativeContext");
-  Dart_EnterScope();
-
-  int handle = GetArgAsInt(arguments, 0);
-  int width = GetArgAsInt(arguments, 1);
-  int height = GetArgAsInt(arguments, 2);
-
-  CanvasContext* rtn = new CanvasContext(handle, width, height);
-  if (display_context == NULL) {
-    LOGI("Created display context");
-    display_context = rtn;
-  }
-  Dart_ExitScope();
-  LOGI("Out C2DCreateNativeContext");
-}
-
-void C2DSetWidth(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetWidth");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  int width = GetArgAsInt(arguments, 1);
-  SetIntReturnValue(arguments, Context2D(handle)->setWidth(width));
-  Dart_ExitScope();
-  LOGI("Out C2DSetWidth");
-}
-
-void C2DSetHeight(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetHeight");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  int height = GetArgAsInt(arguments, 1);
-  SetIntReturnValue(arguments, Context2D(handle)->setHeight(height));
-  Dart_ExitScope();
-  LOGI("Out C2DSetHeight");
-}
-
-void C2DSetGlobalAlpha(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetGlobalAlpha");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double alpha = GetArgAsDouble(arguments, 1);
-  alpha = MIN(1.0, MAX(alpha, 0.0));
-  Context2D(handle)->setGlobalAlpha(alpha);
-  SetDoubleReturnValue(arguments, alpha);
-  Dart_ExitScope();
-  LOGI("Out C2DSetGlobalAlpha");
-}
-
-void C2DSetFillStyle(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetFillStyle");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* color = GetArgAsString(arguments, 1);
-  Context2D(handle)->setFillColor(color);
-  Dart_ExitScope();
-  LOGI("Out C2DSetFillStyle");
-}
-
-void C2DSetFont(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetFont");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* font = GetArgAsString(arguments, 1);
-  SetStringReturnValue(arguments, Context2D(handle)->setFont(font));
-  Dart_ExitScope();
-  LOGI("Out C2DSetFont");
-}
-
-void C2DSetGlobalCompositeOperation(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetGlobalCompositeOperation");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* op = GetArgAsString(arguments, 1);
-  Context2D(handle)->setGlobalCompositeOperation(op);
-  Dart_ExitScope();
-  LOGI("Out C2DSetGlobalCompositeOperation");
-}
-
-void C2DSetLineCap(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetLineCap");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* lc = GetArgAsString(arguments, 1);
-  Context2D(handle)->setLineCap(lc);
-  Dart_ExitScope();
-  LOGI("Out C2DSetLineCap");
-}
-
-void C2DSetLineJoin(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetLineJoin");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* lj = GetArgAsString(arguments, 1);
-  Context2D(handle)->setLineJoin(lj);
-  Dart_ExitScope();
-  LOGI("Out C2DSetLineJoin");
-}
-
-void C2DSetLineWidth(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetLineWidth");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double w = GetArgAsDouble(arguments, 1);
-  Context2D(handle)->setLineWidth(w);
-  Dart_ExitScope();
-  LOGI("Out C2DSetLineWidth");
-}
-
-void C2DSetMiterLimit(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetMiterLimit");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double w = GetArgAsDouble(arguments, 1);
-  Context2D(handle)->setMiterLimit(w);
-  Dart_ExitScope();
-  LOGI("Out C2DSetMiterLimit");
-}
-
-void C2DSetShadowBlur(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetShadowBlur");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double blur = GetArgAsDouble(arguments, 1);
-  Context2D(handle)->setShadowBlur(blur);
-  Dart_ExitScope();
-  LOGI("Out C2DSetShadowBlur");
-}
-
-void C2DSetShadowColor(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetShadowColor");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* color = GetArgAsString(arguments, 1);
-  Context2D(handle)->setShadowColor(color);
-  Dart_ExitScope();
-  LOGI("Out C2DSetShadowColor");
-}
-
-void C2DSetShadowOffsetX(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetShadowOffsetX");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double offset = GetArgAsDouble(arguments, 1);
-  Context2D(handle)->setShadowOffsetX(offset);
-  Dart_ExitScope();
-  LOGI("Out C2DSetShadowOffsetX");
-}
-
-void C2DSetShadowOffsetY(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetShadowOffsetY");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double offset = GetArgAsDouble(arguments, 1);
-  Context2D(handle)->setShadowOffsetY(offset);
-  Dart_ExitScope();
-  LOGI("Out C2DSetShadowOffsetY");
-}
-
-void C2DSetStrokeStyle(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetStrokeStyle");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* color = GetArgAsString(arguments, 1);
-  Context2D(handle)->setStrokeColor(color);
-  Dart_ExitScope();
-  LOGI("Out C2DSetStrokeStyle");
-}
-
-void C2DSetTextAlign(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetTextAlign");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* align = GetArgAsString(arguments, 1);
-  SetStringReturnValue(arguments, Context2D(handle)->setTextAlign(align));
-  Dart_ExitScope();
-  LOGI("Out C2DSetTextAlign");
-}
-
-void C2DSetTextBaseline(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetTextBaseline");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* baseline = GetArgAsString(arguments, 1);
-  SetStringReturnValue(arguments, Context2D(handle)->setTextBaseline(baseline));
-  Dart_ExitScope();
-  LOGI("Out C2DSetTextBaseline");
-}
-
-void C2DGetImageSmoothingEnabled(Dart_NativeArguments arguments) {
-  LOGI("In C2DGetImageSmoothingEnabled");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  SetDoubleReturnValue(arguments, Context2D(handle)->imageSmoothingEnabled());
-  Dart_ExitScope();
-  LOGI("Out C2DGetImageSmoothingEnabled");
-}
-
-void C2DArc(Dart_NativeArguments arguments) {
-  LOGI("In C2DArc");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double x = GetArgAsDouble(arguments, 1);
-  double y = GetArgAsDouble(arguments, 2);
-  double r = GetArgAsDouble(arguments, 3);
-  double a1 = GetArgAsDouble(arguments, 4);
-  double a2 = GetArgAsDouble(arguments, 5);
-  bool anticlockwise = GetArgAsBool(arguments, 6);
-  Context2D(handle)->Arc(x, y, r, a1, a2, anticlockwise);
-  Dart_ExitScope();
-  LOGI("Out C2DArc");
-}
-
-void C2DArcTo(Dart_NativeArguments arguments) {
-  LOGI("In C2DArcTo");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double x1 = GetArgAsDouble(arguments, 1);
-  double y1 = GetArgAsDouble(arguments, 2);
-  double x2 = GetArgAsDouble(arguments, 3);
-  double y2 = GetArgAsDouble(arguments, 4);
-  double radius = GetArgAsDouble(arguments, 5);
-  Context2D(handle)->ArcTo(x1, y1, x2, y2, radius);
-  Dart_ExitScope();
-  LOGI("Out C2DArcTo");
-}
-
-void C2DBeginPath(Dart_NativeArguments arguments) {
-  LOGI("In C2DBeginPath");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  Context2D(handle)->BeginPath();
-  Dart_ExitScope();
-  LOGI("Out C2DBeginPath");
-}
-
-void C2DBezierCurveTo(Dart_NativeArguments arguments) {
-  LOGI("In C2DBezierCurveTo");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double cp1x = GetArgAsDouble(arguments, 1);
-  double cp1y = GetArgAsDouble(arguments, 2);
-  double cp2x = GetArgAsDouble(arguments, 3);
-  double cp2y = GetArgAsDouble(arguments, 4);
-  double x = GetArgAsDouble(arguments, 5);
-  double y = GetArgAsDouble(arguments, 6);
-  Context2D(handle)->BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
-  Dart_ExitScope();
-  LOGI("Out C2DBezierCurveTo");
-}
-
-void C2DClearRect(Dart_NativeArguments arguments) {
-  LOGI("In C2DClearRect");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double left = GetArgAsDouble(arguments, 1);
-  double top = GetArgAsDouble(arguments, 2);
-  double width = GetArgAsDouble(arguments, 3);
-  double height = GetArgAsDouble(arguments, 4);
-  Context2D(handle)->ClearRect(left, top, width, height);
-  Dart_ExitScope();
-  LOGI("Out C2DClearRect");
-}
-
-void C2DClip(Dart_NativeArguments arguments) {
-  LOGI("In C2DClip");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  Context2D(handle)->Clip();
-  Dart_ExitScope();
-  LOGI("Out C2DClip");
-}
-
-void C2DClosePath(Dart_NativeArguments arguments) {
-  LOGI("In C2DClosePath");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  Context2D(handle)->ClosePath();
-  Dart_ExitScope();
-  LOGI("Out C2DClosePath");
-}
-
-void C2DCreateImageDataFromDimensions(Dart_NativeArguments arguments) {
-  LOGI("In C2DCreateImageDataFromDimensions");
-  Dart_EnterScope();
-  // int handle = GetArgAsInt(arguments, 0);
-  // double sw = GetArgAsDouble(arguments, 1);
-  // double sh = GetArgAsDouble(arguments, 2);
-  // GLubyte* pixels = (GLubyte*)calloc(sw * sh * 4, sizeof(GLubyte));
-  // ImageData* imageData = new ImageData(sw, sh, pixels);
-  // TODO(gram): How do we create a Dart ImageData object from this?
-  Dart_ExitScope();
-  LOGI("Out C2DCreateImageDataFromDimensions");
-}
-
-void C2DDrawImage(Dart_NativeArguments arguments) {
-  LOGI("In C2DDrawImage");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* src_url = GetArgAsString(arguments, 1);
-  int sx = GetArgAsInt(arguments, 2);
-  int sy = GetArgAsInt(arguments, 3);
-  bool has_src_dimensions = GetArgAsBool(arguments, 4);
-  int sw = GetArgAsInt(arguments, 5);
-  int sh = GetArgAsInt(arguments, 6);
-  int dx = GetArgAsInt(arguments, 7);
-  int dy = GetArgAsInt(arguments, 8);
-  bool has_dst_dimensions = GetArgAsBool(arguments, 9);
-  int dw = GetArgAsInt(arguments, 10);
-  int dh = GetArgAsInt(arguments, 11);
-  Context2D(handle)->DrawImage(src_url,
-                               sx, sy, has_src_dimensions, sw, sh,
-                               dx, dy, has_dst_dimensions, dw, dh);
-  Dart_ExitScope();
-  LOGI("Out C2DDrawImage");
-}
-
-void C2DFill(Dart_NativeArguments arguments) {
-  LOGI("In C2DFill");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  Context2D(handle)->Fill();
-  Dart_ExitScope();
-  LOGI("Out C2DFill");
-}
-
-void C2DFillRect(Dart_NativeArguments arguments) {
-  LOGI("In C2DFillRect");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double left = GetArgAsDouble(arguments, 1);
-  double top = GetArgAsDouble(arguments, 2);
-  double width = GetArgAsDouble(arguments, 3);
-  double height = GetArgAsDouble(arguments, 4);
-  Context2D(handle)->FillRect(left, top, width, height);
-  Dart_ExitScope();
-  LOGI("Out C2DFillRect");
-}
-
-void C2DFillText(Dart_NativeArguments arguments) {
-  LOGI("In C2DFillText");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* text = GetArgAsString(arguments, 1);
-  double x = GetArgAsDouble(arguments, 2);
-  double y = GetArgAsDouble(arguments, 3);
-  double maxWidth = GetArgAsDouble(arguments, 4);
-  Context2D(handle)->FillText(text, x, y, maxWidth);
-  Dart_ExitScope();
-  LOGI("Out C2DFillText");
-}
-
-void C2DGetImageData(Dart_NativeArguments arguments) {
-  LOGI("In C2DGetImageData");
-  Dart_EnterScope();
-  // TODO(gram): Complete this.
-  // int handle = GetArgAsInt(arguments, 0);
-  // double sx = GetArgAsDouble(arguments, 1);
-  // double sy = GetArgAsDouble(arguments, 2);
-  // double sw = GetArgAsDouble(arguments, 3);
-  // double sh = GetArgAsDouble(arguments, 4);
-  // ... = Context2D(handle)->GetImageData(text, x, y, maxWidth);
-  Dart_ExitScope();
-  LOGI("Out C2DGetImageData");
-}
-
-void C2DLineTo(Dart_NativeArguments arguments) {
-  LOGI("In C2DLineTo");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double x = GetArgAsDouble(arguments, 1);
-  double y = GetArgAsDouble(arguments, 2);
-  Context2D(handle)->LineTo(x, y);
-  Dart_ExitScope();
-  LOGI("Out C2DLineTo");
-}
-
-void C2DMeasureText(Dart_NativeArguments arguments) {
-  LOGI("In C2DMeasureText");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* text = GetArgAsString(arguments, 1);
-  float width = Context2D(handle)->MeasureText(text);
-  SetDoubleReturnValue(arguments, width);
-  Dart_ExitScope();
-  LOGI("Out C2DMeasureText");
-}
-
-void C2DMoveTo(Dart_NativeArguments arguments) {
-  LOGI("IN C2DMoveTo");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double x = GetArgAsDouble(arguments, 1);
-  double y = GetArgAsDouble(arguments, 2);
-  Context2D(handle)->MoveTo(x, y);
-  Dart_ExitScope();
-  LOGI("Out C2DMoveTo");
-}
-
-void C2DPutImageData(Dart_NativeArguments arguments) {
-  LOGI("IN C2DPutImageData");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  // Get object arguments 2
-  // BindingImageData* imageData = GetArgAsObject(arguments, 1);
-  double dx = GetArgAsDouble(arguments, 2);
-  double dy = GetArgAsDouble(arguments, 3);
-  Context2D(handle)->PutImageData(NULL, dx, dy);
-  Dart_ExitScope();
-  LOGI("Out C2DPutImageData");
-}
-
-void C2DQuadraticCurveTo(Dart_NativeArguments arguments) {
-  LOGI("In C2DQuadraticCurveTo");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double cpx = GetArgAsDouble(arguments, 1);
-  double cpy = GetArgAsDouble(arguments, 2);
-  double x = GetArgAsDouble(arguments, 3);
-  double y = GetArgAsDouble(arguments, 4);
-  Context2D(handle)->QuadraticCurveTo(cpx, cpy, x, y);
-  Dart_ExitScope();
-  LOGI("Out C2DQuadraticCurveTo");
-}
-
-void C2DRect(Dart_NativeArguments arguments) {
-  LOGI("In C2DRect");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double x = GetArgAsDouble(arguments, 1);
-  double y = GetArgAsDouble(arguments, 2);
-  double w = GetArgAsDouble(arguments, 3);
-  double h = GetArgAsDouble(arguments, 4);
-  Context2D(handle)->Rect(x, y, w, h);
-  Dart_ExitScope();
-  LOGI("Out C2DRect");
-}
-
-void C2DRestore(Dart_NativeArguments arguments) {
-  LOGI("In C2DRestore");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  CanvasContext* context = Context2D(handle);
-  context->Restore();
-  Dart_ExitScope();
-  LOGI("Out C2DRestore");
-}
-
-void C2DRotate(Dart_NativeArguments arguments) {
-  LOGI("In C2DRotate");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double a = GetArgAsDouble(arguments, 1);
-  Context2D(handle)->Rotate(a);
-  Dart_ExitScope();
-  LOGI("Out C2DRotate");
-}
-
-void C2DSave(Dart_NativeArguments arguments) {
-  LOGI("In C2DSave");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  Context2D(handle)->Save();
-  Dart_ExitScope();
-  LOGI("Out C2DSave");
-}
-
-void C2DScale(Dart_NativeArguments arguments) {
-  LOGI("In C2DScale");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double sx = GetArgAsDouble(arguments, 1);
-  double sy = GetArgAsDouble(arguments, 2);
-  Context2D(handle)->Scale(sx, sy);
-  Dart_ExitScope();
-  LOGI("Out C2DScale");
-}
-
-void C2DSetLineDash(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetLineDash");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  int len;
-  float* dash = static_cast<float*>(GetArgsAsFloatList(arguments, 1, &len));
-  if (dash != NULL) {
-    Context2D(handle)->setLineDash(dash, len);
-    delete[] dash;
-  }
-  Dart_ExitScope();
-  LOGI("Out C2DSetLineDash");
-}
-
-void C2DSetLineDashOffset(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetLineDashOffset");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double offset = GetArgAsDouble(arguments, 1);
-  Context2D(handle)->setLineDashOffset(offset);
-  Dart_ExitScope();
-  LOGI("Out C2DSetLineDashOffset");
-}
-
-void C2DSetTransform(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetTransform");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double m11 = GetArgAsDouble(arguments, 1);
-  double m12 = GetArgAsDouble(arguments, 2);
-  double m21 = GetArgAsDouble(arguments, 3);
-  double m22 = GetArgAsDouble(arguments, 4);
-  double dx = GetArgAsDouble(arguments, 5);
-  double dy = GetArgAsDouble(arguments, 6);
-  Context2D(handle)->setTransform(m11, m12, m21, m22, dx, dy);
-  Dart_ExitScope();
-  LOGI("Out C2DSetTransform");
-}
-
-void C2DStroke(Dart_NativeArguments arguments) {
-  LOGI("In C2DStroke");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  Context2D(handle)->Stroke();
-  Dart_ExitScope();
-  LOGI("Out C2DStroke");
-}
-
-void C2DStrokeRect(Dart_NativeArguments arguments) {
-  LOGI("In C2DStrokeRect");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double left = GetArgAsDouble(arguments, 1);
-  double top = GetArgAsDouble(arguments, 2);
-  double width = GetArgAsDouble(arguments, 3);
-  double height = GetArgAsDouble(arguments, 4);
-  Context2D(handle)->StrokeRect(left, top, width, height);
-  Dart_ExitScope();
-  LOGI("Out C2DStrokeRect");
-}
-
-void C2DStrokeText(Dart_NativeArguments arguments) {
-  LOGI("In C2DStrokeText");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  const char* text = GetArgAsString(arguments, 1);
-  double x = GetArgAsDouble(arguments, 2);
-  double y = GetArgAsDouble(arguments, 3);
-  double maxWidth = GetArgAsDouble(arguments, 4);
-  Context2D(handle)->StrokeText(text, x, y, maxWidth);
-  Dart_ExitScope();
-  LOGI("Out C2DStrokeText");
-}
-
-void C2DTransform(Dart_NativeArguments arguments) {
-  LOGI("In C2DTransform");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double m11 = GetArgAsDouble(arguments, 1);
-  double m12 = GetArgAsDouble(arguments, 2);
-  double m21 = GetArgAsDouble(arguments, 3);
-  double m22 = GetArgAsDouble(arguments, 4);
-  double dx = GetArgAsDouble(arguments, 5);
-  double dy = GetArgAsDouble(arguments, 6);
-  Context2D(handle)->Transform(m11, m12, m21, m22, dx, dy);
-  Dart_ExitScope();
-  LOGI("Out C2DTransform");
-}
-
-void C2DTranslate(Dart_NativeArguments arguments) {
-  LOGI("In C2DTranslate");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  double x = GetArgAsDouble(arguments, 1);
-  double y = GetArgAsDouble(arguments, 2);
-  Context2D(handle)->Translate(x, y);
-  Dart_ExitScope();
-  LOGI("Out C2DTranslate");
-}
-
-void C2DSetFillGradient(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetFillGradient");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  bool is_radial = GetArgAsBool(arguments, 1);
-  double x0 = GetArgAsDouble(arguments, 2);
-  double y0 = GetArgAsDouble(arguments, 3);
-  double r0 = GetArgAsDouble(arguments, 4);
-  double x1 = GetArgAsDouble(arguments, 5);
-  double y1 = GetArgAsDouble(arguments, 6);
-  double r1 = GetArgAsDouble(arguments, 7);
-  int num_positions, num_colors;
-  float* positions = GetArgsAsFloatList(arguments, 8, &num_positions);
-  char** colors = GetArgsAsStringList(arguments, 9, &num_colors);
-  Context2D(handle)->SetFillGradient(is_radial, x0, y0, r0, x1, y1, r1,
-    num_positions, positions, colors);
-  Dart_ExitScope();
-  LOGI("Out C2DSetFillGradient");
-}
-
-void C2DSetStrokeGradient(Dart_NativeArguments arguments) {
-  LOGI("In C2DSetStrokeGradient");
-  Dart_EnterScope();
-  int handle = GetArgAsInt(arguments, 0);
-  bool is_radial = GetArgAsBool(arguments, 1);
-  double x0 = GetArgAsDouble(arguments, 2);
-  double y0 = GetArgAsDouble(arguments, 3);
-  double r0 = GetArgAsDouble(arguments, 4);
-  double x1 = GetArgAsDouble(arguments, 5);
-  double y1 = GetArgAsDouble(arguments, 6);
-  double r1 = GetArgAsDouble(arguments, 7);
-  int num_positions, num_colors;
-  float* positions = GetArgsAsFloatList(arguments, 8, &num_positions);
-  char** colors = GetArgsAsStringList(arguments, 9, &num_colors);
-  Context2D(handle)->SetStrokeGradient(is_radial, x0, y0, r0, x1, y1, r1,
-    num_positions, positions, colors);
-  Dart_ExitScope();
-  LOGI("Out C2DSetStrokeGradient");
-}
-
-void C2DGetImageWidth(Dart_NativeArguments arguments) {
-  LOGI("In C2DGetImageWidth");
-  Dart_EnterScope();
-  const char* src_url = GetArgAsString(arguments, 0);
-  int w = ImageCache::GetWidth(src_url);
-  SetIntReturnValue(arguments, w);
-  Dart_ExitScope();
-  LOGI("Out C2DGetImageWidth");
-}
-
-void C2DGetImageHeight(Dart_NativeArguments arguments) {
-  LOGI("In C2DGetImageHeight");
-  Dart_EnterScope();
-  const char* src_url = GetArgAsString(arguments, 0);
-  int h = ImageCache::GetHeight(src_url);
-  SetIntReturnValue(arguments, h);
-  Dart_ExitScope();
-  LOGI("Out C2DGetImageHeight");
-}
-
-struct FunctionLookup {
-  const char* name;
-  Dart_NativeFunction function;
-};
-
-FunctionLookup function_list[] = {
-    {"Log", Log},
-    {"LogError", LogError},
-    {"SystemRand", SystemRand},
-    {"SystemSrand", SystemSrand},
-    {"SwapBuffers", SwapBuffers},
-    {"GetDeviceScreenWidth", GetDeviceScreenWidth},
-    {"GetDeviceScreenHeight", GetDeviceScreenHeight},
-    {"GLAttachShader", GLAttachShader},
-    {"GLBindBuffer", GLBindBuffer},
-    {"GLBufferData", GLBufferData},
-    {"GLClear", GLClear},
-    {"GLClearColor", GLClearColor},
-    {"GLClearDepth", GLClearDepth},
-    {"GLCompileShader", GLCompileShader},
-    {"GLCreateBuffer", GLCreateBuffer},
-    {"GLCreateProgram", GLCreateProgram},
-    {"GLCreateShader", GLCreateShader},
-    {"GLDrawArrays", GLDrawArrays},
-    {"GLEnableVertexAttribArray", GLEnableVertexAttribArray},
-    {"GLGetAttribLocation", GLGetAttribLocation},
-    {"GLGetError", GLGetError},
-    {"GLGetProgramParameter", GLGetProgramParameter},
-    {"GLGetShaderParameter", GLGetShaderParameter},
-    {"GLGetUniformLocation", GLGetUniformLocation},
-    {"GLLinkProgram", GLLinkProgram},
-    {"GLShaderSource", GLShaderSource},
-    {"GLUniform1f", GLUniform1f},
-    {"GLUniform2f", GLUniform2f},
-    {"GLUniform3f", GLUniform3f},
-    {"GLUniform4f", GLUniform4f},
-    {"GLUniform1i", GLUniform1i},
-    {"GLUniform2i", GLUniform2i},
-    {"GLUniform3i", GLUniform3i},
-    {"GLUniform4i", GLUniform4i},
-    {"GLUniform1fv", GLUniform1fv},
-    {"GLUniform2fv", GLUniform2fv},
-    {"GLUniform3fv", GLUniform3fv},
-    {"GLUniform4fv", GLUniform4fv},
-    {"GLUniform1iv", GLUniform1iv},
-    {"GLUniform2iv", GLUniform2iv},
-    {"GLUniform3iv", GLUniform3iv},
-    {"GLUniform4iv", GLUniform4iv},
-    {"GLUseProgram", GLUseProgram},
-    {"GLVertexAttribPointer", GLVertexAttribPointer},
-    {"GLViewport", GLViewport},
-    {"GLArrayBuffer", GLArrayBuffer},
-    {"GLColorBufferBit", GLColorBufferBit},
-    {"GLCompileStatus", GLCompileStatus},
-    {"GLDeleteStatus", GLDeleteStatus},
-    {"GLDepthBufferBit", GLDepthBufferBit},
-    {"GLFloat", GLFloat},
-    {"GLFragmentShader", GLFragmentShader},
-    {"GLLinkStatus", GLLinkStatus},
-    {"GLTriangleStrip", GLTriangleStrip},
-    {"GLTriangles", GLTriangles},
-    {"GLTrue", GLTrue},
-    {"GLStaticDraw", GLStaticDraw},
-    {"GLValidateStatus", GLValidateStatus},
-    {"GLVertexShader", GLVertexShader},
-    {"GLGetShaderInfoLog", GLGetShaderInfoLog},
-    {"GLGetProgramInfoLog", GLGetProgramInfoLog},
-    {"RandomArray_ServicePort", RandomArrayServicePort},
-
-    // Audio support.
-    {"PlayBackground", PlayBackground},
-    {"StopBackground", StopBackground},
-    {"LoadSample", LoadSample},
-    {"PlaySample", PlaySample},
-
-    // 2D Support
-
-    { "C2DCreateNativeContext", C2DCreateNativeContext},
-
-    // Property getters/setters.
-
-    { "C2DSetWidth", C2DSetWidth},
-    { "C2DSetHeight", C2DSetHeight},
-    { "C2DSetGlobalAlpha", C2DSetGlobalAlpha},
-    { "C2DSetFillStyle", C2DSetFillStyle},
-    { "C2DSetFont", C2DSetFont},
-    { "C2DSetGlobalCompositeOperation", C2DSetGlobalCompositeOperation},
-    { "C2DSetLineCap", C2DSetLineCap},
-    { "C2DSetLineJoin", C2DSetLineJoin},
-    { "C2DSetLineWidth", C2DSetLineWidth},
-    { "C2DSetMiterLimit", C2DSetMiterLimit},
-    { "C2DSetShadowBlur", C2DSetShadowBlur},
-    { "C2DSetShadowColor", C2DSetShadowColor},
-    { "C2DSetShadowOffsetX", C2DSetShadowOffsetX},
-    { "C2DSetShadowOffsetY", C2DSetShadowOffsetY},
-    { "C2DSetStrokeStyle", C2DSetStrokeStyle},
-    { "C2DSetTextAlign", C2DSetTextAlign},
-    { "C2DSetTextBaseline", C2DSetTextBaseline},
-    { "C2DGetImageSmoothingEnabled", C2DGetImageSmoothingEnabled},
-
-    // Methods.
-    { "C2DArc", C2DArc},
-    { "C2DArcTo", C2DArcTo},
-    { "C2DBeginPath", C2DBeginPath},
-    { "C2DBezierCurveTo", C2DBezierCurveTo},
-    { "C2DClearRect", C2DClearRect},
-    { "C2DClip", C2DClip},
-    { "C2DClosePath", C2DClosePath},
-    { "C2DCreateImageDataFromDimensions", C2DCreateImageDataFromDimensions},
-    { "C2DDrawImage", C2DDrawImage},
-    { "C2DFill", C2DFill},
-    { "C2DFillRect", C2DFillRect},
-    { "C2DFillText", C2DFillText},
-    { "C2DGetImageData", C2DGetImageData},
-    { "C2DLineTo", C2DLineTo},
-    { "C2DMeasureText", C2DMeasureText},
-    { "C2DMoveTo", C2DMoveTo},
-    { "C2DPutImageData", C2DPutImageData},
-    { "C2DQuadraticCurveTo", C2DQuadraticCurveTo},
-    { "C2DRect", C2DRect},
-    { "C2DRestore", C2DRestore},
-    { "C2DRotate", C2DRotate},
-    { "C2DSave", C2DSave},
-    { "C2DScale", C2DScale},
-    { "C2DSetLineDash", C2DSetLineDash},
-    { "C2DSetLineDashOffset", C2DSetLineDashOffset},
-    { "C2DSetTransform", C2DSetTransform},
-    { "C2DStroke", C2DStroke},
-    { "C2DStrokeRect", C2DStrokeRect},
-    { "C2DStrokeText", C2DStrokeText},
-    { "C2DTransform", C2DTransform},
-    { "C2DTranslate", C2DTranslate},
-    { "C2DSetFillGradient", C2DSetFillGradient},
-    { "C2DSetStrokeGradient", C2DSetStrokeGradient},
-    { "C2DGetImageWidth", C2DGetImageWidth},
-    { "C2DGetImageHeight", C2DGetImageHeight},
-
-    {NULL, NULL}};
-
-Dart_NativeFunction ResolveName(Dart_Handle name, int argc) {
-  if (!Dart_IsString(name)) return NULL;
-  Dart_NativeFunction result = NULL;
-  Dart_EnterScope();
-  const char* cname;
-  HandleError(Dart_StringToCString(name, &cname));
-  for (int i = 0; function_list[i].name != NULL; ++i) {
-    if (strcmp(function_list[i].name, cname) == 0) {
-      result = function_list[i].function;
-      break;
-    }
-  }
-  Dart_ExitScope();
-  return result;
-}
diff --git a/runtime/embedders/openglui/common/extension.h b/runtime/embedders/openglui/common/extension.h
deleted file mode 100644
index a13413e..0000000
--- a/runtime/embedders/openglui/common/extension.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_EXTENSION_H_
-#define EMBEDDERS_OPENGLUI_COMMON_EXTENSION_H_
-
-#include "include/dart_api.h"
-
-Dart_NativeFunction ResolveName(Dart_Handle name, int argc);
-
-extern int32_t PlayBackgroundSound(const char* path);
-extern void StopBackgroundSound();
-extern int32_t LoadSoundSample(const char* path);
-extern int32_t PlaySoundSample(const char* path);
-extern int32_t Init2DGraphics();
-
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_EXTENSION_H_
-
diff --git a/runtime/embedders/openglui/common/gl.dart b/runtime/embedders/openglui/common/gl.dart
deleted file mode 100644
index c37c80b..0000000
--- a/runtime/embedders/openglui/common/gl.dart
+++ /dev/null
@@ -1,1211 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library android_extension;
-import 'dart:async';
-
-// A VERY simplified DOM.
-
-class BodyElement {
-  List _nodes;
-  get nodes => _nodes;
-  BodyElement() : _nodes = new List();
-}
-
-// The OpenGLUI "equivalent" of Window.
-
-typedef void RequestAnimationFrameCallback(num highResTime);
-
-class Window {
-  static int _nextId = 0;
-  List _callbacks;
-  List _arguments;
-
-  Window._internal() : _callbacks = [], _arguments = [];
-
-  int _scheduleCallback(callback, [argument]) {
-    _callbacks.add(callback);
-    _arguments.add(argument);
-    return _callbacks.length - 1;
-  }
-
-  int requestAnimationFrame(RequestAnimationFrameCallback callback) {
-    return _scheduleCallback(callback,
-        (new DateTime.now()).millisecondsSinceEpoch);
-  }
-
-  void cancelAnimationFrame(id) {
-    _callbacks[id] = null;
-    _arguments[id] = null;
-  }
-
-  get animationFrame {
-    // TODO(gram)
-    return null;
-  }
-
-  void _dispatch() {
-    // We clear out the callbacks map before calling any callbacks,
-    // as they may schedule new callbacks.
-    var oldcallbacks = _callbacks;
-    var oldarguments = _arguments;
-    _callbacks = [];
-    _arguments = [];
-    for (var i = 0; i < oldcallbacks.length; i++) {
-      if (oldcallbacks[i] != null) {
-        oldcallbacks[i](oldarguments[i]);
-      }
-    }
-    // We could loop around here to handle any callbacks
-    // scheduled in processing the prior ones, but then we
-    // need some other mechanism for trying to get requestAnimationFrame
-    // callbacks at 60fps.
-  }
-
-  Map localStorage = {};  // TODO(gram) - Make this persistent.
-}
-
-Window window = new Window._internal();
-
-// The OpenGLUI "equivalent" of HtmlDocument.
-class Document extends Node {
-  BodyElement _body;
-  get body => _body;
-  Document._internal() : _body = new BodyElement();
-}
-
-Document document = new Document._internal();
-
-// TODO(gram): make private and call from within library context.
-update_() {
-  log("in update");
-  window._dispatch();
-}
-
-// Event handling. This is very kludgy for now, especially the
-// bare-bones Stream stuff!
-
-typedef void EventListener(Event event);
-
-class EventTarget {
-  static Map<EventTarget, Map<String, List<EventListener>>>
-      _listeners = new Map();
-
-  static get listeners => _listeners;
-
-  bool dispatchEvent(Event event) {
-    var rtn = false;
-    if (!_listeners.containsKey(this)) return false;
-    var listeners = _listeners[this];
-    if (!listeners.containsKey(event.type)) return false;
-    var eventListeners = listeners[event.type];
-    for (var eventListener in eventListeners) {
-      if (eventListener != null) {
-        eventListener(event);
-        rtn = true;
-      }
-    }
-    return rtn;
-  }
-
-  void addListener(String eventType, EventListener handler) {
-    if (!_listeners.containsKey(this)) {
-      _listeners[this] = new Map();
-    }
-    var listeners = _listeners[this];
-    if (!listeners.containsKey(eventType)) {
-      listeners[eventType] = new List();
-    }
-    var event_listeners = listeners[eventType];
-    for (var i = 0; i < event_listeners.length; i++) {
-      if (event_listeners[i] == null) {
-        event_listeners[i] = handler;
-        return;
-      }
-    }
-    event_listeners.add(handler);
-  }
-
-  void removeListener(String eventType, EventListener handler) {
-    if (_listeners.containsKey(this)) {
-      var listeners = _listeners[this];
-      if (listeners.containsKey(eventType)) {
-        var event_listeners = listeners[eventType];
-        for (var i = 0; i < event_listeners.length; i++) {
-          if (event_listeners[i] == handler) {
-            event_listeners[i] = null;
-            break;
-          }
-        }
-      }
-    }
-  }
-}
-
-class Event {
-  final String type;
-  EventTarget target;
-  Event(String type) : this.type = type;
-  preventDefault() {}
-  stopPropagation() {}
-}
-
-class KeyboardEvent extends Event {
-  final bool altKey;
-  final bool ctrlKey;
-  final bool shiftKey;
-  final int keyCode;
-
-  KeyboardEvent(String type, int keycode, bool alt, bool ctrl, bool shift) 
-    : super(type),
-      keyCode = keycode,
-      altKey = alt,
-      ctrlKey = ctrl,
-      shiftKey = shift {
-  }
-}
-
-class MouseEvent extends Event {
-  final int screenX, screenY;
-  final int clientX, clientY;
-
-  MouseEvent(String type, int x, int y)
-    : super(type),
-      screenX = x,
-      screenY = y,
-      clientX = x,
-      clientY = y {
-  }
-}
-
-class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
-  int _pauseCount = 0;
-  EventTarget _target;
-  final String _eventType;
-  var _onData;
-
-  _EventStreamSubscription(this._target, this._eventType, this._onData) {
-    _tryResume();
-  }
-
-  void cancel() {
-    if (_canceled) {
-      throw new StateError("Subscription has been canceled.");
-    }
-
-    _unlisten();
-    // Clear out the target to indicate this is complete.
-    _target = null;
-    _onData = null;
-  }
-
-  bool get _canceled => _target == null;
-
-  void onData(void handleData(T event)) {
-    if (_canceled) {
-      throw new StateError("Subscription has been canceled.");
-    }
-    // Remove current event listener.
-    _unlisten();
-
-    _onData = handleData
-    _tryResume();
-  }
-
-  /// Has no effect.
-  void onError(void handleError(Object error)) {}
-
-  /// Has no effect.
-  void onDone(void handleDone()) {}
-
-  void pause([Future resumeSignal]) {
-    if (_canceled) {
-      throw new StateError("Subscription has been canceled.");
-    }
-    ++_pauseCount;
-    _unlisten();
-
-    if (resumeSignal != null) {
-      resumeSignal.whenComplete(resume);
-    }
-  }
-
-  bool get _paused => _pauseCount > 0;
-
-  void resume() {
-    if (_canceled) {
-      throw new StateError("Subscription has been canceled.");
-    }
-    if (!_paused) {
-      throw new StateError("Subscription is not paused.");
-    }
-    --_pauseCount;
-    _tryResume();
-  }
-
-  void _tryResume() {
-    if (_onData != null && !_paused) {
-      _target.addListener(_eventType, _onData);
-    }
-  }
-
-  void _unlisten() {
-    if (_onData != null) {
-      _target.removeListener(_eventType, _onData);
-    }
-  }
-
-  Future asFuture([var futureValue]) {
-    // We just need a future that will never succeed or fail.
-    Completer completer = new Completer();
-    return completer.future;
-  }
-}
-
-class _EventStream<T extends Event> extends Stream<T> {
-  final Object _target;
-  final String _eventType;
-
-  _EventStream(this._target, this._eventType);
-
-  // DOM events are inherently multi-subscribers.
-  Stream<T> asBroadcastStream() => this;
-  bool get isBroadcast => true;
-
-  StreamSubscription<T> listen(void onData(T event),
-      { void onError(Object error),
-      void onDone(),
-      bool cancelOnError}) {
-
-    return new _EventStreamSubscription<T>(
-        this._target, this._eventType, onData);
-  }
-}
-
-class Node extends EventTarget {
-  Stream<KeyboardEvent> get onKeyDown => new _EventStream(this, 'keydown');
-  Stream<KeyboardEvent> get onKeyUp => new _EventStream(this, 'keyup');
-  Stream<MouseEvent> get onMouseDown => new _EventStream(this, 'mousedown');
-  Stream<MouseEvent> get onMouseMove => new _EventStream(this, 'mousemove');
-  Stream<MouseEvent> get onMouseUp => new _EventStream(this, 'mouseup');
-}
-
-// TODO(gram): If we support more than one on-screen canvas, we will
-// need to filter dispatched mouse and key events by the target Node
-// with more granularity; right now we just iterate through DOM nodes
-// until we find one that handles the event.
-_dispatchEvent(Event event) {
-  assert(document.body.nodes.length <= 1);
-  for (var target in document.body.nodes) {
-    event.target = target;
-    if (target.dispatchEvent(event)) {
-      return;
-    }
-  }
-  document.dispatchEvent(event);
-}
-
-_dispatchKeyEvent(String type, int keyCode, bool alt, bool ctrl, bool shift) {
-  _dispatchEvent(new KeyboardEvent(type, keyCode, alt, ctrl, shift));
-}
-
-_dispatchMouseEvent(String type, double x, double y) {
-  _dispatchEvent(new MouseEvent(type, x.toInt(), y.toInt()));
-}
-
-// These next few are called by vmglue.cc.
-onKeyDown_(int when, int keyCode, bool alt, bool ctrl, bool shift, int repeat)
-    =>  _dispatchKeyEvent('keydown', keyCode, alt, ctrl, shift);
-
-onKeyUp_(int when, int keyCode, bool alt, bool ctrl, bool shift, int repeat) =>
-    _dispatchKeyEvent('keyup', keyCode, alt, ctrl, shift);
-
-onMouseDown_(int when, double x, double y) =>
-    _dispatchMouseEvent('mousedown', x, y);
-
-onMouseMove_(int when, double x, double y) =>
-    _dispatchMouseEvent('mousemove', x, y);
-
-onMouseUp_(int when, double x, double y) =>
-    _dispatchMouseEvent('mouseup', x, y);
-
-class CanvasElement extends Node {
-  int height;
-  int width;
-
-  CanvasRenderingContext2D _context2d;
-  WebGLRenderingContext _context3d;
-
-  // For use with drawImage, we want to support a src property
-  // like ImageElement, which maps to the context handle in native
-  // code.
-  get src => "context2d://${_context2d.handle}";
-
-  CanvasElement({int width, int height})
-    : super() {
-    this.width = (width == null) ? getDeviceScreenWidth() : width;
-    this.height = (height == null) ? getDeviceScreenHeight() : height;
-    getContext('2d');
-  }
-
-  CanvasRenderingContext getContext(String contextId) {
-    if (contextId == "2d") {
-      if (_context2d == null) {
-        _context2d = new CanvasRenderingContext2D(this, width, height);
-      }
-      return _context2d;
-    } else if (contextId == "webgl" || 
-               contextId == "experimental-webgl") {
-      if (_context3d == null) {
-        _context3d = new WebGLRenderingContext(this);
-      }
-      return _context3d;
-    }
-  }
- 
-  String toDataUrl(String type) {
-    // This needs to take the contents of the underlying
-    // canvas painted by the 2d context, give that a unique
-    // URL, and return that. The canvas element should be
-    // reuable afterwards without destroying the previously
-    // rendered data associated with this URL.
-    assert(_context2d != null);
-    var rtn = src;
-    _context2d = null;
-    return rtn;
-  }
-}
-
-class CanvasRenderingContext {
-  final CanvasElement canvas;
-
-  CanvasRenderingContext(this.canvas);
-}
-
-class AudioElement {
-  double volume;
-  String _src;
-  get src => _src;
-  set src(String v) {
-    _src = v;
-    _loadSample(v);
-  }
-
-  AudioElement([this._src]);
-  void play() {
-    _playSample(_src);
-  }
-}
-
-// The simplest way to call native code: top-level functions.
-int systemRand() native "SystemRand";
-void systemSrand(int seed) native "SystemSrand";
-void log(String what) native "Log";
-
-int getDeviceScreenWidth() native "GetDeviceScreenWidth";
-int getDeviceScreenHeight() native "GetDeviceScreenHeight";
-
-// EGL functions.
-void glSwapBuffers() native "SwapBuffers";
-
-// GL functions.
-void glAttachShader(int program, int shader) native "GLAttachShader";
-void glBindBuffer(int target, int buffer) native "GLBindBuffer";
-void glBufferData(int target, List data, int usage) native "GLBufferData";
-void glClearColor(num r, num g, num b, num alpha) native "GLClearColor";
-void glClearDepth(num depth) native "GLClearDepth";
-void glClear(int mask) native "GLClear";
-void glCompileShader(int shader) native "GLCompileShader";
-int glCreateBuffer() native "GLCreateBuffer";
-int glCreateProgram() native "GLCreateProgram";
-int glCreateShader(int shaderType) native "GLCreateShader";
-void glDrawArrays(int mode, int first, int count) native "GLDrawArrays";
-void glEnableVertexAttribArray(int index) native "GLEnableVertexAttribArray";
-int glGetAttribLocation(int program, String name) native "GLGetAttribLocation";
-int glGetError() native "GLGetError";
-int glGetProgramParameter(int program, int param)
-    native "GLGetProgramParameter";
-int glGetShaderParameter(int shader, int param) native "GLGetShaderParameter";
-int glGetUniformLocation(int program, String name)
-    native "GLGetUniformLocation";
-void glLinkProgram(int program) native "GLLinkProgram";
-void glShaderSource(int shader, String source) native "GLShaderSource";
-void glUniform1f(int location, double v0) native "GLUniform1f";
-void glUniform2f(int location, double v0, double v1) native "GLUniform2f";
-void glUniform3f(int location, double v0, double v1, double v2)
-    native "GLUniform3f";
-void glUniform4f(int location, double v0, double v1, double v2, double v3)
-    native "GLUniform4f";
-void glUniform1i(int location, int v0) native "GLUniform1i";
-void glUniform2i(int location, int v0, int v1) native "GLUniform2i";
-void glUniform3i(int location, int v0, int v1, int v2) native "GLUniform3i";
-void glUniform4i(int location, int v0, int v1, int v2, int v3)
-    native "GLUniform4i";
-void glUniform1fv(int location, List values) native "GLUniform1fv";
-void glUniform2fv(int location, List values) native "GLUniform2fv";
-void glUniform3fv(int location, List values) native "GLUniform3fv";
-void glUniform4fv(int location, List values) native "GLUniform4fv";
-void glUniform1iv(int location, List values) native "GLUniform1iv";
-void glUniform2iv(int location, List values) native "GLUniform2iv";
-void glUniform3iv(int location, List values) native "GLUniform3iv";
-void glUniform4iv(int location, List values) native "GLUniform4iv";
-void glUseProgram(int program) native "GLUseProgram";
-void glVertexAttribPointer(int index, int size, int type, bool normalized,
-    int stride, int pointer) native "GLVertexAttribPointer";
-void glViewport(int x, int y, int width, int height) native "GLViewport";
-
-int glArrayBuffer() native "GLArrayBuffer";
-int glColorBufferBit() native "GLColorBufferBit";
-int glCompileStatus() native "GLCompileStatus";
-int glDeleteStatus() native "GLDeleteStatus";
-int glDepthBufferBit() native "GLDepthBufferBit";
-int glFloat() native "GLFloat";
-int glFragmentShader() native "GLFragmentShader";
-int glLinkStatus() native "GLLinkStatus";
-int glStaticDraw() native "GLStaticDraw";
-int glTriangleStrip() native "GLTriangleStrip";
-int glTriangles() native "GLTriangles";
-int glTrue() native "GLTrue";
-int glValidateStatus() native "GLValidateStatus";
-int glVertexShader() native "GLVertexShader";
-
-String glGetShaderInfoLog(int shader) native "GLGetShaderInfoLog";
-String glGetProgramInfoLog(int program) native "GLGetProgramInfoLog";
-
-class WebGLRenderingContext extends CanvasRenderingContext {
-  WebGLRenderingContext(canvas) : super(canvas);
-
-  static get ARRAY_BUFFER => glArrayBuffer();
-  static get COLOR_BUFFER_BIT => glColorBufferBit();
-  static get COMPILE_STATUS => glCompileStatus();
-  static get DELETE_STATUS => glDeleteStatus();
-  static get DEPTH_BUFFER_BIT => glDepthBufferBit();
-  static get FLOAT => glFloat();
-  static get FRAGMENT_SHADER => glFragmentShader();
-  static get LINK_STATUS => glLinkStatus();
-  static get STATIC_DRAW => glStaticDraw();
-  static get TRUE => glTrue();
-  static get TRIANGLE_STRIP => glTriangleStrip();
-  static get TRIANGLES => glTriangles();
-  static get VALIDATE_STATUS => glValidateStatus();
-  static get VERTEX_SHADER => glVertexShader();
-
-  attachShader(program, shader) => glAttachShader(program, shader);
-  bindBuffer(target, buffer) => glBindBuffer(target, buffer);
-  bufferData(target, data, usage) => glBufferData(target, data, usage);
-  clearColor(r, g, b, alpha) => glClearColor(r, g, b, alpha);
-  clearDepth(depth) => glClearDepth(depth);
-  clear(mask) => glClear(mask);
-  compileShader(shader) => glCompileShader(shader);
-  createBuffer() => glCreateBuffer();
-  createProgram() => glCreateProgram();
-  createShader(shaderType) => glCreateShader(shaderType);
-  drawArrays(mode, first, count) => glDrawArrays(mode, first, count);
-  enableVertexAttribArray(index) => glEnableVertexAttribArray(index);
-  getAttribLocation(program, name) => glGetAttribLocation(program, name);
-  getError() => glGetError();
-  getProgramParameter(program, name) {
-    var rtn = glGetProgramParameter(program, name);
-    if (name == DELETE_STATUS ||
-        name == LINK_STATUS ||
-        name == VALIDATE_STATUS) {
-      return (rtn == 0) ? false : true;
-    }
-    return rtn;
-  }
-  getShaderParameter(shader, name) {
-    var rtn = glGetShaderParameter(shader, name);
-    if (name == DELETE_STATUS || name == COMPILE_STATUS) {
-      return (rtn == 0) ? false : true;
-    }
-    return rtn;
-  }
-  getUniformLocation(program, name) => glGetUniformLocation(program, name);
-  linkProgram(program) => glLinkProgram(program);
-  shaderSource(shader, source) => glShaderSource(shader, source);
-  uniform1f(location, v0) => glUniform1f(location, v0);
-  uniform2f(location, v0, v1) => glUniform2f(location, v0, v1);
-  uniform3f(location, v0, v1, v2) => glUniform3f(location, v0, v1, v2);
-  uniform4f(location, v0, v1, v2, v3) => glUniform4f(location, v0, v1, v2, v3);
-  uniform1i(location, v0) => glUniform1i(location, v0);
-  uniform2i(location, v0, v1) => glUniform2i(location, v0, v1);
-  uniform3i(location, v0, v1, v2) => glUniform3i(location, v0, v1, v2);
-  uniform4i(location, v0, v1, v2, v3) => glUniform4i(location, v0, v1, v2, v3);
-  uniform1fv(location, values) => glUniform1fv(location, values);
-  uniform2fv(location, values) => glUniform2fv(location, values);
-  uniform3fv(location, values) => glUniform3fv(location, values);
-  uniform4fv(location, values) => glUniform4fv(location, values);
-  uniform1iv(location, values) => glUniform1iv(location, values);
-  uniform2iv(location, values) => glUniform2iv(location, values);
-  uniform3iv(location, values) => glUniform3iv(location, values);
-  uniform4iv(location, values) => glUniform4iv(location, values);
-  useProgram(program) => glUseProgram(program);
-  vertexAttribPointer(index, size, type, normalized, stride, pointer) =>
-    glVertexAttribPointer(index, size, type, normalized, stride, pointer);
-  viewport(x, y, width, height) => glViewport(x, y, width, height);
-  getShaderInfoLog(shader) => glGetShaderInfoLog(shader);
-  getProgramInfoLog(program) => glGetProgramInfoLog(program);
-
-  // TODO(vsm): Kill.
-  noSuchMethod(invocation) {
-      throw new Exception('Unimplemented ${invocation.memberName}');
-  }
-}
-
-//------------------------------------------------------------------
-// Simple audio support.
-
-void playBackground(String path) native "PlayBackground";
-void stopBackground() native "StopBackground";
-
-//-------------------------------------------------------------------
-// Set up print().
-
-get _printClosure => (s) {
-  try {
-    log(s);
-  } catch (_) {
-    throw(s);
-  }
-};
-
-//------------------------------------------------------------------
-// Temp hack for compat with WebGL.
-
-class Float32Array extends List<double> {
-  Float32Array.fromList(List a) {
-    addAll(a);
-  }
-}
-
-//------------------------------------------------------------------
-// 2D canvas support
-
-int _SetWidth(int handle, int width)
-    native "C2DSetWidth";
-int _SetHeight(int handle, int height)
-    native "C2DSetHeight";
-
-double _SetGlobalAlpha(int handle, double globalAlpha)
-    native "C2DSetGlobalAlpha";
-void _SetFillStyle(int handle, fs)
-    native "C2DSetFillStyle";
-String _SetFont(int handle, String font)
-    native "C2DSetFont";
-void _SetGlobalCompositeOperation(int handle, String op)
-    native "C2DSetGlobalCompositeOperation";
-_SetLineCap(int handle, String lc)
-    native "C2DSetLineCap";
-_SetLineJoin(int handle, String lj)
-    native "C2DSetLineJoin";
-_SetLineWidth(int handle, double w)
-    native "C2DSetLineWidth";
-_SetMiterLimit(int handle, double limit)
-    native "C2DSetMiterLimit";
-_SetShadowBlur(int handle, double blur)
-    native "C2DSetShadowBlur";
-_SetShadowColor(int handle, String color)
-    native "C2DSetShadowColor";
-_SetShadowOffsetX(int handle, double offset)
-    native "C2DSetShadowOffsetX";
-_SetShadowOffsetY(int handle, double offset)
-    native "C2DSetShadowOffsetY";
-void _SetStrokeStyle(int handle, ss)
-    native "C2DSetStrokeStyle";
-String _SetTextAlign(int handle, String align)
-    native "C2DSetTextAlign";
-String _SetTextBaseline(int handle, String baseline)
-    native "C2DSetTextBaseline";
-_GetBackingStorePixelRatio(int handle)
-    native "C2DGetBackingStorePixelRatio";
-void _SetImageSmoothingEnabled(int handle, bool ise)
-    native "C2DSetImageSmoothingEnabled";    
-void _SetLineDash(int handle, List v)
-    native "C2DSetLineDash";
-_SetLineDashOffset(int handle, int v)
-    native "C2DSetLineDashOffset";
-void _Arc(int handle, double x, double y, double radius,
-    double startAngle, double endAngle, [bool anticlockwise = false])
-    native "C2DArc";
-void _ArcTo(int handle, double x1, double y1,
-              double x2, double y2, double radius)
-    native "C2DArcTo"; 
-void _ArcTo2(int handle, double x1, double y1,
-               double x2, double y2, double radiusX,
-    double radiusY, double rotation)
-    native "C2DArcTo2"; 
-void _BeginPath(int handle)
-    native "C2DBeginPath";
-void _BezierCurveTo(int handle, double cp1x, double cp1y,
-                      double cp2x, double cp2y, double x, double y)
-    native "C2DBezierCurveTo";
-void _ClearRect(int handle, double x, double y, double w, double h)
-    native "C2DClearRect";
-void _Clip(int handle)
-    native "C2DClip";
-void _ClosePath(int handle)
-    native "C2DClosePath";
-ImageData _CreateImageDataFromDimensions(int handle, num w, num h)
-    native "C2DCreateImageDataFromDimensions";
-void _DrawImage(int handle, String src_url,
-                  int sx, int sy,
-                  bool has_src_dimensions, int sw, int sh,
-                  int dx, int dy,
-                  bool has_dst_dimensions, int dw, int dh)
-    native "C2DDrawImage";
-void _Fill(int handle)
-    native "C2DFill";
-void _FillRect(int handle, double x, double y, double w, double h)
-    native "C2DFillRect";
-void _FillText(int handle, String text, double x, double y, double maxWidth)
-    native "C2DFillText";
-ImageData _GetImageData(num sx, num sy, num sw, num sh)
-    native "C2DGetImageData";    
-void _LineTo(int handle, double x, double y)
-    native "C2DLineTo";
-double _MeasureText(int handle, String text)
-    native "C2DMeasureText";
-void _MoveTo(int handle, double x, double y)
-    native "C2DMoveTo";
-void _PutImageData(int handle, ImageData imagedata, double dx, double dy)
-    native "C2DPutImageData";    
-void _QuadraticCurveTo(int handle, double cpx, double cpy,
-    double x, double y)
-        native "C2DQuadraticCurveTo";
-void _Rect(int handle, double x, double y, double w, double h)
-    native "C2DRect";
-void _Restore(int handle)
-    native "C2DRestore";
-void _Rotate(int handle, double a)
-    native "C2DRotate";
-void _Save(int handle)
-    native "C2DSave";
-void _Scale(int handle, double sx, double sy)
-    native "C2DScale";
-void _SetTransform(int handle, double m11, double m12,
-                     double m21, double m22, double dx, double dy)
-    native "C2DSetTransform";
-void _Stroke(int handle)
-    native "C2DStroke";
-void _StrokeRect(int handle, double x, double y, double w, double h)
-    native "C2DStrokeRect";    
-void _StrokeText(int handle, String text, double x, double y,
-    double maxWidth)
-        native "C2DStrokeText";
-void _Transform(int handle, double m11, double m12,
-                  double m21, double m22, double dx, double dy)
-    native "C2DTransform";
-void _Translate(int handle, double x, double y)
-    native "C2DTranslate";
-
-void _CreateNativeContext(int handle, int width, int height)
-    native "C2DCreateNativeContext";
-
-void _SetFillGradient(int handle, bool isRadial,
-        double x0, double y0, double r0,
-        double x1, double y1, double r1,
-        List<double> positions, List<String> colors)
-    native "C2DSetFillGradient";
-
-void _SetStrokeGradient(int handle, bool isRadial,
-        double x0, double y0, double r0,
-        double x1, double y1, double r1,
-        List<double> positions, List<String> colors)
-    native "C2DSetStrokeGradient";
-
-int _GetImageWidth(String url)
-    native "C2DGetImageWidth";
-
-int _GetImageHeight(String url)
-    native "C2DGetImageHeight";
-
-class CanvasGradient {
-  num _x0, _y0, _r0 = 0, _x1, _y1, _r1 = 0;
-  bool _isRadial;
-  List<double> _colorStopPositions = [];
-  List<String> _colorStopColors = [];
-
-  void addColorStop(num offset, String color) {
-    _colorStopPositions.add(offset.toDouble());
-    _colorStopColors.add(color);
-  }
-
-  CanvasGradient.linear(this._x0, this._y0, this._x1, this._y1)
-      : _isRadial = false;
-  
-  CanvasGradient.radial(this._x0, this._y0, this._r0,
-                        this._x1, this._y1, this._r1)
-      : _isRadial = true;
-
-  void setAsFillStyle(_handle) {
-    _SetFillGradient(_handle, _isRadial,
-        _x0.toDouble(), _y0.toDouble(), _r0.toDouble(),
-        _x1.toDouble(), _y1.toDouble(), _r1.toDouble(),
-        _colorStopPositions, _colorStopColors);
-  }
-
-  void setAsStrokeStyle(_handle) {
-    _SetStrokeGradient(_handle, _isRadial,
-        _x0.toDouble(), _y0.toDouble(), _r0.toDouble(),
-        _x1.toDouble(), _y1.toDouble(), _r1.toDouble(),
-        _colorStopPositions, _colorStopColors);
-  }
-}
-
-class ImageElement extends Node {
-  Stream<Event> get onLoad => new _EventStream(this, 'load');
-
-  String _src;
-  int _width;
-  int _height;
-
-  get src => _src;
-
-  set src(String v) {
-    log("Set ImageElement src to $v");
-    _src = v;
-  }
-
-  // The onLoad handler may be set after the src, so
-  // we hook into that here...
-  void addListener(String eventType, EventListener handler) {
-    super.addListener(eventType, handler);
-    if (eventType == 'load') {
-      var e = new Event('load');
-      e.target = this;
-      window._scheduleCallback(handler, e);
-    }
-  }
-
-  get width => _width == null ? _width = _GetImageWidth(_src) : _width;
-  get height => _height == null ? _height = _GetImageHeight(_src) : _height;
-  set width(int widthp) => _width = widthp;
-  set height(int heightp) => _height = heightp;
-
-  ImageElement({String srcp, int widthp, int heightp})
-    : _src = srcp,
-      _width = widthp,
-      _height = heightp {
-    if (_src != null) {
-      if (_width == null) _width = _GetImageWidth(_src);
-      if (_height == null) _height = _GetImageHeight(_src);
-    }
-  }
-}
-
-class ImageData {
-  final Uint8ClampedArray data;
-  final int height;
-  final int width;
-  ImageData(this.height, this.width, this.data);
-}
-
-class TextMetrics {
-  final num width;
-  TextMetrics(this.width);
-}
-
-void shutdown() {
-  CanvasRenderingContext2D.next_handle = 0;
-}
-
-class Rect {
-  final num top, left, width, height;
-  const Rect(this.left, this.top, this.width, this.height);
-}
-
-class CanvasRenderingContext2D extends CanvasRenderingContext {
-  // TODO(gram): We need to support multiple contexts, for cached content
-  // prerendered to an offscreen buffer. For this we will use handles, with
-  // handle 0 being the physical display.
-  static int next_handle = 0;
-  int _handle = 0;
-  get handle => _handle;
-
-  int _width, _height;
-  set width(int w) { _width = SetWidth(_handle, w); }
-  get width => _width;
-  set height(int h) { _height = SetHeight(_handle, h); }
-  get height => _height;
-
-  CanvasRenderingContext2D(canvas, width, height) : super(canvas) {
-    _width = width;
-    _height = height;
-    _CreateNativeContext(_handle = next_handle++, width, height);
-  }
-
-  double _alpha = 1.0;
-  set globalAlpha(num a) {
-    _alpha = _SetGlobalAlpha(_handle, a.toDouble());
-  }
-  get globalAlpha => _alpha;
-
-  // TODO(gram): make sure we support compound assignments like:
-  // fillStyle = strokeStyle = "red"
-  var _fillStyle = "#000";
-  set fillStyle(fs) {
-    _fillStyle = fs;
-    // TODO(gram): Support for CanvasPattern.
-    if (fs is CanvasGradient) {
-      fs.setAsFillStyle(_handle);
-    } else {
-      _SetFillStyle(_handle, fs);
-    }
-  }
-  get fillStyle => _fillStyle;
-
-  String _font = "10px sans-serif";
-  set font(String f) { _font = _SetFont(_handle, f); }
-  get font => _font;
-
-  String _globalCompositeOperation = "source-over";
-  set globalCompositeOperation(String o) =>
-      _SetGlobalCompositeOperation(_handle, _globalCompositeOperation = o);
-  get globalCompositeOperation => _globalCompositeOperation;
-
-  String _lineCap = "butt"; // "butt", "round", "square"
-  get lineCap => _lineCap;
-  set lineCap(String lc) => _SetLineCap(_handle, _lineCap = lc);
-
-  int _lineDashOffset = 0;
-  get lineDashOffset => _lineDashOffset;
-  set lineDashOffset(num v) {
-    _lineDashOffset = v.toInt();
-    _SetLineDashOffset(_handle, _lineDashOffset);
-  }
-
-  String _lineJoin = "miter"; // "round", "bevel", "miter"
-  get lineJoin => _lineJoin;
-  set lineJoin(String lj) =>  _SetLineJoin(_handle, _lineJoin = lj);
-
-  num _lineWidth = 1.0;
-  get lineWidth => _lineWidth;
-  set lineWidth(num w) {
-    _SetLineWidth(_handle, w.toDouble());
-    _lineWidth = w;
-  }
-
-  num _miterLimit = 10.0; // (default 10)
-  get miterLimit => _miterLimit;
-  set miterLimit(num limit) {
-    _SetMiterLimit(_handle, limit.toDouble());
-    _miterLimit = limit;
-  }
-
-  num _shadowBlur;
-  get shadowBlur =>  _shadowBlur;
-  set shadowBlur(num blur) {
-    _shadowBlur = blur;
-    _SetShadowBlur(_handle, blur.toDouble());
-  }
-
-  String _shadowColor;
-  get shadowColor => _shadowColor;
-  set shadowColor(String color) =>
-      _SetShadowColor(_handle, _shadowColor = color);
-  
-  num _shadowOffsetX;
-  get shadowOffsetX => _shadowOffsetX;
-  set shadowOffsetX(num offset) {
-    _shadowOffsetX = offset;
-    _SetShadowOffsetX(_handle, offset.toDouble());
-  }
-
-  num _shadowOffsetY;
-  get shadowOffsetY => _shadowOffsetY;
-  set shadowOffsetY(num offset) {
-    _shadowOffsetY = offset;
-    _SetShadowOffsetY(_handle, offset.toDouble());
-  }
-
-  var _strokeStyle = "#000";
-  get strokeStyle => _strokeStyle;
-  set strokeStyle(ss) {
-    _strokeStyle = ss;
-    // TODO(gram): Support for CanvasPattern.
-    if (ss is CanvasGradient) {
-      ss.setAsStrokeStyle(_handle);
-    } else {
-      _SetStrokeStyle(_handle, ss);
-    }
-  }
-
-  String _textAlign = "start";
-  get textAlign => _textAlign;
-  set textAlign(String a) { _textAlign = _SetTextAlign(_handle, a); }
-
-  String _textBaseline = "alphabetic";
-  get textBaseline => _textBaseline;
-  set textBaseline(String b) { _textBaseline = _SetTextBaseline(_handle, b); }
-
-  get webkitBackingStorePixelRatio => _GetBackingStorePixelRatio(_handle);
-
-  bool _webkitImageSmoothingEnabled;
-  get webkitImageSmoothingEnabled => _webkitImageSmoothingEnabled;
-  set webkitImageSmoothingEnabled(bool v) =>
-     _SetImageSmoothingEnabled(_webkitImageSmoothingEnabled = v);
-
-  get webkitLineDash => lineDash;
-  set webkitLineDash(List v) => lineDash = v;
-
-  get webkitLineDashOffset => lineDashOffset;
-  set webkitLineDashOffset(num v) => lineDashOffset = v;
-
-  // Methods
-
-  void arc(num x, num y, num radius, num a1, num a2, bool anticlockwise) {
-    if (radius < 0) {
-      // throw IndexSizeError
-    } else {
-      _Arc(_handle, x.toDouble(), y.toDouble(), radius.toDouble(),
-          a1.toDouble(), a2.toDouble(), anticlockwise);
-    }
-  }
-
-  // Note - looking at the Dart docs it seems Dart doesn't support
-  // the second form in the browser.
-  void arcTo(num x1, num y1, num x2, num y2,
-    num radiusX, [num radiusY, num rotation]) {
-    if (radiusY == null) {
-      _ArcTo(_handle, x1.toDouble(), y1.toDouble(),
-                        x2.toDouble(), y2.toDouble(), radiusX.toDouble());
-    } else {
-      _ArcTo2(_handle, x1.toDouble(), y1.toDouble(),
-                         x2.toDouble(), y2.toDouble(),
-                         radiusX.toDouble(), radiusY.toDouble(),
-                         rotation.toDouble());
-    }
-  }
-
-  void beginPath() => _BeginPath(_handle);
-
-  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y,
-    num x, num y) =>
-    _BezierCurveTo(_handle, cp1x.toDouble(), cp1y.toDouble(),
-                              cp2x.toDouble(), cp2y.toDouble(),
-                              x.toDouble(), y.toDouble());
-
-  void clearRect(num x, num y, num w, num h) =>
-    _ClearRect(_handle, x.toDouble(), y.toDouble(),
-        w.toDouble(), h.toDouble());
-
-  void clip() => _Clip(_handle);
-
-  void closePath() => _ClosePath(_handle);
-
-  ImageData createImageData(var imagedata_OR_sw, [num sh = null]) {
-    if (sh == null) {
-      throw new Exception('Unimplemented createImageData(imagedata)');
-    } else {
-      return _CreateImageDataFromDimensions(_handle, imagedata_OR_sw, sh);
-    }
-  }
-
-  CanvasGradient createLinearGradient(num x0, num y0, num x1, num y1) {
-    return new CanvasGradient.linear(x0, y0, x1, y1);
-  }
-
-  CanvasPattern createPattern(canvas_OR_image, String repetitionType) {
-    throw new Exception('Unimplemented createPattern');
-  }
-
-  CanvasGradient createRadialGradient(num x0, num y0, num r0,
-                                      num x1, num y1, num r1) {
-    return new CanvasGradient.radial(x0, y0, r0, x1, y1, r1);
-  }
-
-  void _drawImage(element, num x1, num y1,
-                [num w1, num h1, num x2, num y2, num w2, num h2]) {
-    if (element == null || element.src == null || element.src.length == 0) {
-      throw "drawImage called with no valid src";
-    } else {
-      log("drawImage ${element.src}");
-    }
-    var w = (element.width == null) ? 0 : element.width;
-    var h = (element.height == null) ?  0 : element.height;
-    if (!?w1) { // drawImage(element, dx, dy)
-      _DrawImage(_handle, element.src, 0, 0, false, w, h,
-                   x1.toInt(), y1.toInt(), false, 0, 0);
-    } else if (!?x2) {  // drawImage(element, dx, dy, dw, dh)
-      _DrawImage(_handle, element.src, 0, 0, false, w, h,
-                   x1.toInt(), y1.toInt(), true, w1.toInt(), h1.toInt());
-    } else {  // drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
-      _DrawImage(_handle, element.src, 
-                   x1.toInt(), y1.toInt(), true, w1.toInt(), h1.toInt(),
-                   x2.toInt(), y2.toInt(), true, w2.toInt(), h2.toInt());
-    }
-  }
-
-  void drawImage(source, num destX, num destY) {
-    _drawImage(source, destX, destY);
-  }
-
-  void drawImageScaled(source,
-      num destX, num destY, num destWidth, num destHeight) {
-    _drawImage(source, destX,  destY, destWidth, destHeight);
-  }
-
-  void drawImageScaledFromSource(source,
-      num sourceX, num sourceY, num sourceWidth, num sourceHeight,
-      num destX, num destY, num destWidth, num destHeight) {
-    _drawImage(source, sourceX, sourceY, sourceWidth, sourceHeight,
-        destX, destY, destWidth, destHeight);
-  }
-
-  void drawImageToRect(source, Rect dest, {Rect sourceRect}) {
-    if (sourceRect == null) {
-      _drawImage(source, dest.left, dest.top, dest.width, dest.height);
-    } else {
-      _drawImage(source,
-         sourceRect.left, sourceRect.top, sourceRect.width, sourceRect.height,
-         dest.left, dest.top, dest.width, dest.height);
-    }
-  }
-
-  void fill() => _Fill(_handle);
-
-  void fillRect(num x, num y, num w, num h) =>
-    _FillRect(_handle, x.toDouble(), y.toDouble(),
-                         w.toDouble(), h.toDouble());
-
-  void fillText(String text, num x, num y, [num maxWidth = -1]) =>
-    _FillText(_handle, text, x.toDouble(), y.toDouble(),
-                                 maxWidth.toDouble());
-
-  ImageData getImageData(num sx, num sy, num sw, num sh) =>
-    _GetImageData(sx, sy, sw, sh);
-
-  List<double> _lineDash = null;
-  List<num> getLineDash() {
-    if (_lineDash == null) return [];
-    return _lineDash;  // TODO(gram): should we return a copy?
-  }
-
-  bool isPointInPath(num x, num y) {
-    throw new Exception('Unimplemented isPointInPath');
-  }
-
-  void lineTo(num x, num y) {
-    _LineTo(_handle, x.toDouble(), y.toDouble());
-  }
-
-  TextMetrics measureText(String text) {
-    double w = _MeasureText(_handle, text);
-    return new TextMetrics(w);
-  }
-
-  void moveTo(num x, num y) =>
-    _MoveTo(_handle, x.toDouble(), y.toDouble());
-
-  void putImageData(ImageData imagedata, num dx, num dy,
-                   [num dirtyX, num dirtyY, num dirtyWidth, num dirtyHeight]) {
-    if (dirtyX != null || dirtyY != null) {
-      throw new Exception('Unimplemented putImageData');
-    } else {
-      _PutImageData(_handle, imagedata, dx, dy);
-    }
-  }
-
-  void quadraticCurveTo(num cpx, num cpy, num x, num y) =>
-    _QuadraticCurveTo(_handle, cpx.toDouble(), cpy.toDouble(),
-                        x.toDouble(), y.toDouble());
-
-  void rect(num x, num y, num w, num h) =>
-    _Rect(_handle, x.toDouble(), y.toDouble(), w.toDouble(), h.toDouble());
-
-  void restore() => _Restore(_handle);
-
-  void rotate(num angle) => _Rotate(_handle, angle.toDouble());
-
-  void save() => _Save(_handle);
-
-  void scale(num x, num y) => _Scale(_handle, x.toDouble(), y.toDouble());
-
-  void setFillColorHsl(int h, num s, num l, [num a = 1]) {
-    throw new Exception('Unimplemented setFillColorHsl');
-  }
-
-  void setFillColorRgb(int r, int g, int b, [num a = 1]) {
-    throw new Exception('Unimplemented setFillColorRgb');
-  }
-
-  void setLineDash(List<num> dash) {
-    var valid = true;
-    var new_dash;
-    if (dash.length % 2 == 1) {
-      new_dash = new List<double>(2 * dash.length);
-      for (int i = 0; i < dash.length; i++) {
-        double v = dash[i].toDouble();
-        if (v < 0) {
-          valid = false;
-          break;
-        }
-        new_dash[i] = new_dash[i + dash.length] = v;
-      }
-    } else {
-      new_dash = new List<double>(dash.length);
-      for (int i = 0; i < dash.length; i++) {
-        double v = dash[i].toDouble();
-        if (v < 0) {
-          valid = false;
-          break;
-        }
-        new_dash[i] = v;
-      }
-    }
-    if (valid) {
-      _SetLineDash(_handle, _lineDash = new_dash);
-    }
-  }
-
-  void setStrokeColorHsl(int h, num s, num l, [num a = 1]) {
-    throw new Exception('Unimplemented setStrokeColorHsl');
-  }
-
-  void setStrokeColorRgb(int r, int g, int b, [num a = 1]) {
-    throw new Exception('Unimplemented setStrokeColorRgb');
-  }
-
-  void setTransform(num m11, num m12, num m21, num m22, num dx, num dy) =>
-    _SetTransform(_handle, m11.toDouble(), m12.toDouble(),
-                           m21.toDouble(), m22.toDouble(),
-                           dx.toDouble(), dy.toDouble());
-
-  void stroke() => _Stroke(_handle);
-
-  void strokeRect(num x, num y, num w, num h, [num lineWidth]) =>
-    _StrokeRect(_handle, x.toDouble(), y.toDouble(),
-        w.toDouble(), h.toDouble());
-
-  void strokeText(String text, num x, num y, [num maxWidth = -1]) =>
-    _StrokeText(_handle, text, x.toDouble(), y.toDouble(),
-        maxWidth.toDouble());
-
-  void transform(num m11, num m12, num m21, num m22, num dx, num dy) =>
-    _Transform(_handle, m11.toDouble(), m12.toDouble(),
-                        m21.toDouble(), m22.toDouble(),
-                        dx.toDouble(), dy.toDouble());
-
-  void translate(num x, num y) =>
-    _Translate(_handle, x.toDouble(), y.toDouble());
-
-  ImageData webkitGetImageDataHD(num sx, num sy, num sw, num sh) {
-    throw new Exception('Unimplemented webkitGetImageDataHD');
-  }
-
-  void webkitPutImageDataHD(ImageData imagedata, num dx, num dy,
-                           [num dirtyX, num dirtyY,
-                            num dirtyWidth, num dirtyHeight]) {
-    throw new Exception('Unimplemented webkitGetImageDataHD');
-  }
-
-  // TODO(vsm): Kill.
-  noSuchMethod(invocation) {
-      throw new Exception('Unimplemented/unknown ${invocation.memberName}');
-  }
-}
-
-var sfx_extension = 'raw';
-int _loadSample(String s) native "LoadSample";
-int _playSample(String s) native "PlaySample";
diff --git a/runtime/embedders/openglui/common/graphics_handler.cc b/runtime/embedders/openglui/common/graphics_handler.cc
deleted file mode 100644
index 449facb..0000000
--- a/runtime/embedders/openglui/common/graphics_handler.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/common/graphics_handler.h"
-#include "embedders/openglui/common/canvas_context.h"
-#include "embedders/openglui/common/log.h"
-
-extern void CheckGLError(const char *function);
-
-GraphicsHandler* graphics;
-extern CanvasContext* display_context;
-
-GraphicsHandler::GraphicsHandler(const char* resource_path)
-  : resource_path_(resource_path),
-    ag(),
-    grcontext(NULL),
-    width_(0),
-    height_(0) {
-  graphics = this;
-  DecoderHack(0, NULL);
-}
-
-void GraphicsHandler::DecoderHack(int x, SkStream* s) {
-  if (x) {  // hack to keep the linker from throwing these out
-    extern SkImageDecoder* sk_libpng_dfactory(SkStream* s);
-    sk_libpng_dfactory(s);
-
-    // TODO(gram): For some reason I get linker errors on these, even though
-    // they are defined in libskia_images. Figure out why...
-    /*
-    extern SkImageDecoder* sk_libjpeg_dfactory(SkStream* s);
-    extern SkImageDecoder* sk_libbmp_dfactory(SkStream* s);
-    extern SkImageDecoder* sk_libgif_dfactory(SkStream* s);
-    extern SkImageDecoder* sk_libico_dfactory(SkStream* s);
-    extern SkImageDecoder* sk_libwbmp_dfactory(SkStream* s);
-    sk_libjpeg_dfactory(s);
-    sk_libbmp_dfactory(s);
-    sk_libgif_dfactory(s);
-    sk_libico_dfactory(s);
-    sk_libwbmp_dfactory(s);
-    */
-  }
-}
-
-// Kludge to get around an issue with Android emulator, which returns
-// NULL for the shader language version, causing Skia to blow up.
-const GrGLubyte* myGLGetString(GLenum name) {
-  const GrGLubyte* str = glGetString(name);
-  if (NULL == str && GL_SHADING_LANGUAGE_VERSION == name) {
-    return reinterpret_cast<GrGLubyte*>(
-        const_cast<char*>("OpenGL ES GLSL ES 1.0"));
-  } else {
-    return str;
-  }
-}
-
-int32_t GraphicsHandler::Start() {
-  GrGLInterface* fGL = const_cast<GrGLInterface*>(GrGLCreateNativeInterface());
-  LOGI("Created native interface %s\n", fGL ? "succeeded" : "failed");
-  fGL->fGetString = myGLGetString;
-  grcontext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fGL);
-  LOGI("Created GrContext %s\n", grcontext ? "succeeded" : "failed");
-  return 0;
-}
-
-void GraphicsHandler::Stop() {
-  LOGI("Releasing display context");
-  FreeContexts();
-  grcontext->unref();
-  grcontext = NULL;
-}
-
-SkCanvas* GraphicsHandler::CreateDisplayCanvas() {
-  GrBackendRenderTargetDesc desc;
-  desc.fWidth = width_;
-  desc.fHeight = height_;
-  desc.fConfig = kSkia8888_GrPixelConfig;
-  desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
-  glGetIntegerv(GL_SAMPLES, &desc.fSampleCnt);
-  glGetIntegerv(GL_STENCIL_BITS, &desc.fStencilBits);
-  LOGI("Creating %dx%d display canvas, samples %d, stencil bits %d",
-    width_, height_, desc.fSampleCnt, desc.fStencilBits);
-  GrGLint buffer;
-  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &buffer);
-  desc.fRenderTargetHandle = buffer;
-  GrRenderTarget* fGrRenderTarget = grcontext->wrapBackendRenderTarget(desc);
-  SkGpuDevice* device = new SkGpuDevice(grcontext, fGrRenderTarget);
-//  fGrRenderTarget->unref(); // TODO(gram):  determine if we need this.
-  SkCanvas* canvas = new SkCanvas(device);
-  device->unref();
-  return canvas;
-}
-
-SkCanvas* GraphicsHandler::CreateBitmapCanvas(int width, int height) {
-  LOGI("Creating %dx%d bitmap canvas", width, height);
-  SkDevice* rasterDevice =
-      new SkDevice(SkBitmap::kARGB_8888_Config, width, height);
-  SkCanvas* canvas = new SkCanvas(rasterDevice);
-  rasterDevice->unref();
-  return canvas;
-}
-
-void GraphicsHandler::SetViewport(int left, int top, int width, int height) {
-  width_ = width;
-  height_ = height;
-  glViewport(left, top, width, height);
-  CheckGLError("glViewPort");
-}
-
-int32_t GraphicsHandler::Update() {
-  LOGI("In GraphicsHandler::Update, display_context dirty %s",
-    (display_context == NULL ? "NULL" :
-        (display_context->isDirty() ? "yes":"no")));
-  if (display_context != NULL && display_context->isDirty()) {
-    LOGI("Flushing display context\n");
-    display_context->Flush();
-    SwapBuffers();
-    display_context->clearDirty();
-  }
-  return 0;
-}
-
diff --git a/runtime/embedders/openglui/common/graphics_handler.h b/runtime/embedders/openglui/common/graphics_handler.h
deleted file mode 100644
index 77f57ec..0000000
--- a/runtime/embedders/openglui/common/graphics_handler.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_GRAPHICS_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_COMMON_GRAPHICS_HANDLER_H_
-
-#include "embedders/openglui/common/isized.h"
-#include "embedders/openglui/common/opengl.h"
-#include "embedders/openglui/common/support.h"
-#include "embedders/openglui/common/timer.h"
-
-class GraphicsHandler : public ISized {
-  private:
-    void DecoderHack(int x, SkStream* s);
-
-  public:
-    explicit GraphicsHandler(const char* resource_path);
-
-    const int32_t& height() {
-      return height_;
-    }
-
-    const int32_t& width() {
-      return width_;
-    }
-
-    void ApplyOrtho(float maxX, float maxY) const;
-    void ApplyRotation(float degrees) const;
-
-    virtual int32_t Start();
-    virtual void Stop();
-
-    void SwapBuffers() {
-      GLSwapBuffers();
-    }
-
-    virtual int32_t Update();
-
-    void SetViewport(int left, int top, int width, int height);
-
-    SkCanvas* CreateDisplayCanvas();
-    SkCanvas* CreateBitmapCanvas(int width, int height);
-
-    inline const char* resource_path() {
-      return resource_path_;
-    }
-
-    virtual ~GraphicsHandler() {
-    }
-
-  protected:
-    const char* resource_path_;
-    SkAutoGraphics ag;
-    GrContext* grcontext;
-    int32_t width_, height_;
-};
-
-extern GraphicsHandler* graphics;
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_GRAPHICS_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/common/image_cache.cc b/runtime/embedders/openglui/common/image_cache.cc
deleted file mode 100644
index 957f7ea..0000000
--- a/runtime/embedders/openglui/common/image_cache.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/common/image_cache.h"
-
-#include <ctype.h>
-#include <string.h>
-#include "core/SkStream.h"
-#include "embedders/openglui/common/canvas_context.h"
-
-ImageCache* ImageCache::instance_ = NULL;
-
-extern CanvasContext* Context2D(int handle);
-
-ImageCache::ImageCache(const char* resource_path)
-    : images(), resource_path_(resource_path) {
-}
-
-const SkBitmap* ImageCache::GetImage_(const char* src_url) {
-  if (strncmp(src_url, "context2d://", 12) == 0) {
-    int handle = atoi(src_url + 12);
-    CanvasContext* otherContext = Context2D(handle);
-    return otherContext->GetBitmap();
-  } else if (images.find(src_url) == images.end()) {
-    SkBitmap* bm = Load(src_url);
-    if (bm != NULL) {
-      images[src_url] = bm;
-    }
-    return bm;
-  } else {
-    return images[src_url];
-  }
-}
-
-int ImageCache::GetWidth_(const char* src_url) {
-  const SkBitmap* image = GetImage(src_url);
-  if (image == NULL) return 0;
-  return image->width();
-}
-
-int ImageCache::GetHeight_(const char* src_url) {
-  const SkBitmap* image = GetImage(src_url);
-  if (image == NULL) return 0;
-  return image->height();
-}
-
-SkBitmap* ImageCache::Load(const char* src_url) {
-  SkBitmap *bm = NULL;
-  const char* filepath;
-  if (strncmp(src_url, "file://", 7) == 0) {
-    filepath = src_url + 7;
-  } else {
-    // TODO(gram): We need a way to remap URLs to local file names.
-    // For now I am just using the characters after the last '/'.
-    // Note also that if we want to support URLs and network fetches,
-    // then we introduce more complexity; this can't just be an URL.
-    int pos = strlen(src_url);
-    while (--pos >= 0 && src_url[pos] != '/');
-    filepath = src_url + pos + 1;
-  }
-  char* path;
-  if (filepath[0] == '/') {
-    path = const_cast<char*>(filepath);
-  } else {
-    size_t len1 = strlen(resource_path_);
-    size_t len2 = strlen(filepath);
-    path = new char[len1 + 1 + len2 + 1];
-    strncpy(path, resource_path_, len1+1);
-    strncat(path, "/", 1);
-    strncat(path, filepath, len2);
-  }
-
-  SkFILEStream stream(path);
-  if (stream.isValid()) {
-    // We could use DecodeFile and pass the path, but by creating the
-    // SkStream here we can produce better error log messages.
-    bm = new SkBitmap();
-    if (!SkImageDecoder::DecodeStream(&stream, bm)) {
-      LOGI("Image decode of %s failed", path);
-      return NULL;
-    } else {
-      LOGI("Decode image %s: width=%d,height=%d",
-          path, bm->width(), bm->height());
-    }
-  } else {
-    LOGI("Path %s is invalid", path);
-  }
-
-  if (path != filepath) {
-    delete[] path;
-  }
-  return bm;
-}
-
diff --git a/runtime/embedders/openglui/common/image_cache.h b/runtime/embedders/openglui/common/image_cache.h
deleted file mode 100644
index 4aa22f8..0000000
--- a/runtime/embedders/openglui/common/image_cache.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_IMAGE_CACHE_H_
-#define EMBEDDERS_OPENGLUI_COMMON_IMAGE_CACHE_H_
-
-#include <map>
-#include <string>
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/opengl.h"
-#include "embedders/openglui/common/support.h"
-
-class ImageCache {
- public:
-  static void Init(const char *resource_path) {
-    if (instance_ == NULL) {
-      instance_ = new ImageCache(resource_path);
-    }
-  }
-
-  inline static const SkBitmap* GetImage(const char* src_url) {
-    if (instance_ == NULL) {
-      fprintf(stderr, "GetImage called with no instance_\n");
-      return NULL;
-    }
-    return instance_->GetImage_(src_url);
-  }
-
-  inline static int GetWidth(const char* src_url) {
-    if (instance_ == NULL) {
-      fprintf(stderr, "GetWidth called with no instance_\n");
-      return NULL;
-    }
-    return instance_->GetWidth_(src_url);
-  }
-
-  inline static int GetHeight(const char* src_url) {
-    if (instance_ == NULL) {
-      fprintf(stderr, "GetHeight called with no instance_\n");
-      return NULL;
-    }
-    return instance_->GetHeight_(src_url);
-  }
-
- private:
-  explicit ImageCache(const char* resource_path);
-  SkBitmap* Load(const char* src_url);
-  const SkBitmap* GetImage_(const char* src_url);
-  int GetWidth_(const char* src_url);
-  int GetHeight_(const char* src_url);
-
-  std::map<std::string, SkBitmap*> images;
-  const char* resource_path_;
-  static ImageCache* instance_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_IMAGE_CACHE_H_
diff --git a/runtime/embedders/openglui/common/input_handler.cc b/runtime/embedders/openglui/common/input_handler.cc
deleted file mode 100644
index 7c4c3d2..0000000
--- a/runtime/embedders/openglui/common/input_handler.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/common/input_handler.h"
-#include "embedders/openglui/common/log.h"
-
-InputHandler::InputHandler(VMGlue* vm_glue)
-  : vm_glue_(vm_glue) {
-}
-
-int InputHandler::OnMotionEvent(MotionEvent event,
-                                int64_t when,
-                                float x,
-                                float y) {
-  const char *function = NULL;
-  // For now we just keep this simple. There are
-  // no click events or mouseover events.
-  switch (event) {
-    case kMotionDown:
-      function = "onMouseDown_";
-      break;
-    case kMotionUp:
-      function = "onMouseUp_";
-      break;
-    case kMotionMove:
-      function = "onMouseMove_";
-      break;
-    case kMotionCancel:
-      break;
-    case kMotionOutside:
-      break;
-    case kMotionPointerDown:
-      break;
-    case kMotionPointerUp:
-      break;
-    default:
-      return -1;
-  }
-  if (function == NULL) {
-    return 0;
-  } else {
-    return vm_glue_->OnMotionEvent(function, when, x, y);
-  }
-}
-
-int InputHandler::OnKeyEvent(KeyEvent event,
-                             int64_t when,
-                             int32_t key_code,
-                             bool isAltKeyDown,
-                             bool isCtrlKeyDown,
-                             bool isShiftKeyDown,
-                             int32_t repeat) {
-  const char *function = NULL;
-  switch (event) {
-    case kKeyDown:
-      function = "onKeyDown_";
-      break;
-    case kKeyUp:
-      function = "onKeyUp_";
-      break;
-    case kKeyMultiple:
-      return -1;  // TODO(gram): handle this.
-      break;
-    default:
-      return -1;
-  }
-  return vm_glue_->OnKeyEvent(function, when, key_code,
-                              isAltKeyDown, isCtrlKeyDown, isShiftKeyDown,
-                              repeat);
-}
-
-void InputHandler::OnAccelerometerEvent(float x, float y, float z) {
-  vm_glue_->OnAccelerometerEvent(x, y, z);
-}
-
diff --git a/runtime/embedders/openglui/common/input_handler.h b/runtime/embedders/openglui/common/input_handler.h
deleted file mode 100644
index 06d6d0f..0000000
--- a/runtime/embedders/openglui/common/input_handler.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_INPUT_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_COMMON_INPUT_HANDLER_H_
-
-#include "embedders/openglui/common/events.h"
-#include "embedders/openglui/common/vm_glue.h"
-
-class InputHandler {
-  public:
-    explicit InputHandler(VMGlue* vm_glue);
-    virtual int32_t Start() { return 0; }
-    virtual void Stop() { }
-    virtual int OnMotionEvent(MotionEvent event, int64_t when,
-                    float move_x, float move_y);
-    virtual int OnKeyEvent(KeyEvent event, int64_t when, int32_t key_code,
-                           bool isAltKeyDown, bool isCtrlKeyDown,
-                           bool isShiftKeyDown, int32_t repeat);
-    virtual void OnAccelerometerEvent(float x, float y, float z);
-
-    virtual ~InputHandler() {}
-
-  protected:
-    VMGlue* vm_glue_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_INPUT_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/common/isized.h b/runtime/embedders/openglui/common/isized.h
deleted file mode 100644
index b84dde2..0000000
--- a/runtime/embedders/openglui/common/isized.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_ISIZED_H_
-#define EMBEDDERS_OPENGLUI_COMMON_ISIZED_H_
-
-#include <stdint.h>
-
-// An interface for objects that have a size. VMGlue needs the window
-// size when calling setup() (and eventually resize()) but it does not
-// need to know anything else about the window, so we use this interface.
-class ISized {
-  public:
-    virtual const int32_t& height() = 0;
-    virtual const int32_t& width() = 0;
-    virtual ~ISized() {}
-};
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_ISIZED_H_
-
diff --git a/runtime/embedders/openglui/common/lifecycle_handler.h b/runtime/embedders/openglui/common/lifecycle_handler.h
deleted file mode 100644
index cc1a659..0000000
--- a/runtime/embedders/openglui/common/lifecycle_handler.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_LIFECYCLE_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_COMMON_LIFECYCLE_HANDLER_H_
-
-class LifeCycleHandler {
-  public:
-    virtual int32_t OnStart() = 0;
-    virtual int32_t Activate() = 0;
-    virtual void Deactivate() = 0;
-    virtual int32_t OnStep() = 0;
-    virtual void Pause() {}
-    virtual int32_t Resume() {
-      return 0;
-    }
-    virtual void FreeAllResources() {}
-    virtual void OnSaveState(void** data, size_t* size) {}
-    virtual void OnConfigurationChanged() {}
-    virtual void OnLowMemory() {}
-    virtual ~LifeCycleHandler() {}
-};
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_LIFECYCLE_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/common/log.h b/runtime/embedders/openglui/common/log.h
deleted file mode 100644
index d74e0f5..0000000
--- a/runtime/embedders/openglui/common/log.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_LOG_H_
-#define EMBEDDERS_OPENGLUI_COMMON_LOG_H_
-
-#ifndef ANDROID
-#include <stdio.h>
-#define LOGI(...)       do {\
-                          fprintf(stdout, __VA_ARGS__);\
-                          fprintf(stdout, "\n");\
-                          fflush(stdout);\
-                        } while (0)
-#define LOGE(...)       do { \
-                          fprintf(stderr, __VA_ARGS__);\
-                          fprintf(stderr, "\n");\
-                          fflush(stderr);\
-                        } while (0)
-#else
-#include "embedders/openglui/android/android_log.h"
-#endif
-
-#ifndef DEBUG
-#undef LOGI
-#define LOGI(...)
-#endif
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_LOG_H_
-
diff --git a/runtime/embedders/openglui/common/opengl.h b/runtime/embedders/openglui/common/opengl.h
deleted file mode 100644
index 3a41415..0000000
--- a/runtime/embedders/openglui/common/opengl.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// A semi-generic header file that can be used to isolate platform differences
-// for OpenGL headers.
-#ifndef EMBEDDERS_OPENGLUI_COMMON_OPENGL_H_
-#define EMBEDDERS_OPENGLUI_COMMON_OPENGL_H_
-
-#if defined(__APPLE__)
-#  ifdef GL_ES_VERSION_2_0
-#    include <OpenGLES/ES2/gl.h>
-#  else
-#    include <Glut/glut.h>
-#    include <OpenGL/gl.h>
-#  endif
-#  define GLSwapBuffers()    glutSwapBuffers()
-#elif defined(_WIN32) || defined(_WIN64)
-#  include <GL/glew.h>
-#  include <GL/wglew.h>
-#  include <GLUT/glut.h>
-#  include <Windows.h>
-#  define GLSwapBuffers()    glutSwapBuffers()
-#elif defined(__ANDROID__)
-#  include <EGL/egl.h>
-#  include <GLES2/gl2.h>
-#  include <GLES2/gl2ext.h>
-#  define GLSwapBuffers() \
-    do {\
-      EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); \
-      EGLSurface surface = eglGetCurrentSurface(EGL_DRAW); \
-      eglSwapBuffers(display, surface); \
-    } while (0);
-#else  // Linux.
-#  define GL_GLEXT_PROTOTYPES 1
-#  include <GL/gl.h>
-#  include <GL/glext.h>
-#  include <GL/glut.h>
-#  define GLSwapBuffers()    glutSwapBuffers()
-#endif
-
-#include "core/SkCanvas.h"
-#include "core/SkGraphics.h"
-#include "core/SkPaint.h"
-#include "core/SkTypeface.h"
-#include "effects/SkBlurDrawLooper.h"
-#include "effects/SkDashPathEffect.h"
-#include "effects/SkGradientShader.h"
-#include "gpu/SkGpuDevice.h"
-#include "gpu/GrContext.h"
-#include "gpu/GrRenderTarget.h"
-#include "gpu/gl/GrGLInterface.h"
-#include "gpu/gl/SkNativeGLContext.h"
-#include "images/SkImageDecoder.h"
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_OPENGL_H_
-
diff --git a/runtime/embedders/openglui/common/resource.h b/runtime/embedders/openglui/common/resource.h
deleted file mode 100644
index dd07a68..0000000
--- a/runtime/embedders/openglui/common/resource.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_RESOURCE_H_
-#define EMBEDDERS_OPENGLUI_COMMON_RESOURCE_H_
-
-#include <stdlib.h>
-#include <string.h>
-
-class Resource {
-  public:
-    explicit Resource(const char* path)
-        :  descriptor_(-1),
-           start_(0),
-           length_(-1) {
-      path_ = strdup(path);
-    }
-
-    const char* path() {
-      return path_;
-    }
-
-    virtual int32_t descriptor() {
-      return descriptor_;
-    }
-
-    virtual off_t start() {
-      return start_;
-    }
-
-    virtual off_t length() {
-      return length_;
-    }
-
-    virtual int32_t Open() {
-      return -1;
-    }
-
-    virtual void Close() {
-    }
-
-    virtual int32_t Read(void* buffer, size_t count) {
-      return -1;
-    }
-
-    virtual ~Resource() {
-      free(path_);
-    }
-
-  protected:
-    char* path_;
-    int32_t descriptor_;
-    off_t start_;
-    off_t length_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_RESOURCE_H_
-
diff --git a/runtime/embedders/openglui/common/sample.h b/runtime/embedders/openglui/common/sample.h
deleted file mode 100644
index 5fc4239..0000000
--- a/runtime/embedders/openglui/common/sample.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_SAMPLE_H_
-#define EMBEDDERS_OPENGLUI_COMMON_SAMPLE_H_
-
-#include "embedders/openglui/common/resource.h"
-
-extern Resource* MakePlatformResource(const char *path);
-
-class Sample {
-  public:
-    explicit Sample(const char* path)
-        : buffer_(NULL),
-          length_(0) {
-      resource_ = MakePlatformResource(path);
-    }
-
-    ~Sample() {
-      Unload();
-      delete resource_;
-    }
-
-    const char* path() {
-      return resource_->path();
-    }
-
-    uint8_t* buffer() {
-      return buffer_;
-    }
-
-    off_t length() {
-      return length_;
-    }
-
-    int32_t Load() {
-      int32_t rtn = -1;
-      if (resource_->Open() == 0) {
-        buffer_ = new uint8_t[length_ = resource_->length()];
-        rtn = resource_->Read(buffer_, length_);
-        resource_->Close();
-      }
-      return rtn;
-    }
-
-    void Unload() {
-      if (buffer_ != NULL) {
-        delete[] buffer_;
-        buffer_ = NULL;
-      }
-      length_ = 0;
-    }
-
-  private:
-    friend class SoundService;
-    Resource* resource_;
-    uint8_t* buffer_;
-    off_t length_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_SAMPLE_H_
-
diff --git a/runtime/embedders/openglui/common/sound_handler.cc b/runtime/embedders/openglui/common/sound_handler.cc
deleted file mode 100644
index 8af2379..0000000
--- a/runtime/embedders/openglui/common/sound_handler.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/common/sound_handler.h"
-
-#include <string.h>
-
-#include "embedders/openglui/common/log.h"
-
-// TODO(gram): Clean up this instance pointer; either make the class
-// a proper singleton or provide a cleaner way for the static functions
-// at the end to access it (those functions are the hooks into the Dart
-// native extension).
-SoundHandler* instance_ = NULL;
-
-SoundHandler::SoundHandler()
-    : samples_() {
-  instance_ = this;
-}
-
-Sample* SoundHandler::GetSample(const char* path) {
-  for (samples_t::iterator sp = samples_.begin();
-       sp != samples_.end();
-       ++sp) {
-    Sample* sample = (*sp);
-    if (strcmp(sample->path(), path) == 0) {
-      LOGI("Returning cached sample %s", path);
-      return sample;
-    }
-  }
-  Sample* sample = new Sample(path);
-  if (sample->Load() != 0) {
-    LOGI("Failed to load sample %s", path);
-    delete sample;
-    return NULL;
-  }
-  samples_.push_back(sample);
-  LOGI("Adding sample %s to cache", path);
-  return sample;
-}
-
-int32_t PlayBackgroundSound(const char* path) {
-  return instance_->PlayBackground(path);
-}
-
-void StopBackgroundSound() {
-  instance_->StopBackground();
-}
-
-int32_t LoadSoundSample(const char* path) {
-  return instance_->LoadSample(path);
-}
-
-int32_t PlaySoundSample(const char* path) {
-  return instance_->PlaySample(path);
-}
-
diff --git a/runtime/embedders/openglui/common/sound_handler.h b/runtime/embedders/openglui/common/sound_handler.h
deleted file mode 100644
index 61090a7..0000000
--- a/runtime/embedders/openglui/common/sound_handler.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_SOUND_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_COMMON_SOUND_HANDLER_H_
-
-#include <stdint.h>
-#include <vector>
-
-#include "embedders/openglui/common/sample.h"
-
-class SoundHandler {
-  public:
-    SoundHandler();
-
-    virtual ~SoundHandler() {
-    }
-
-    virtual int32_t Start() {
-      return 0;
-    }
-
-    virtual void Stop() {
-    }
-
-    virtual int32_t Suspend() {
-      return 0;
-    }
-
-    virtual int32_t Resume() {
-      return 0;
-    }
-
-    virtual int32_t PlayBackground(const char* path) {
-      return 0;
-    }
-
-    virtual void StopBackground() {
-    }
-
-    // Optional, for preloading.
-    int32_t LoadSample(const char* path) {
-       return (GetSample(path) == NULL) ? -1 : 0;
-    }
-
-    virtual int32_t PlaySample(const char* path) {
-      // Just do a load so we can get logging.
-      return (GetSample(path) == NULL) ? -1 : 0;
-    }
-
-  protected:
-    typedef std::vector<Sample*> samples_t;
-
-    Sample* GetSample(const char* path);
-
-    samples_t samples_;
-};
-
-int32_t PlayBackgroundSound(const char* path);
-void StopBackgroundSound();
-int32_t LoadSoundSample(const char* path);
-int32_t PlaySoundSample(const char* path);
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_SOUND_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/common/support.h b/runtime/embedders/openglui/common/support.h
deleted file mode 100644
index 143c9a9..0000000
--- a/runtime/embedders/openglui/common/support.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_SUPPORT_H_
-#define EMBEDDERS_OPENGLUI_COMMON_SUPPORT_H_
-
-#include "embedders/openglui/common/opengl.h"
-
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-// Colors as used by canvas.
-typedef struct ColorRGBA {
-  // We store Skia-compatible values. Skia uses
-  // the form AARRGGBB.
-  uint32_t v;
-
-  inline ColorRGBA(char rp, char gp, char bp, char ap = 255) {
-    v = ((static_cast<uint32_t>(rp) & 0xFF) << 16) |
-        ((static_cast<uint32_t>(gp) & 0xFF) << 8) |
-        ((static_cast<uint32_t>(bp) & 0xFF) << 0) |
-        ((static_cast<uint32_t>(ap) & 0xFF) << 24);
-  }
-  inline ColorRGBA(uint32_t vp)
-    : v(vp) {
-  }
-  inline uint8_t alpha() {
-    return (v >> 24) & 0xFF;
-  }
-} ColorRGBA;
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_SUPPORT_H_
diff --git a/runtime/embedders/openglui/common/timer.cc b/runtime/embedders/openglui/common/timer.cc
deleted file mode 100644
index 9a0e2af..0000000
--- a/runtime/embedders/openglui/common/timer.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/common/timer.h"
-
-#define NANO (+1.0E-9)
-
-#ifdef __MACH__
-#include <mach/mach.h>
-#include <mach/mach_time.h>
-#include <sys/time.h>
-
-#define GIGA UINT64_C(1000000000)
-
-#define CLOCK_REALTIME    0
-#define CLOCK_MONOTONIC   1
-
-double timebase = 0.0;
-uint64_t timestart = 0;
-
-void clock_gettime(int type, timespec* t) {
-  if (!timestart) {
-    mach_timebase_info_data_t tb = { 0, 1 };
-    mach_timebase_info(&tb);
-    timebase = tb.numer;
-    timebase /= tb.denom;
-    timestart = mach_absolute_time();
-  }
-  if (type == CLOCK_MONOTONIC) {
-    double diff = (mach_absolute_time() - timestart) * timebase;
-    t->tv_sec = diff * NANO;
-    t->tv_nsec = diff - (t->tv_sec * GIGA);
-  } else {  // type == CLOCK_REALTIME
-    struct timeval now;
-    gettimeofday(&now, NULL);
-    t->tv_sec  = now.tv_sec;
-    t->tv_nsec = now.tv_usec * 1000;
-  }
-}
-#endif
-
-Timer::Timer() : elapsed_(0.0f), last_time_(0.0) {
-}
-
-void Timer::Reset() {
-  elapsed_ = 0.0f;
-  last_time_ = Now();
-}
-
-void Timer::Update() {
-  double current = Now();
-  elapsed_ = (current - last_time_);
-  last_time_ = current;
-}
-
-double Timer::Now() {
-  timespec timeval;
-  clock_gettime(CLOCK_MONOTONIC, &timeval);
-  return timeval.tv_sec + (timeval.tv_nsec * NANO);
-}
-
-float Timer::Elapsed() {
-  return elapsed_;
-}
-
diff --git a/runtime/embedders/openglui/common/timer.h b/runtime/embedders/openglui/common/timer.h
deleted file mode 100644
index d2f3d67..0000000
--- a/runtime/embedders/openglui/common/timer.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_TIMER_H_
-#define EMBEDDERS_OPENGLUI_COMMON_TIMER_H_
-
-#include <time.h>
-
-class Timer {
- public:
-  Timer();
-  void Reset();
-  void Update();
-  double Now();
-  float Elapsed();
-
- private:
-  float elapsed_;
-  double last_time_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_TIMER_H_
-
diff --git a/runtime/embedders/openglui/common/types.h b/runtime/embedders/openglui/common/types.h
deleted file mode 100644
index 8acbe8c..0000000
--- a/runtime/embedders/openglui/common/types.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_TYPES_H_
-#define EMBEDDERS_OPENGLUI_COMMON_TYPES_H_
-
-struct Location {
-  Location() : pos_x_(0), pos_y_(0) {
-  };
-  void setPosition(float pos_x, float pos_y) {
-    pos_x_ = pos_x;
-    pos_y_ = pos_y;
-  }
-  void translate(float amount_x, float amount_y) {
-    pos_x_ += amount_x;
-    pos_y_ += amount_y;
-  }
-
-  float pos_x_, pos_y_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_TYPES_H_
-
diff --git a/runtime/embedders/openglui/common/vm_glue.cc b/runtime/embedders/openglui/common/vm_glue.cc
deleted file mode 100644
index 91a26db..0000000
--- a/runtime/embedders/openglui/common/vm_glue.cc
+++ /dev/null
@@ -1,398 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include <math.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "embedders/openglui/common/extension.h"
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/vm_glue.h"
-#include "include/dart_api.h"
-
-char* VMGlue::extension_script_ = NULL;
-bool VMGlue::initialized_vm_ = false;
-
-// snapshot_buffer points to a snapshot if we link in a snapshot otherwise
-// it is initialized to NULL.
-
-VMGlue::VMGlue(ISized* surface,
-               const char* script_path,
-               const char* extension_script,
-               const char* main_script,
-               int setup_flag)
-    : surface_(surface),
-      isolate_(NULL),
-      initialized_script_(false),
-      x_(0.0),
-      y_(0.0),
-      z_(0.0),
-      accelerometer_changed_(false),
-      setup_flag_(setup_flag) {
-  LOGI("Creating VMGlue");
-  if (main_script == NULL) {
-    main_script = "main.dart";
-  }
-  if (extension_script == NULL) {
-    extension_script = "gl.dart";
-  }
-  size_t len = strlen(script_path) + strlen(main_script) + 2;
-  main_script_ = new char[len];
-  snprintf(main_script_, len, "%s/%s", script_path, main_script);
-  len = strlen(script_path) + strlen(extension_script) + 2;
-  extension_script_ = new char[len];
-  snprintf(extension_script_, len, "%s/%s", script_path, extension_script);
-}
-
-Dart_Handle VMGlue::CheckError(Dart_Handle handle) {
-  if (Dart_IsError(handle)) {
-    LOGE("Unexpected Error Handle: %s", Dart_GetError(handle));
-    Dart_PropagateError(handle);
-  }
-  return handle;
-}
-
-#define CHECK_RESULT(result)                   \
-  if (Dart_IsError(result)) {                  \
-    *error = strdup(Dart_GetError(result));    \
-    LOGE("%s", *error);                        \
-    Dart_ExitScope();                          \
-    Dart_ShutdownIsolate();                    \
-    return false;                              \
-  }
-
-Dart_Handle VMGlue::LibraryTagHandler(Dart_LibraryTag tag,
-                                      Dart_Handle library,
-                                      Dart_Handle urlHandle) {
-  const char* url;
-  Dart_StringToCString(urlHandle, &url);
-  if (tag == kCanonicalizeUrl) {
-    return urlHandle;
-  }
-  // TODO(vsm): Split this up into separate libraries for 3D, 2D,
-  // Touch, Audio, etc.  All builtin libraries should be handled here
-  // (or moved into a snapshot).
-  if (strcmp(url, "gl.dart") == 0) {
-    Dart_Handle source =
-        VMGlue::LoadSourceFromFile(extension_script_);
-    Dart_Handle library = CheckError(Dart_LoadLibrary(urlHandle, source));
-    CheckError(Dart_SetNativeResolver(library, ResolveName));
-    return library;
-  }
-  LOGE("UNIMPLEMENTED: load library %s\n", url);
-  return NULL;
-}
-
-// Returns true on success, false on failure.
-Dart_Isolate VMGlue::CreateIsolateAndSetupHelper(const char* script_uri,
-                                         const char* main,
-                                         void* data,
-                                         char** error) {
-  LOGI("Creating isolate %s, %s", script_uri, main);
-  Dart_Isolate isolate =
-      Dart_CreateIsolate(script_uri, main, NULL, data, error);
-  if (isolate == NULL) {
-    LOGE("Couldn't create isolate: %s", *error);
-    return NULL;
-  }
-
-  LOGI("Entering scope");
-  Dart_EnterScope();
-
-  // Set up the library tag handler for this isolate.
-  LOGI("Setting up library tag handler");
-  Dart_Handle result = CheckError(Dart_SetLibraryTagHandler(LibraryTagHandler));
-  CHECK_RESULT(result);
-
-  Dart_ExitScope();
-  return isolate;
-}
-
-Dart_Isolate VMGlue::CreateIsolateAndSetup(const char* script_uri,
-  const char* main,
-  void* data, char** error) {
-  return CreateIsolateAndSetupHelper(script_uri,
-                                     main,
-                                     data,
-                                     error);
-}
-
-const char* VM_FLAGS[] = {
-  "--enable_type_checks",  // TODO(gram): This should be an option!
-  // "--trace_isolates",
-  // "--trace_natives",
-  // "--trace_compiler",
-};
-
-static void* openFileCallback(const char* name, bool write) {
-  return fopen(name, write ? "w" : "r");
-}
-
-static void readFileCallback(const uint8_t** data, intptr_t* fileLength,
-    void* stream) {
-  if (!stream) {
-    *data = 0;
-    *fileLength = 0;
-  } else {
-    FILE* file = reinterpret_cast<FILE*>(stream);
-
-    // Get the file size.
-    fseek(file, 0, SEEK_END);
-    *fileLength = ftell(file);
-    rewind(file);
-
-    // Allocate data buffer.
-    *data = new uint8_t[*fileLength];
-    *fileLength = fread(const_cast<uint8_t*>(*data), 1, *fileLength, file);
-  }
-}
-
-static void writeFileCallback(const void* data, intptr_t length, void* file) {
-  fwrite(data, 1, length, reinterpret_cast<FILE*>(file));
-}
-
-static void closeFileCallback(void* file) {
-  fclose(reinterpret_cast<FILE*>(file));
-}
-
-int VMGlue::InitializeVM() {
-  // We need the next call to get Dart_Initialize not to bail early.
-  LOGI("Setting VM Options");
-  Dart_SetVMFlags(sizeof(VM_FLAGS) / sizeof(VM_FLAGS[0]), VM_FLAGS);
-
-  // Initialize the Dart VM, providing the callbacks to use for
-  // creating and shutting down isolates.
-  LOGI("Initializing Dart");
-  if (!Dart_Initialize(CreateIsolateAndSetup,
-                       0,
-                       0,
-                       0,
-                       openFileCallback,
-                       readFileCallback,
-                       writeFileCallback,
-                       closeFileCallback)) {
-    LOGE("VM initialization failed\n");
-    return -1;
-  }
-  initialized_vm_ = true;
-
-  return 0;
-}
-
-Dart_Handle VMGlue::LoadSourceFromFile(const char* url) {
-  FILE* file = fopen(url, "r");
-  if (file == NULL) {
-    LOGE("Main script not found at: %s\n", url);
-    return NULL;
-  }
-
-  struct stat sb;
-  int fd = fileno(file);
-  fstat(fd, &sb);
-  int length = sb.st_size;
-  LOGI("Entry file %s is %d bytes.\n", url, length);
-
-  char* buffer = new char[length+1];
-  if (read(fd, buffer, length) < 0) {
-    LOGE("Could not read script %s.\n", url);
-    return NULL;
-  }
-  buffer[length] = 0;
-  fclose(file);
-
-  Dart_Handle contents = CheckError(Dart_NewStringFromCString(buffer));
-  delete[] buffer;
-  return contents;
-}
-
-int VMGlue::StartMainIsolate() {
-  if (!initialized_vm_) {
-    int rtn = InitializeVM();
-    if (rtn != 0) return rtn;
-  }
-
-  // Create an isolate and loads up the application script.
-  char* error = NULL;
-  if (!CreateIsolateAndSetup(main_script_, "main", NULL, &error)) {
-    LOGE("CreateIsolateAndSetup: %s\n", error);
-    free(error);
-    return -1;
-  }
-  LOGI("Created isolate");
-  isolate_ = Dart_CurrentIsolate();
-  Dart_EnterScope();
-
-  Dart_Handle url = CheckError(Dart_NewStringFromCString(main_script_));
-  Dart_Handle source = LoadSourceFromFile(main_script_);
-  CheckError(Dart_LoadScript(url, source, 0, 0));
-
-  Dart_ExitScope();
-  Dart_ExitIsolate();
-  return 0;
-}
-
-int VMGlue::CallSetup(bool force) {
-  // TODO(gram): See if we actually need this flag guard here, or if
-  // we can eliminate it along with the need for the force parameter.
-  if (!initialized_script_ || force) {
-    initialized_script_ = true;
-    LOGI("Invoking setup(null, %d,%d,%d)",
-        surface_->width(), surface_->height(), setup_flag_);
-    Dart_EnterIsolate(isolate_);
-    Dart_EnterScope();
-    Dart_Handle args[4];
-    args[0] = CheckError(Dart_Null());
-    args[1] = CheckError(Dart_NewInteger(surface_->width()));
-    args[2] = CheckError(Dart_NewInteger(surface_->height()));
-    args[3] = CheckError(Dart_NewInteger(setup_flag_));
-    int rtn = Invoke("setup", 4, args);
-
-    if (rtn == 0) {
-      // Plug in the print handler. It would be nice if we could do this
-      // before calling setup, but the call to GetField blows up if we
-      // haven't run anything yet.
-      Dart_Handle library = CheckError(Dart_LookupLibrary(
-          Dart_NewStringFromCString("gl.dart")));
-      Dart_Handle print = CheckError(
-          Dart_GetField(library, Dart_NewStringFromCString("_printClosure")));
-      Dart_Handle corelib = CheckError(Dart_LookupLibrary(
-          Dart_NewStringFromCString("dart:core")));
-      CheckError(Dart_SetField(corelib,
-        Dart_NewStringFromCString("_printClosure"), print));
-    }
-    Dart_ExitScope();
-    Dart_ExitIsolate();
-    LOGI("Done setup");
-    return rtn;
-  }
-  return 0;
-}
-
-int VMGlue::CallUpdate() {
-  if (initialized_script_) {
-    // If the accelerometer has changed, first do that
-    // event.
-    Dart_EnterIsolate(isolate_);
-    if (accelerometer_changed_) {
-      Dart_Handle args[3];
-      LOGI("Invoking onAccelerometer(%f,%f,%f)", x_, y_, z_);
-      Dart_EnterScope();
-      args[0] = CheckError(Dart_NewDouble(x_));
-      args[1] = CheckError(Dart_NewDouble(y_));
-      args[2] = CheckError(Dart_NewDouble(z_));
-      Invoke("onAccelerometer", 3, args, false);
-      Dart_ExitScope();
-      accelerometer_changed_ = false;
-    }
-    Dart_EnterScope();
-    int rtn = Invoke("update_", 0, 0);
-    Dart_ExitScope();
-    Dart_ExitIsolate();
-    LOGI("Invoke update_ returns %d", rtn);
-    return rtn;
-  }
-  return -1;
-}
-
-int VMGlue::CallShutdown() {
-  if (initialized_script_) {
-    Dart_EnterIsolate(isolate_);
-    Dart_EnterScope();
-    int rtn = Invoke("shutdown", 0, 0);
-    Dart_ExitScope();
-    Dart_ExitIsolate();
-    return rtn;
-  }
-  return -1;
-}
-
-int VMGlue::OnMotionEvent(const char* pFunction, int64_t pWhen,
-  float pMoveX, float pMoveY) {
-  if (initialized_script_) {
-    LOGI("Invoking %s", pFunction);
-    Dart_EnterIsolate(isolate_);
-    Dart_EnterScope();
-    Dart_Handle args[3];
-    args[0] = CheckError(Dart_NewInteger(pWhen));
-    args[1] = CheckError(Dart_NewDouble(pMoveX));
-    args[2] = CheckError(Dart_NewDouble(pMoveY));
-    int rtn = Invoke(pFunction, 3, args, false);
-    Dart_ExitScope();
-    Dart_ExitIsolate();
-    LOGI("Done %s", pFunction);
-    return rtn;
-  }
-  return -1;
-}
-
-int VMGlue::OnKeyEvent(const char* function, int64_t when, int32_t key_code,
-                       bool isAltKeyDown, bool isCtrlKeyDown,
-                       bool isShiftKeyDown, int32_t repeat) {
-  if (initialized_script_) {
-    LOGI("Invoking %s(_,%d,...)", function, key_code);
-    Dart_EnterIsolate(isolate_);
-    Dart_EnterScope();
-    Dart_Handle args[6];
-    args[0] = CheckError(Dart_NewInteger(when));
-    args[1] = CheckError(Dart_NewInteger(key_code));
-    args[2] = CheckError(Dart_NewBoolean(isAltKeyDown));
-    args[3] = CheckError(Dart_NewBoolean(isCtrlKeyDown));
-    args[4] = CheckError(Dart_NewBoolean(isShiftKeyDown));
-    args[5] = CheckError(Dart_NewInteger(repeat));
-    int rtn = Invoke(function, 6, args, false);
-    Dart_ExitScope();
-    Dart_ExitIsolate();
-    LOGI("Done %s", function);
-    return rtn;
-  }
-  return -1;
-}
-
-int VMGlue::Invoke(const char* function,
-                   int argc,
-                   Dart_Handle* args,
-                   bool failIfNotDefined) {
-  // Lookup the library of the root script.
-  Dart_Handle library = Dart_RootLibrary();
-  if (Dart_IsNull(library)) {
-     LOGE("Unable to find root library\n");
-     return -1;
-  }
-
-  Dart_Handle nameHandle = Dart_NewStringFromCString(function);
-
-  Dart_Handle result = Dart_Invoke(library, nameHandle, argc, args);
-
-  if (Dart_IsError(result)) {
-    const char* error = Dart_GetError(result);
-    LOGE("Invoke %s failed: %s", function, error);
-    if (failIfNotDefined) {
-      return -1;
-    }
-  }
-
-  // TODO(vsm): I don't think we need this.
-  // Keep handling messages until the last active receive port is closed.
-  result = Dart_RunLoop();
-  if (Dart_IsError(result)) {
-    LOGE("Dart_RunLoop: %s\n", Dart_GetError(result));
-    return -1;
-  }
-
-  return 0;
-}
-
-void VMGlue::FinishMainIsolate() {
-  LOGI("Finish main isolate");
-  Dart_EnterIsolate(isolate_);
-  // Shutdown the isolate.
-  Dart_ShutdownIsolate();
-  isolate_ = NULL;
-  initialized_script_ = false;
-}
-
diff --git a/runtime/embedders/openglui/common/vm_glue.h b/runtime/embedders/openglui/common/vm_glue.h
deleted file mode 100644
index 8f84377..0000000
--- a/runtime/embedders/openglui/common/vm_glue.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_COMMON_VM_GLUE_H_
-#define EMBEDDERS_OPENGLUI_COMMON_VM_GLUE_H_
-
-#include <stdlib.h>
-
-#include "embedders/openglui/common/events.h"
-#include "embedders/openglui/common/isized.h"
-#include "include/dart_api.h"
-
-class VMGlue {
- public:
-  explicit VMGlue(ISized* surface,
-                  const char* script_path,
-                  const char* extension_script = NULL,
-                  const char* main_script = NULL,
-                  int setup_flag = 0);
-  ~VMGlue() {
-    delete[] main_script_;
-    delete[] extension_script_;
-  }
-
-  int InitializeVM();
-  int StartMainIsolate();
-  int CallSetup(bool force = false);
-  int CallUpdate();
-  int CallShutdown();
-  int OnMotionEvent(const char* funtion, int64_t when,
-                    float move_x, float move_y);
-  int OnKeyEvent(const char* funtion, int64_t when, int32_t key_code,
-                 bool isAltKeyDown, bool isCtrlKeyDown, bool isShiftKeyDown,
-                 int32_t repeat);
-  inline void OnAccelerometerEvent(float x, float y, float z) {
-    if (x != x_ || y != y_ || z != z_) {
-      x_ = x;
-      y_ = y;
-      z_ = z;
-      accelerometer_changed_ = true;
-    }
-  }
-
-  void FinishMainIsolate();
-
- private:
-  int Invoke(const char *function, int argc, Dart_Handle* args,
-             bool failIfNotDefined = true);
-
-  static Dart_Handle CheckError(Dart_Handle);
-
-  static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
-                                          const char* main,
-                                          void* data,
-                                          char** error);
-  static Dart_Isolate CreateIsolateAndSetup(const char* script_uri,
-                                    const char* main,
-                                    void* data, char** error);
-  static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
-                                       Dart_Handle library,
-                                       Dart_Handle urlHandle);
-  static Dart_Handle LoadSourceFromFile(const char* url);
-  static void ShutdownIsolate(void* callback_data);
-
-  static bool initialized_vm_;
-  static char* extension_script_;
-  ISized* surface_;
-  Dart_Isolate isolate_;
-  bool initialized_script_;
-  char* main_script_;
-  float x_, y_, z_;  // Last values from accelerometer.
-  bool accelerometer_changed_;
-  int setup_flag_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_COMMON_VM_GLUE_H_
-
diff --git a/runtime/embedders/openglui/emulator/emulator_embedder.cc b/runtime/embedders/openglui/emulator/emulator_embedder.cc
deleted file mode 100644
index de01870..0000000
--- a/runtime/embedders/openglui/emulator/emulator_embedder.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/emulator/emulator_embedder.h"
-
-#include <string.h>
-#include <sys/time.h>
-#include <time.h>
-#include "embedders/openglui/common/canvas_context.h"
-#include "embedders/openglui/common/context.h"
-#include "embedders/openglui/common/dart_host.h"
-#include "embedders/openglui/common/events.h"
-#include "embedders/openglui/common/input_handler.h"
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/sound_handler.h"
-#include "embedders/openglui/common/vm_glue.h"
-#include "embedders/openglui/emulator/emulator_graphics_handler.h"
-#include "embedders/openglui/emulator/emulator_resource.h"
-
-InputHandler* input_handler_ptr;
-LifeCycleHandler* lifecycle_handler_ptr;
-
-struct timeval tvStart;
-void tick(int data);
-
-Resource* MakePlatformResource(const char *path) {
-  return new EmulatorResource(path);
-}
-
-void display() {
-  // Get number of msecs since last call.
-  struct timeval tvEnd;
-  gettimeofday(&tvEnd, NULL);
-  uint64_t now = (tvEnd.tv_usec + 1000000 * tvEnd.tv_sec);
-
-  if (lifecycle_handler_ptr->OnStep() != 0) {
-    exit(-1);
-  }
-  // Schedule next call, trying to aim for 60fps.
-  uint64_t elapsed = now - (tvStart.tv_usec + 1000000 * tvStart.tv_sec);
-  int delay = 1000 / 60 - (elapsed / 1000);
-  if (delay < 0) delay = 0;
-  tvStart = tvEnd;
-  glutTimerFunc(delay, tick, 0);
-}
-
-void tick(int data) {
-  display();
-}
-
-void reshape(int width, int height) {
-  glViewport(0, 0, width, height);
-  glMatrixMode(GL_PROJECTION);
-  glLoadIdentity();
-  glOrtho(0, width, 0, height, -1, 1);
-  glMatrixMode(GL_MODELVIEW);
-  glutPostRedisplay();
-}
-
-void keyboard(unsigned char key, int x, int y) {
-  input_handler_ptr->OnKeyEvent(kKeyDown, time(0), key, false, false, false, 0);
-  input_handler_ptr->OnKeyEvent(kKeyUp, time(0), key, false, false, false, 0);
-  if (key == 'Q') {
-    lifecycle_handler_ptr->Pause();
-    lifecycle_handler_ptr->Deactivate();
-    lifecycle_handler_ptr->FreeAllResources();
-    exit(0);
-  } else if (key == 'S') {
-    LOGI("Simulating suspend");
-    lifecycle_handler_ptr->Pause();
-    lifecycle_handler_ptr->Deactivate();
-  } else if (key == 'R') {
-    LOGI("Simulating resume");
-    lifecycle_handler_ptr->Activate();
-    lifecycle_handler_ptr->Resume();
-  } else if (key == '+') {
-    LOGI("Simulating focus gain");
-    lifecycle_handler_ptr->Resume();
-  } else if (key == '-') {
-    LOGI("Simulating focus loss");
-    lifecycle_handler_ptr->Pause();
-  }
-}
-
-void mouse(int button, int state, int x, int y) {
-  if (state == GLUT_UP) {
-    input_handler_ptr->OnMotionEvent(kMotionUp, time(0), x, y);
-  } else if (state == GLUT_DOWN) {
-    input_handler_ptr->OnMotionEvent(kMotionDown, time(0), x, y);
-  }
-}
-
-void motion(int x, int y) {
-  input_handler_ptr->OnMotionEvent(kMotionMove, time(0), x, y);
-}
-
-DART_EXPORT void emulator_main(int argc, char** argv, const char* script) {
-  EmulatorGraphicsHandler graphics_handler(argc, argv);
-  if (argc > 0) {
-    int i = argc - 1;
-    size_t len = strlen(argv[i]);
-    if (len > 5 && strcmp(".dart", argv[i] + len - 5) == 0) {
-      script = argv[i];
-    }
-  }
-  VMGlue vm_glue(&graphics_handler, ".", "gl.dart", script, 1);
-  InputHandler input_handler(&vm_glue);
-  input_handler_ptr = &input_handler;
-  SoundHandler sound_handler;
-  Timer timer;
-  Context app_context;
-  app_context.graphics_handler = &graphics_handler;
-  app_context.input_handler = &input_handler;
-  app_context.sound_handler = &sound_handler;
-  app_context.timer = &timer;
-  app_context.vm_glue = &vm_glue;
-  DartHost host(&app_context);
-  lifecycle_handler_ptr = &host;
-  glutReshapeFunc(reshape);
-  glutDisplayFunc(display);
-  glutKeyboardFunc(keyboard);
-  glutMouseFunc(mouse);
-  glutMotionFunc(motion);
-  lifecycle_handler_ptr->OnStart();
-  lifecycle_handler_ptr->Activate();
-  lifecycle_handler_ptr->Resume();
-  gettimeofday(&tvStart, NULL);
-  glutTimerFunc(1, tick, 0);
-  glutMainLoop();
-}
-
diff --git a/runtime/embedders/openglui/emulator/emulator_embedder.h b/runtime/embedders/openglui/emulator/emulator_embedder.h
deleted file mode 100644
index f0f0638..0000000
--- a/runtime/embedders/openglui/emulator/emulator_embedder.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_EMBEDDER_H_
-#define EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_EMBEDDER_H_
-
-#include "include/dart_api.h"
-
-DART_EXPORT void emulator_main(int argc, char** argv,
-                               const char* script);
-
-#endif  // EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_EMBEDDER_H_
-
diff --git a/runtime/embedders/openglui/emulator/emulator_graphics_handler.cc b/runtime/embedders/openglui/emulator/emulator_graphics_handler.cc
deleted file mode 100644
index 606dc76..0000000
--- a/runtime/embedders/openglui/emulator/emulator_graphics_handler.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "embedders/openglui/emulator/emulator_graphics_handler.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-EmulatorGraphicsHandler::EmulatorGraphicsHandler(int argc,
-                                                 char** argv)
-  : GraphicsHandler(".") {
-  glutInit(&argc, argv);
-  width_ = 800;
-  height_ = 480;
-  for (int i = 1; i < argc; i++) {
-    if (argv[i][0] == '-') {
-      int next_arg = i + 1;
-      if (next_arg < argc && strcmp(argv[i], "-w") == 0) {
-        width_ = static_cast<size_t>(atoi(argv[i = next_arg]));
-      } else if (next_arg < argc && strcmp(argv[i], "-h") == 0) {
-        height_ = static_cast<size_t>(atoi(argv[i = next_arg]));
-      }
-    }
-  }
-  SetViewport(0, 0, width_, height_);
-  glutInitWindowSize(width_, height_);
-  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL);
-  glutCreateWindow("Dart");
-}
-
-int32_t EmulatorGraphicsHandler::Start() {
-  return GraphicsHandler::Start();
-}
-
-void EmulatorGraphicsHandler::Stop() {
-  GraphicsHandler::Stop();
-}
-
diff --git a/runtime/embedders/openglui/emulator/emulator_graphics_handler.h b/runtime/embedders/openglui/emulator/emulator_graphics_handler.h
deleted file mode 100644
index 4a29270..0000000
--- a/runtime/embedders/openglui/emulator/emulator_graphics_handler.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_GRAPHICS_HANDLER_H_
-#define EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_GRAPHICS_HANDLER_H_
-
-#include "embedders/openglui/common/graphics_handler.h"
-
-class EmulatorGraphicsHandler : public GraphicsHandler {
-  public:
-    EmulatorGraphicsHandler(int argc, char** argv);
-
-    int32_t Start();
-    void Stop();
-};
-
-#endif  // EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_GRAPHICS_HANDLER_H_
-
diff --git a/runtime/embedders/openglui/emulator/emulator_resource.h b/runtime/embedders/openglui/emulator/emulator_resource.h
deleted file mode 100644
index fc54f8a..0000000
--- a/runtime/embedders/openglui/emulator/emulator_resource.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_RESOURCE_H_
-#define EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_RESOURCE_H_
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "embedders/openglui/common/log.h"
-#include "embedders/openglui/common/resource.h"
-
-class EmulatorResource : public Resource {
-  public:
-    explicit EmulatorResource(const char* path)
-      : Resource(path),
-        fd_(-1) {
-    }
-
-    int32_t descriptor() {
-      if (fd_ < 0) {
-        Open();
-      }
-      return fd_;
-    }
-
-    off_t length() {
-      if (length_ < 0) {
-        length_ = lseek(fd_, 0, SEEK_END);
-        lseek(fd_, 0, SEEK_SET);
-      }
-      return length_;
-    }
-
-    int32_t Open() {
-      fd_ = open(path_, 0);
-      if (fd_ >= 0) {
-        return 0;
-      }
-      LOGE("Could not open asset %s", path_);
-      return -1;
-    }
-
-    void Close() {
-      if (fd_ >= 0) {
-        close(fd_);
-        fd_ = -1;
-      }
-    }
-
-    int32_t Read(void* buffer, size_t count) {
-      size_t actual = read(fd_, buffer, count);
-      return (actual == count) ? 0 : -1;
-    }
-
-  private:
-    int fd_;
-};
-
-#endif  // EMBEDDERS_OPENGLUI_EMULATOR_EMULATOR_RESOURCE_H_
-
diff --git a/runtime/embedders/openglui/openglui_embedder.gypi b/runtime/embedders/openglui/openglui_embedder.gypi
deleted file mode 100644
index 4b058cc..0000000
--- a/runtime/embedders/openglui/openglui_embedder.gypi
+++ /dev/null
@@ -1,310 +0,0 @@
-# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-{
-  # TODO(gram) : figure out how to make this be autoconfigured. 
-  # I've tried a bunch of things with no success yet.
-  'variables': {
-    'skia_build_flag' : '--release',
-    'skia_libs_location_android': '-Lthird_party/skia/trunk/out/config/android-x86/Release/obj.target/gyp', 
-    'skia_libs_location_desktop': '-Lthird_party/skia/trunk/out/Release', 
-  },
-  'conditions': [
-    ['OS=="android"',
-      {
-        'targets': [
-          {
-            # Dart shared library for Android.
-            'target_name': 'android_embedder',
-            'type': 'shared_library',
-            'dependencies': [
-              'skia-android',
-              'libdart_lib_withcore',
-              'libdart_vm',
-              'libjscre',
-              'libdouble_conversion',
-              'generate_version_cc_file#host',
-            ],
-            'include_dirs': [
-              '../..',
-              '../../../third_party/android_tools/ndk/sources/android/native_app_glue',
-              '../../../third_party/skia/trunk/include',
-              '../../../third_party/skia/trunk/include/config',
-              '../../../third_party/skia/trunk/include/core',
-              '../../../third_party/skia/trunk/include/gpu',
-              '../../../third_party/skia/trunk/include/lazy',
-              '../../../third_party/skia/trunk/include/utils',
-            ],
-            'defines': [
-              'DART_SHARED_LIB',
-              '__ANDROID__',
-              'SK_BUILD_FOR_ANDROID',
-              'SK_BUILD_FOR_ANDROID_NDK',
-            ],
-            'sources': [
-              '../../include/dart_api.h',
-              '../../include/dart_debugger_api.h',
-              '../../vm/dart_api_impl.cc',
-              '../../vm/debugger_api_impl.cc',
-              '../../vm/version.h',
-              '../../../third_party/android_tools/ndk/sources/android/native_app_glue/android_native_app_glue.h',
-              '../../../third_party/android_tools/ndk/sources/android/native_app_glue/android_native_app_glue.c',
-              '../../../third_party/skia/trunk/src/core/SkPaintOptionsAndroid.cpp',
-              'android/android_graphics_handler.cc',
-              'android/android_graphics_handler.h',
-              'android/android_input_handler.h',
-              'android/android_resource.h',
-              'android/android_sound_handler.cc',
-              'android/android_sound_handler.h',
-              'android/eventloop.cc',
-              'android/eventloop.h',
-              'android/log.h',
-              'android/main.cc',
-              'android/support_android.cc',
-              'common/canvas_context.cc',
-              'common/canvas_context.h',
-              'common/canvas_state.cc',
-              'common/canvas_state.h',
-              'common/context.h',
-              'common/dart_host.cc',
-              'common/dart_host.h',
-              'common/events.h',
-              'common/extension.cc',
-              'common/extension.h',
-              'common/graphics_handler.cc',
-              'common/graphics_handler.h',
-              'common/image_cache.cc',
-              'common/image_cache.h',
-              'common/input_handler.cc',
-              'common/input_handler.h',
-              'common/isized.h',
-              'common/life_cycle_handler.h',
-              'common/log.h',
-              'common/opengl.h',
-              'common/resource.h',
-              'common/sample.h',
-              'common/sound_handler.cc',
-              'common/sound_handler.h',
-              'common/support.h',
-              'common/timer.cc',
-              'common/timer.h',
-              'common/types.h',
-              'common/vm_glue.cc',
-              'common/vm_glue.h',
-              '<(version_cc_file)',
-            ],
-            'link_settings': {
-              'ldflags': [
-                # The libraries we need should all be in
-                # Lthird_party/skia/trunk/out/config/android-x86/Debug but
-                # As I (gram) want to avoid patching the Skia gyp files to build
-                # real libraries we'll just point to the location of the 'thin'
-                # libraries used by the Skia build for now.
-                # TODO(gram): We need to support debug vs release modes.
-                '<(skia_libs_location_android)',
-                '-z',
-                'muldefs',
-              ],
-              'ldflags!': [
-                '-Wl,--exclude-libs=ALL,-shared',
-              ],
-              'libraries': [
-                '-Wl,--start-group',
-                '-lexpat',
-                '-lfreetype',
-                '-lgif',
-                '-ljpeg',
-                '-lpng',
-                '-lwebp_dec',
-                '-lwebp_utils',
-                '-lwebp_dsp',
-                '-lwebp_enc',
-                '-lskia_core',
-                '-lskia_effects',
-                '-lskia_gr',
-                '-lskia_images',
-                '-lskia_opts',
-                '-lskia_pdf',
-                '-lskia_ports',
-                '-lskia_sfnt',
-                '-lskia_skgr',
-                '-lskia_utils',
-                '-lskia_views',
-                '-lskia_xml',
-                '-lzlib',
-                '-Wl,--end-group',
-                '-llog',
-                '-lc',
-                '-lz',
-                '-landroid',
-                '-lEGL',
-                '-lGLESv2',
-                '-lOpenSLES',
-                '-landroid',
-              ],
-            },
-          },
-          {
-            'target_name': 'skia-android',
-            'type': 'none',
-            'actions': [
-              {
-                'action_name': 'build_skia',
-                'inputs': [
-                  'build_skia.sh'
-                ],
-                'outputs': [
-                  'dummy' # To force re-execution every time.
-                ],
-                # For now we drive the build from a shell
-                # script, to get us going. Eventually we will
-                # want to either fork Skia or incorporate its 
-                # gclient settings into ours, and include its 
-                # gyp files within ours, so that it gets built
-                # as part of our tree.
-                'action': [
-                  'embedders/openglui/build_skia.sh',
-                  '--android',
-                  '<(skia_build_flag)',
-                  '..'
-                ],
-                'message': 'Building Skia.'
-              }
-            ]
-          }
-        ],
-      },
-    ],
-    ['OS=="mac" or OS=="linux"',
-      {
-        'targets': [
-          {
-            'target_name': 'emulator_embedder',
-            'type': 'static_library',
-            'dependencies': [
-              'skia-desktop',
-              'libdart_lib_withcore',
-              'libdart_vm',
-              'libjscre',
-              'libdouble_conversion',
-              'generate_version_cc_file',
-            ],
-            'include_dirs': [
-              '../..',
-              '/usr/X11/include',
-              '../../../third_party/skia/trunk/include',
-              '../../../third_party/skia/trunk/include/config',
-              '../../../third_party/skia/trunk/include/core',
-              '../../../third_party/skia/trunk/include/gpu',
-              '../../../third_party/skia/trunk/include/lazy',
-              '../../../third_party/skia/trunk/include/utils',
-            ],
-            'defines': [
-              'DART_SHARED_LIB'
-            ],
-            'sources': [
-              '../../include/dart_api.h',
-              '../../include/dart_debugger_api.h',
-              '../../vm/dart_api_impl.cc',
-              '../../vm/debugger_api_impl.cc',
-              '../../vm/version.h',
-              'common/canvas_context.cc',
-              'common/canvas_context.h',
-              'common/canvas_state.cc',
-              'common/canvas_state.h',
-              'common/context.h',
-              'common/dart_host.cc',
-              'common/dart_host.h',
-              'common/events.h',
-              'common/extension.cc',
-              'common/extension.h',
-              'common/graphics_handler.cc',
-              'common/graphics_handler.h',
-              'common/image_cache.cc',
-              'common/image_cache.h',
-              'common/input_handler.cc',
-              'common/input_handler.h',
-              'common/isized.h',
-              'common/life_cycle_handler.h',
-              'common/log.h',
-              'common/opengl.h',
-              'common/resource.h',
-              'common/sample.h',
-              'common/sound_handler.cc',
-              'common/sound_handler.h',
-              'common/support.h',
-              'common/support.h',
-              'common/timer.cc',
-              'common/timer.h',
-              'common/types.h',
-              'common/vm_glue.cc',
-              'common/vm_glue.h',
-              'emulator/emulator_embedder.cc',
-              'emulator/emulator_embedder.h',
-              'emulator/emulator_graphics_handler.cc',
-              'emulator/emulator_graphics_handler.h',
-              'emulator/emulator_resource.h',
-              '<(version_cc_file)',
-            ],
-            'link_settings': {
-              'ldflags': [
-                '-Wall',
-                '<(skia_libs_location_desktop)',
-                '-Wl,--start-group',
-                '-lskia_core',
-                '-lskia_effects',
-                '-lskia_gr',
-                '-lskia_images',
-                '-lskia_opts',
-                '-lskia_opts_ssse3',
-                '-lskia_ports',
-                '-lskia_sfnt',
-                '-lskia_skgr',
-                '-lskia_utils',
-                '-Wl,--end-group',
-                '-lfreetype',
-              ],
-              'libraries': [
-                '-lGL',
-                '-lglut',
-                '-lGLU',
-                '-lm',
-                '-lwebp'
-              ],
-            },
-            'conditions': [
-              ['OS=="mac"', {
-                'xcode_settings' : {
-                  'OTHER_LDFLAGS': [ '-framework OpenGL', '-framework GLUT', '-L /usr/X11/lib' ]
-                },
-              }],
-            ]
-          },
-          {
-            'target_name': 'skia-desktop',
-            'type': 'none',
-            'actions': [
-              {
-                'action_name': 'build_skia',
-                'inputs': [
-                  'build_skia.sh'
-                ],
-                'outputs': [
-                  'dummy' # To force re-execution every time.
-                ],
-                'action': [
-                  'embedders/openglui/build_skia.sh',
-                  '<(skia_build_flag)',
-                  '..'
-                ],
-                'message': 'Building Skia.'
-              }
-            ]
-          }
-        ],
-      },
-    ],
-  ],
-}
-
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index a09f212..9f4969e 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -185,9 +185,13 @@
  * can be used to store objects across scopes. Persistent handles have
  * the lifetime of the current isolate unless they are explicitly
  * deallocated (see Dart_DeletePersistentHandle).
+ * The type Dart_Handle represents a handle (both local and persistent).
+ * The type Dart_PersistentHandle is a Dart_Handle and it is used to
+ * document that a persistent handle is expected as a parameter to a call
+ * or the return value from a call is a persistent handle.
  */
 typedef struct _Dart_Handle* Dart_Handle;
-typedef struct _Dart_PersistentHandle* Dart_PersistentHandle;
+typedef Dart_Handle Dart_PersistentHandle;
 typedef struct _Dart_WeakPersistentHandle* Dart_WeakPersistentHandle;
 
 typedef void (*Dart_WeakPersistentHandleFinalizer)(
@@ -2241,9 +2245,9 @@
  * \param url A url identifying the origin of the patch source
  * \param source A string of Dart patch source
  */
-DART_EXPORT Dart_Handle Dart_LoadPatch(Dart_Handle library,
-                                       Dart_Handle url,
-                                       Dart_Handle patch_source);
+DART_EXPORT Dart_Handle Dart_LibraryLoadPatch(Dart_Handle library,
+                                              Dart_Handle url,
+                                              Dart_Handle patch_source);
 
 
 /*
diff --git a/runtime/lib/array.cc b/runtime/lib/array.cc
index 7116f5b..c81aef2 100644
--- a/runtime/lib/array.cc
+++ b/runtime/lib/array.cc
@@ -12,7 +12,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(ObjectArray_allocate, 2) {
+DEFINE_NATIVE_ENTRY(List_allocate, 2) {
   const AbstractTypeArguments& type_arguments =
       AbstractTypeArguments::CheckedHandle(isolate, arguments->NativeArgAt(0));
   const Instance& length = Instance::CheckedHandle(
@@ -21,18 +21,14 @@
     const String& error = String::Handle(String::NewFormatted(
         "Length must be an integer in the range [0..%" Pd "].",
         Array::kMaxElements));
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, error);
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
+    Exceptions::ThrowArgumentError(error);
   }
   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 "].",
         len, Array::kMaxElements));
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, error);
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
+    Exceptions::ThrowArgumentError(error);
   }
   const Array& new_array = Array::Handle(Array::New(len));
   new_array.SetTypeArguments(type_arguments);
@@ -40,7 +36,7 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(ObjectArray_getIndexed, 2) {
+DEFINE_NATIVE_ENTRY(List_getIndexed, 2) {
   const Array& array = Array::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
   if ((index.Value() < 0) || (index.Value() >= array.Length())) {
@@ -52,7 +48,7 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(ObjectArray_setIndexed, 3) {
+DEFINE_NATIVE_ENTRY(List_setIndexed, 3) {
   const Array& array = Array::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
   const Instance& value = Instance::CheckedHandle(arguments->NativeArgAt(2));
@@ -66,14 +62,14 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(ObjectArray_getLength, 1) {
+DEFINE_NATIVE_ENTRY(List_getLength, 1) {
   const Array& array = Array::CheckedHandle(arguments->NativeArgAt(0));
   return Smi::New(array.Length());
 }
 
 
 // ObjectArray src, int srcStart, int dstStart, int count.
-DEFINE_NATIVE_ENTRY(ObjectArray_copyFromObjectArray, 5) {
+DEFINE_NATIVE_ENTRY(List_copyFromObjectArray, 5) {
   const Array& dest = Array::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Array, source, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, src_start, arguments->NativeArgAt(2));
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index e16cbef..89ddce5 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -4,26 +4,26 @@
 
 
 // TODO(srdjan): Use shared array implementation.
-class _ObjectArray<E> implements List<E> {
-  static final int _classId = (new _ObjectArray(0))._cid;
+class _List<E> implements List<E> {
+  static final int _classId = (new _List(0))._cid;
 
-  factory _ObjectArray(length) native "ObjectArray_allocate";
+  factory _List(length) native "List_allocate";
 
-  E operator [](int index) native "ObjectArray_getIndexed";
+  E operator [](int index) native "List_getIndexed";
 
-  void operator []=(int index, E value) native "ObjectArray_setIndexed";
+  void operator []=(int index, E value) native "List_setIndexed";
 
   String toString() {
     return IterableMixinWorkaround.toStringIterable(this,'[' , ']');
   }
 
-  int get length native "ObjectArray_getLength";
+  int get length native "List_getLength";
 
-  void _copyFromObjectArray(_ObjectArray src,
+  void _copyFromObjectArray(_List src,
                             int srcStart,
                             int dstStart,
                             int count)
-      native "ObjectArray_copyFromObjectArray";
+      native "List_copyFromObjectArray";
 
   void insert(int index, E element) {
     throw new UnsupportedError(
@@ -74,7 +74,7 @@
     int length = end - start;
     if (length == 0) return;
 
-    if (iterable is _ObjectArray) {
+    if (iterable is _List) {
       _copyFromObjectArray(iterable, skipCount, start, length);
     } else {
       List otherList;
@@ -110,7 +110,7 @@
     if (end == null) end = this.length;
     int length = end - start;
     if (start == end) return [];
-    List list = new _GrowableObjectArray<E>.withCapacity(length);
+    List list = new _GrowableList<E>.withCapacity(length);
     list.length = length;
     Arrays.copy(this, start, list, 0, length);
     return list;
@@ -270,29 +270,29 @@
 }
 
 
-// This is essentially the same class as _ObjectArray, but it does not
+// This is essentially the same class as _List, but it does not
 // permit any modification of array elements from Dart code. We use
 // this class for arrays constructed from Dart array literals.
 // TODO(hausner): We should consider the trade-offs between two
 // classes (and inline cache misses) versus a field in the native
 // implementation (checks when modifying). We should keep watching
 // the inline cache misses.
-class _ImmutableArray<E> implements List<E> {
+class _ImmutableList<E> implements List<E> {
   static final int _classId = (const [])._cid;
 
-  factory _ImmutableArray._uninstantiable() {
+  factory _ImmutableList._uninstantiable() {
     throw new UnsupportedError(
         "ImmutableArray can only be allocated by the VM");
   }
 
-  E operator [](int index) native "ObjectArray_getIndexed";
+  E operator [](int index) native "List_getIndexed";
 
   void operator []=(int index, E value) {
     throw new UnsupportedError(
         "Cannot modify an immutable array");
   }
 
-  int get length native "ObjectArray_getLength";
+  int get length native "List_getLength";
 
   void insert(int index, E element) {
     throw new UnsupportedError(
@@ -537,7 +537,7 @@
 
   _FixedSizeArrayIterator(List array)
       : _array = array, _length = array.length, _position = -1 {
-    assert(array is _ObjectArray || array is _ImmutableArray);
+    assert(array is _List || array is _ImmutableList);
   }
 
   bool moveNext() {
diff --git a/runtime/lib/array_patch.dart b/runtime/lib/array_patch.dart
index 386e8ac..cb9ca76 100644
--- a/runtime/lib/array_patch.dart
+++ b/runtime/lib/array_patch.dart
@@ -13,17 +13,17 @@
 patch class List<E> {
   /* patch */ factory List([int length = _GROWABLE_ARRAY_MARKER]) {
     if (identical(length, _GROWABLE_ARRAY_MARKER)) {
-      return new _GrowableObjectArray<E>(0);
+      return new _GrowableList<E>(0);
     }
     // All error handling on the length parameter is done at the implementation
-    // of new _ObjectArray.
-    return new _ObjectArray<E>(length);
+    // of new _List.
+    return new _List<E>(length);
   }
 
   /* patch */ factory List.filled(int length, E fill) {
     // All error handling on the length parameter is done at the implementation
-    // of new _ObjectArray.
-    var result = new _ObjectArray<E>(length);
+    // of new _List.
+    var result = new _List<E>(length);
     if (fill != null) {
       for (int i = 0; i < length; i++) {
         result[i] = fill;
@@ -36,9 +36,9 @@
   // [elements] contains elements that are already type checked.
   factory List._fromLiteral(List elements) {
     if (elements.isEmpty) {
-      return new _GrowableObjectArray<E>(0);
+      return new _GrowableList<E>(0);
     }
-    var result = new _GrowableObjectArray<E>.withData(elements);
+    var result = new _GrowableList<E>.withData(elements);
     result._setLength(elements.length);
     return result;
   }
diff --git a/runtime/lib/date.cc b/runtime/lib/date.cc
index 154f1fe..f1b0298 100644
--- a/runtime/lib/date.cc
+++ b/runtime/lib/date.cc
@@ -20,9 +20,7 @@
       Integer, dart_seconds, arguments->NativeArgAt(0));
   int64_t seconds = dart_seconds.AsInt64Value();
   if (seconds < 0 || seconds > kMaxAllowedSeconds) {
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, dart_seconds);
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
+    Exceptions::ThrowArgumentError(dart_seconds);
   }
   const char* name = OS::GetTimeZoneName(seconds);
   return String::New(name);
@@ -34,9 +32,7 @@
       Integer, dart_seconds, arguments->NativeArgAt(0));
   int64_t seconds = dart_seconds.AsInt64Value();
   if (seconds < 0 || seconds > kMaxAllowedSeconds) {
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, dart_seconds);
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
+    Exceptions::ThrowArgumentError(dart_seconds);
   }
   int offset = OS::GetTimeZoneOffsetInSeconds(seconds);
   return Integer::New(offset);
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index b37c526..1cadbdb 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -219,10 +219,8 @@
       && kLowerBoundary < d && d < kUpperBoundary) {
     return DoubleToStringAsFixed(d, static_cast<int>(fraction_digits_value));
   } else {
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, String::Handle(
+    Exceptions::ThrowArgumentError(String::Handle(
         String::New("Illegal arguments to double.toStringAsFixed")));
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
     return Object::null();
   }
 }
@@ -237,10 +235,8 @@
     return DoubleToStringAsExponential(
         d, static_cast<int>(fraction_digits_value));
   } else {
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, String::Handle(
+    Exceptions::ThrowArgumentError(String::Handle(
         String::New("Illegal arguments to double.toStringAsExponential")));
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
     return Object::null();
   }
 }
@@ -254,10 +250,8 @@
   if (1 <= precision_value && precision_value <= 21) {
     return DoubleToStringAsPrecision(d, static_cast<int>(precision_value));
   } else {
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, String::Handle(
+    Exceptions::ThrowArgumentError(String::Handle(
         String::New("Illegal arguments to double.toStringAsPrecision")));
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
     return Object::null();
   }
 }
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc
index 8c41892..82e6df1 100644
--- a/runtime/lib/function.cc
+++ b/runtime/lib/function.cc
@@ -33,6 +33,7 @@
       isolate, arguments->NativeArgAt(0));
   ASSERT(receiver.IsClosure());
   GET_NATIVE_ARGUMENT(Instance, other, arguments->NativeArgAt(1));
+  ASSERT(!other.IsNull());
   if (receiver.raw() == other.raw()) return Bool::True().raw();
   if (other.IsClosure()) {
     const Function& func_a = Function::Handle(Closure::function(receiver));
diff --git a/runtime/lib/growable_array.cc b/runtime/lib/growable_array.cc
index a080325..34f60a0 100644
--- a/runtime/lib/growable_array.cc
+++ b/runtime/lib/growable_array.cc
@@ -12,7 +12,7 @@
 
 namespace dart {
 
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_allocate, 2) {
+DEFINE_NATIVE_ENTRY(GrowableList_allocate, 2) {
   const AbstractTypeArguments& type_arguments =
       AbstractTypeArguments::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Array, data, arguments->NativeArgAt(1));
@@ -29,7 +29,7 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_getIndexed, 2) {
+DEFINE_NATIVE_ENTRY(GrowableList_getIndexed, 2) {
   const GrowableObjectArray& array =
       GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
@@ -43,7 +43,7 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_setIndexed, 3) {
+DEFINE_NATIVE_ENTRY(GrowableList_setIndexed, 3) {
   const GrowableObjectArray& array =
       GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, index, arguments->NativeArgAt(1));
@@ -58,21 +58,21 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_getLength, 1) {
+DEFINE_NATIVE_ENTRY(GrowableList_getLength, 1) {
   const GrowableObjectArray& array =
       GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
   return Smi::New(array.Length());
 }
 
 
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_getCapacity, 1) {
+DEFINE_NATIVE_ENTRY(GrowableList_getCapacity, 1) {
   const GrowableObjectArray& array =
       GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
   return Smi::New(array.Capacity());
 }
 
 
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_setLength, 2) {
+DEFINE_NATIVE_ENTRY(GrowableList_setLength, 2) {
   const GrowableObjectArray& array =
       GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1));
@@ -82,7 +82,7 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(GrowableObjectArray_setData, 2) {
+DEFINE_NATIVE_ENTRY(GrowableList_setData, 2) {
   const GrowableObjectArray& array =
       GrowableObjectArray::CheckedHandle(arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Array, data, arguments->NativeArgAt(1));
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 812a71a..b1f1ccb 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-class _GrowableObjectArray<T> implements List<T> {
-  static final int _classId = (new _GrowableObjectArray(0))._cid;
+class _GrowableList<T> implements List<T> {
+  static final int _classId = (new _GrowableList(0))._cid;
 
   void insert(int index, T element) {
     if (index < 0 || index > length) {
@@ -117,38 +117,38 @@
     if (end == null) end = length;
     int length = end - start;
     if (start == end) return <T>[];
-    List list = new _GrowableObjectArray<T>.withCapacity(length);
+    List list = new _GrowableList<T>.withCapacity(length);
     list.length = length;
     Arrays.copy(this, start, list, 0, length);
     return list;
   }
 
-  factory _GrowableObjectArray(int length) {
-    var data = new _ObjectArray((length == 0) ? 4 : length);
-    var result = new _GrowableObjectArray<T>.withData(data);
+  factory _GrowableList(int length) {
+    var data = new _List((length == 0) ? 4 : length);
+    var result = new _GrowableList<T>.withData(data);
     if (length > 0) {
       result._setLength(length);
     }
     return result;
   }
 
-  factory _GrowableObjectArray.withCapacity(int capacity) {
-    var data = new _ObjectArray((capacity == 0)? 4 : capacity);
-    return new _GrowableObjectArray<T>.withData(data);
+  factory _GrowableList.withCapacity(int capacity) {
+    var data = new _List((capacity == 0)? 4 : capacity);
+    return new _GrowableList<T>.withData(data);
   }
 
-  factory _GrowableObjectArray.from(Iterable<T> other) {
-    List<T> result = new _GrowableObjectArray<T>();
+  factory _GrowableList.from(Iterable<T> other) {
+    List<T> result = new _GrowableList<T>();
     result.addAll(other);
     return result;
   }
 
-  factory _GrowableObjectArray.withData(_ObjectArray data)
-    native "GrowableObjectArray_allocate";
+  factory _GrowableList.withData(_List data)
+    native "GrowableList_allocate";
 
-  int get length native "GrowableObjectArray_getLength";
+  int get length native "GrowableList_getLength";
 
-  int get _capacity native "GrowableObjectArray_getCapacity";
+  int get _capacity native "GrowableList_getCapacity";
 
   void set length(int new_length) {
     if (new_length > _capacity) {
@@ -161,13 +161,13 @@
     _setLength(new_length);
   }
 
-  void _setLength(int new_length) native "GrowableObjectArray_setLength";
+  void _setLength(int new_length) native "GrowableList_setLength";
 
-  void _setData(_ObjectArray array) native "GrowableObjectArray_setData";
+  void _setData(_List array) native "GrowableList_setData";
 
-  T operator [](int index) native "GrowableObjectArray_getIndexed";
+  T operator [](int index) native "GrowableList_getIndexed";
 
-  void operator []=(int index, T value) native "GrowableObjectArray_setIndexed";
+  void operator []=(int index, T value) native "GrowableList_setIndexed";
 
   // The length of this growable array. It is always less than or equal to the
   // length of the object array, which itself is always greater than 0, so that
@@ -221,7 +221,7 @@
   }
 
   void _grow(int new_length) {
-    var new_data = new _ObjectArray(new_length);
+    var new_data = new _List(new_length);
     for (int i = 0; i < length; i++) {
       new_data[i] = this[i];
     }
diff --git a/runtime/lib/immutable_map.dart b/runtime/lib/immutable_map.dart
index 65db0c9..475051f 100644
--- a/runtime/lib/immutable_map.dart
+++ b/runtime/lib/immutable_map.dart
@@ -4,9 +4,9 @@
 // Immutable map class for compiler generated map literals.
 
 class ImmutableMap<K, V> implements Map<K, V> {
-  final _ImmutableArray _kvPairs;
+  final _ImmutableList _kvPairs;
 
-  const ImmutableMap._create(_ImmutableArray keyValuePairs)
+  const ImmutableMap._create(_ImmutableList keyValuePairs)
       : _kvPairs = keyValuePairs;
 
 
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index 84dc9d6..dedb88d 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -232,9 +232,7 @@
                                         const Smi& amount,
                                         const bool silent = false) {
   if (amount.Value() < 0) {
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, amount);
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
+    Exceptions::ThrowArgumentError(amount);
   }
   if (value.IsSmi()) {
     const Smi& smi_value = Smi::Cast(value);
diff --git a/runtime/lib/integers.dart b/runtime/lib/integers.dart
index cec9518..50a3ab0 100644
--- a/runtime/lib/integers.dart
+++ b/runtime/lib/integers.dart
@@ -187,31 +187,53 @@
     return this.toDouble().toStringAsPrecision(precision);
   }
 
+  static const _digits = "0123456789abcdefghijklmnopqrstuvwxyz";
+
   String toRadixString(int radix) {
-    final table = const ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
-                         "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
-                         "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
-                         "u", "v", "w", "x", "y", "z"];
     if (radix is! int || radix < 2 || radix > 36) {
       throw new ArgumentError(radix);
     }
+    if (radix & (radix - 1) == 0) {
+      return _toPow2String(this, radix);
+    }
+    if (radix == 10) return this.toString();
     final bool isNegative = this < 0;
     int value = isNegative ? -this : this;
     List temp = new List();
-    while (value > 0) {
+    do {
       int digit = value % radix;
       value ~/= radix;
-      temp.add(digit);
+      temp.add(_digits.codeUnitAt(digit));
+    } while (value > 0);
+    if (isNegative) temp.add(0x2d);  // '-'.
+
+    _OneByteString string = _OneByteString._allocate(temp.length);
+    for (int i = 0, j = temp.length; j > 0; i++) {
+      string._setAt(i, temp[--j]);
     }
-    if (temp.isEmpty) {
-      return "0";
+    return string;
+  }
+
+  static String _toPow2String(value, radix) {
+    if (value == 0) return "0";
+    assert(radix & (radix - 1) == 0);
+    var negative = value < 0;
+    var bitsPerDigit = radix.bitLength - 1;
+    var length = 0;
+    if (negative) {
+      value = -value;
+      length = 1;
     }
-    StringBuffer buffer = new StringBuffer();
-    if (isNegative) buffer.write("-");
-    for (int i = temp.length - 1; i >= 0; i--) {
-      buffer.write(table[temp[i]]);
-    }
-    return buffer.toString();
+    // Integer division, rounding up, to find number of _digits.
+    length += (value.bitLength + bitsPerDigit - 1) ~/ bitsPerDigit;
+    _OneByteString string = _OneByteString._allocate(length);
+    string._setAt(0, 0x2d);  // '-'. Is overwritten if not negative.
+    var mask = radix - 1;
+    do {
+      string._setAt(--length, _digits.codeUnitAt(value & mask));
+      value >>= bitsPerDigit;
+    } while (value > 0);
+    return string;
   }
 
   _leftShiftWithMask32(count, mask)  native "Integer_leftShiftWithMask32";
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 8880d2306..9cfcddf 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -114,13 +114,6 @@
 }
 
 
-static void ThrowIllegalArgException(const String& message) {
-  const Array& args = Array::Handle(Array::New(1));
-  args.SetAt(0, message);
-  Exceptions::ThrowByType(Exceptions::kArgument, args);
-}
-
-
 static void ThrowIsolateSpawnException(const String& message) {
   const Array& args = Array::Handle(Array::New(1));
   args.SetAt(0, message);
@@ -239,7 +232,7 @@
     const String& msg = String::Handle(String::New(
         "spawnFunction expects to be passed a closure to a top-level static "
         "function"));
-    ThrowIllegalArgException(msg);
+    Exceptions::ThrowArgumentError(msg);
   }
 
   GET_NATIVE_ARGUMENT(Instance, callback, arguments->NativeArgAt(1));
@@ -258,7 +251,7 @@
     const String& msg = String::Handle(String::New(
         "spawnFunction expects to be passed either a unhandled exception "
         "callback to a top-level static function, or null"));
-    ThrowIllegalArgException(msg);
+    Exceptions::ThrowArgumentError(msg);
   }
 
 #if defined(DEBUG)
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 8e71843..754aa5f 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -742,9 +742,7 @@
   const Class& cls = Class::Handle(type.type_class());
   ASSERT(!cls.IsNull());
   if (cls.IsDynamicClass() || cls.IsVoidClass()) {
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, type);
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
+    Exceptions::ThrowArgumentError(type);
     UNREACHABLE();
   }
   const Type& stripped_type = Type::Handle(cls.RareType());
@@ -1410,11 +1408,31 @@
     UNREACHABLE();
   }
 
+  ASSERT(!type.IsNull());
+  AbstractTypeArguments& type_arguments =
+      AbstractTypeArguments::Handle(type.arguments());
+
   Class& redirected_klass = Class::Handle(klass.raw());
   Function& redirected_constructor = Function::Handle(lookup_constructor.raw());
   if (lookup_constructor.IsRedirectingFactory()) {
     ClassFinalizer::ResolveRedirectingFactory(klass, lookup_constructor);
-    Type& type = Type::Handle(lookup_constructor.RedirectionType());
+    Type& redirect_type = Type::Handle(lookup_constructor.RedirectionType());
+
+    if (!redirect_type.IsInstantiated()) {
+      // The type arguments of the redirection type are instantiated from the
+      // type arguments of the type reflected by the class mirror.
+      Error& malformed_error = Error::Handle();
+      redirect_type ^= redirect_type.InstantiateFrom(type_arguments,
+                                                     &malformed_error);
+      if (!malformed_error.IsNull()) {
+        ThrowInvokeError(malformed_error);
+        UNREACHABLE();
+      }
+    }
+
+    type = redirect_type.raw();
+    type_arguments = redirect_type.arguments();
+
     redirected_constructor = lookup_constructor.RedirectionTarget();
     ASSERT(!redirected_constructor.IsNull());
     redirected_klass = type.type_class();
@@ -1451,10 +1469,6 @@
     UNREACHABLE();
   }
 
-  ASSERT(!type.IsNull());
-  const AbstractTypeArguments& type_arguments =
-      AbstractTypeArguments::Handle(type.arguments());
-
   Instance& new_object = Instance::Handle();
   if (redirected_constructor.IsConstructor()) {
     // Constructors get the uninitialized object and a constructor phase. Note
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 0127c15..bab0aba 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -15,9 +15,7 @@
 DEFINE_NATIVE_ENTRY(StringBase_createFromCodePoints, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, list, arguments->NativeArgAt(0));
   if (!list.IsGrowableObjectArray() && !list.IsArray()) {
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, list);
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
+    Exceptions::ThrowArgumentError(list);
   }
 
   Array& a = Array::Handle();
@@ -37,13 +35,11 @@
   bool is_one_byte_string = true;
   intptr_t utf16_len = array_len;
   int32_t* utf32_array = zone->Alloc<int32_t>(array_len);
-  Object& index_object = Object::Handle(isolate);
+  Instance& index_object = Instance::Handle(isolate);
   for (intptr_t i = 0; i < array_len; i++) {
-    index_object = a.At(i);
+    index_object ^= a.At(i);
     if (!index_object.IsSmi()) {
-      const Array& args = Array::Handle(Array::New(1));
-      args.SetAt(0, index_object);
-      Exceptions::ThrowByType(Exceptions::kArgument, args);
+      Exceptions::ThrowArgumentError(index_object);
     }
     intptr_t value = Smi::Cast(index_object).Value();
     if (Utf::IsOutOfRange(value)) {
@@ -214,20 +210,39 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(Strings_concatAll, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Array, strings, arguments->NativeArgAt(0));
-  ASSERT(!strings.IsNull());
+DEFINE_NATIVE_ENTRY(Strings_concatAll, 3) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, argument, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, start, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(Smi, end, arguments->NativeArgAt(2));
+  const intptr_t start_ix = start.Value();
+  const intptr_t end_ix = end.Value();
+  if (start_ix < 0) {
+    Exceptions::ThrowArgumentError(start);
+  }
+  Array& strings = Array::Handle();
+  intptr_t length = -1;
+  if (argument.IsArray()) {
+    strings ^= argument.raw();
+    length = strings.Length();
+  } else if (argument.IsGrowableObjectArray()) {
+    const GrowableObjectArray& g_array = GrowableObjectArray::Cast(argument);
+    strings = g_array.data();
+    length =  g_array.Length();
+  } else {
+    Exceptions::ThrowArgumentError(argument);
+  }
+  if (end_ix > length) {
+    Exceptions::ThrowArgumentError(end);
+  }
+#if defined(DEBUG)
   // Check that the array contains strings.
   Instance& elem = Instance::Handle();
-  for (intptr_t i = 0; i < strings.Length(); i++) {
+  for (intptr_t i = start_ix; i < end_ix; i++) {
     elem ^= strings.At(i);
-    if (!elem.IsString()) {
-      const Array& args = Array::Handle(Array::New(1));
-      args.SetAt(0, elem);
-      Exceptions::ThrowByType(Exceptions::kArgument, args);
-    }
+    ASSERT(elem.IsString());
   }
-  return String::ConcatAll(strings);
+#endif
+  return String::ConcatAllRange(strings, start_ix, end_ix, Heap::kNew);
 }
 
 
diff --git a/runtime/lib/string_buffer_patch.dart b/runtime/lib/string_buffer_patch.dart
index 9a22647..72ec095 100644
--- a/runtime/lib/string_buffer_patch.dart
+++ b/runtime/lib/string_buffer_patch.dart
@@ -11,7 +11,7 @@
    * When strings are written to the string buffer, we add them to a
    * list of string parts.
    */
-  List _parts = null;
+  List<String> _parts = null;
 
   /**
     * Total number of code units in the string parts. Does not include
@@ -28,11 +28,10 @@
    */
   int _partsCompactionIndex = 0;
   int _partsCodeUnitsSinceCompaction = 0;
-  _ObjectArray _partsCompactionArray = null;
 
   /**
    * The buffer is used to build up a string from code units. It is
-   * used when writing short strings or individul char codes to the
+   * used when writing short strings or individual char codes to the
    * buffer. The buffer is allocated on demand.
    */
   Uint16List _buffer = null;
@@ -101,15 +100,9 @@
   /** Returns the contents of buffer as a string. */
   /* patch */ String toString() {
     _consumeBuffer();
-    if (_partsCodeUnits == 0) return "";
-
-    // TODO(kasperl): It would be nice if concatAllNative would
-    // allow me to pass in a grownable array directly, but for
-    // now we have to copy the contents to a non-growable array.
-    int length = _parts.length;
-    _ObjectArray array = new _ObjectArray(length);
-    for (int i = 0; i < length; i++) array[i] = _parts[i];
-    return _StringBase._concatAllNative(array);
+    return (_partsCodeUnits == 0) ?
+        "" :
+        _StringBase._concatAllNative(_parts, 0, _parts.length);
   }
 
   /** Ensures that the buffer has enough capacity to add n code units. */
@@ -160,18 +153,13 @@
    */
   void _compact() {
     if (_partsCodeUnitsSinceCompaction < _PARTS_TO_COMPACT_SIZE_LIMIT) {
-      if (_partsCompactionArray == null) {
-        _partsCompactionArray = new _ObjectArray(_PARTS_TO_COMPACT);
-      }
-      for (int i = 0; i < _PARTS_TO_COMPACT; i++) {
-        _partsCompactionArray[i] = _parts[i + _partsCompactionIndex];
-      }
-      String compacted = _StringBase._concatAllNative(_partsCompactionArray);
+      String compacted = _StringBase._concatAllNative(
+          _parts,
+          _partsCompactionIndex,                     // Start
+          _partsCompactionIndex + _PARTS_TO_COMPACT  // End
+      );
       _parts.length = _parts.length - _PARTS_TO_COMPACT;
       _parts.add(compacted);
-      for (int i = 0; i < _PARTS_TO_COMPACT; i++) {
-        _partsCompactionArray[i] = null;
-      }
     }
     _partsCodeUnitsSinceCompaction = 0;
     _partsCompactionIndex = _parts.length;
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index e4f959e..d3285b2 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -30,9 +30,9 @@
     if (charCodes != null) {
       // TODO(srdjan): Also skip copying of typed arrays.
       final ccid = charCodes._cid;
-      if ((ccid != _ObjectArray._classId) &&
-          (ccid != _GrowableObjectArray._classId) &&
-          (ccid != _ImmutableArray._classId)) {
+      if ((ccid != _List._classId) &&
+          (ccid != _GrowableList._classId) &&
+          (ccid != _ImmutableList._classId)) {
         charCodes = new List<int>.from(charCodes, growable: false);
       }
 
@@ -395,9 +395,9 @@
    * Convert all objects in [values] to strings and concat them
    * into a result string.
    */
-  static String _interpolate(List values) {
+  static String _interpolate(List<String> values) {
     final int numValues = values.length;
-    _ObjectArray stringList = new List(numValues);
+    _List stringList = new List<String>(numValues);
     bool isOneByteString = true;
     int totalLength = 0;
     for (int i = 0; i < numValues; i++) {
@@ -406,13 +406,16 @@
         totalLength += s.length;
       } else {
         isOneByteString = false;
+        if (s is! String) {
+          throw new ArgumentError(s);
+        }
       }
       stringList[i] = s;
     }
     if (isOneByteString) {
       return _OneByteString._concatAll(stringList, totalLength);
     }
-    return _concatAllNative(stringList);
+    return _concatAllNative(stringList, 0, stringList.length);
   }
 
   Iterable<Match> allMatches(String str) {
@@ -497,8 +500,9 @@
 
   String toLowerCase() native "String_toLowerCase";
 
-  // Call this method if not all list elements are OneByteString-s.
-  static String _concatAllNative(_ObjectArray<String> strings)
+  // Call this method if not all list elements are known to be OneByteString(s).
+  // 'strings' must be an _List or _GrowableList.
+  static String _concatAllNative(List<String> strings, int start, int end)
       native "Strings_concatAll";
 }
 
@@ -531,11 +535,11 @@
   }
 
   // All element of 'strings' must be OneByteStrings.
-  static _concatAll(_ObjectArray<String> strings, int totalLength) {
+  static _concatAll(_List<String> strings, int totalLength) {
     // TODO(srdjan): Improve code below and raise or eliminate the limit.
     if (totalLength > 128) {
       // Native is quicker.
-      return _StringBase._concatAllNative(strings);
+      return _StringBase._concatAllNative(strings, 0, strings.length);
     }
     var res = _OneByteString._allocate(totalLength);
     final stringsLength = strings.length;
diff --git a/runtime/lib/typed_data.cc b/runtime/lib/typed_data.cc
index 6690085..ff4d00b 100644
--- a/runtime/lib/typed_data.cc
+++ b/runtime/lib/typed_data.cc
@@ -38,9 +38,7 @@
     const String& error = String::Handle(String::NewFormatted(
         "Length (%" Pd ") of object must be in range [0..%" Pd "]",
         len, max));
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, error);
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
+    Exceptions::ThrowArgumentError(error);
   }
 }
 
@@ -63,9 +61,7 @@
   }
   const String& error = String::Handle(String::NewFormatted(
       "Expected a TypedData object but found %s", instance.ToCString()));
-  const Array& args = Array::Handle(Array::New(1));
-  args.SetAt(0, error);
-  Exceptions::ThrowByType(Exceptions::kArgument, args);
+  Exceptions::ThrowArgumentError(error);
   return Integer::null();
 }
 
@@ -107,9 +103,7 @@
   if (length.Value() < 0) {
     const String& error = String::Handle(String::NewFormatted(
         "length (%" Pd ") must be non-negative", length.Value()));
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, error);
-    Exceptions::ThrowByType(Exceptions::kArgument, args);
+    Exceptions::ThrowArgumentError(error);
   }
   if (dst.IsTypedData()) {
     if (src.IsTypedData()) {
@@ -193,9 +187,7 @@
   }                                                                            \
   const String& error = String::Handle(String::NewFormatted(                   \
       "Expected a TypedData object but found %s", instance.ToCString()));      \
-  const Array& args = Array::Handle(Array::New(1));                            \
-  args.SetAt(0, error);                                                        \
-  Exceptions::ThrowByType(Exceptions::kArgument, args);                        \
+  Exceptions::ThrowArgumentError(error);                                       \
   return object::null();                                                       \
 }                                                                              \
 
@@ -218,9 +210,7 @@
   } else {                                                                     \
     const String& error = String::Handle(String::NewFormatted(                 \
         "Expected a TypedData object but found %s", instance.ToCString()));    \
-    const Array& args = Array::Handle(Array::New(1));                          \
-    args.SetAt(0, error);                                                      \
-    Exceptions::ThrowByType(Exceptions::kArgument, args);                      \
+    Exceptions::ThrowArgumentError(error);                                     \
   }                                                                            \
   return Object::null();                                                       \
 }
@@ -242,9 +232,7 @@
   } else {                                                                     \
     const String& error = String::Handle(String::NewFormatted(                 \
         "Expected a TypedData object but found %s", instance.ToCString()));    \
-    const Array& args = Array::Handle(Array::New(1));                          \
-    args.SetAt(0, error);                                                      \
-    Exceptions::ThrowByType(Exceptions::kArgument, args);                      \
+    Exceptions::ThrowArgumentError(error);                                     \
   }                                                                            \
   return Integer::NewFromUint64(value);                                        \
 }                                                                              \
@@ -277,9 +265,7 @@
   } else {                                                                     \
     const String& error = String::Handle(String::NewFormatted(                 \
         "Expected a TypedData object but found %s", instance.ToCString()));    \
-    const Array& args = Array::Handle(Array::New(1));                          \
-    args.SetAt(0, error);                                                      \
-    Exceptions::ThrowByType(Exceptions::kArgument, args);                      \
+    Exceptions::ThrowArgumentError(error);                                     \
   }                                                                            \
   return Object::null();                                                       \
 }
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 744aa61..445dd40 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -66,3 +66,6 @@
 [ $compiler == dart2analyzer ]
 # has compilation error, as designed
 dart/isolate_mirror_local_test: fail
+
+[ $compiler == none && $runtime == dartium ]
+dart/isolate_mirror_local_test: Fail # Issue 13719: Please triage this failure.
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index f7b0ea3..cc93724 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -204,6 +204,16 @@
 }
 
 
+void Assembler::PushImmediate(const Immediate& imm, Register pp) {
+  if (CanLoadImmediateFromPool(imm, pp)) {
+    LoadImmediate(TMP, imm, pp);
+    pushq(TMP);
+  } else {
+    pushq(imm);
+  }
+}
+
+
 void Assembler::popq(Register reg) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitRegisterREX(reg, REX_NONE);
@@ -813,7 +823,8 @@
     uint32_t d;
   } float_not_constant =
       { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
-  movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_not_constant)));
+  LoadImmediate(
+      TMP, Immediate(reinterpret_cast<intptr_t>(&float_not_constant)), PP);
   xorps(dst, Address(TMP, 0));
 }
 
@@ -826,7 +837,8 @@
     uint32_t d;
   } float_negate_constant =
       { 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
-  movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_negate_constant)));
+  LoadImmediate(
+      TMP, Immediate(reinterpret_cast<intptr_t>(&float_negate_constant)), PP);
   xorps(dst, Address(TMP, 0));
 }
 
@@ -839,7 +851,8 @@
     uint32_t d;
   } float_absolute_constant =
       { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF };
-  movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_absolute_constant)));
+  LoadImmediate(
+      TMP, Immediate(reinterpret_cast<intptr_t>(&float_absolute_constant)), PP);
   andps(dst, Address(TMP, 0));
 }
 
@@ -852,7 +865,8 @@
     uint32_t d;
   } float_zerow_constant =
       { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 };
-  movq(TMP, Immediate(reinterpret_cast<intptr_t>(&float_zerow_constant)));
+  LoadImmediate(
+      TMP, Immediate(reinterpret_cast<intptr_t>(&float_zerow_constant)), PP);
   andps(dst, Address(TMP, 0));
 }
 
@@ -1342,6 +1356,28 @@
 }
 
 
+void Assembler::CompareImmediate(Register reg, const Immediate& imm,
+                                 Register pp) {
+  if (CanLoadImmediateFromPool(imm, pp)) {
+    LoadImmediate(TMP, imm, pp);
+    cmpq(reg, TMP);
+  } else {
+    cmpq(reg, imm);
+  }
+}
+
+
+void Assembler::CompareImmediate(const Address& address, const Immediate& imm,
+                                 Register pp) {
+  if (CanLoadImmediateFromPool(imm, pp)) {
+    LoadImmediate(TMP, imm, pp);
+    cmpq(address, TMP);
+  } else {
+    cmpq(address, imm);
+  }
+}
+
+
 void Assembler::testl(Register reg1, Register reg2) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   Operand operand(reg2);
@@ -1492,6 +1528,17 @@
 }
 
 
+void Assembler::AndImmediate(Register dst, const Immediate& imm, Register pp) {
+  if (CanLoadImmediateFromPool(imm, pp)) {
+    ASSERT(dst != TMP);
+    LoadImmediate(TMP, imm, pp);
+    andq(dst, TMP);
+  } else {
+    andq(dst, imm);
+  }
+}
+
+
 void Assembler::orq(Register dst, Register src) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   Operand operand(src);
@@ -1521,6 +1568,17 @@
 }
 
 
+void Assembler::OrImmediate(Register dst, const Immediate& imm, Register pp) {
+  if (CanLoadImmediateFromPool(imm, pp)) {
+    ASSERT(dst != TMP);
+    LoadImmediate(TMP, imm, pp);
+    orq(dst, TMP);
+  } else {
+    orq(dst, imm);
+  }
+}
+
+
 void Assembler::xorq(Register dst, Register src) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   Operand operand(src);
@@ -1558,6 +1616,17 @@
 }
 
 
+void Assembler::XorImmediate(Register dst, const Immediate& imm, Register pp) {
+  if (CanLoadImmediateFromPool(imm, pp)) {
+    ASSERT(dst != TMP);
+    LoadImmediate(TMP, imm, pp);
+    xorq(dst, TMP);
+  } else {
+    xorq(dst, imm);
+  }
+}
+
+
 void Assembler::addl(Register dst, Register src) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   Operand operand(src);
@@ -1602,9 +1671,14 @@
 
 
 void Assembler::addq(const Address& address, const Immediate& imm) {
-  // TODO(srdjan): Implement shorter version for imm32.
-  movq(TMP, imm);
-  addq(address, TMP);
+  if (imm.is_int32()) {
+    AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+    EmitOperandREX(0, address, REX_W);
+    EmitComplex(0, Operand(address), imm);
+  } else {
+    movq(TMP, imm);
+    addq(address, TMP);
+  }
 }
 
 
@@ -1708,6 +1782,17 @@
 }
 
 
+void Assembler::MulImmediate(Register reg, const Immediate& imm, Register pp) {
+  if (CanLoadImmediateFromPool(imm, pp)) {
+    ASSERT(reg != TMP);
+    LoadImmediate(TMP, imm, pp);
+    imulq(reg, TMP);
+  } else {
+    imulq(reg, imm);
+  }
+}
+
+
 void Assembler::imulq(Register dst, const Address& address) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitOperandREX(dst, address, REX_W);
@@ -1746,6 +1831,26 @@
 }
 
 
+void Assembler::subq(const Address& address, Register reg) {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  EmitOperandREX(reg, address, REX_W);
+  EmitUint8(0x29);
+  EmitOperand(reg & 7, address);
+}
+
+
+void Assembler::subq(const Address& address, const Immediate& imm) {
+  if (imm.is_int32()) {
+    AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+    EmitOperandREX(0, address, REX_W);
+    EmitComplex(5, Operand(address), imm);
+  } else {
+    movq(TMP, imm);
+    subq(address, TMP);
+  }
+}
+
+
 void Assembler::shll(Register reg, const Immediate& imm) {
   EmitGenericShift(false, 4, reg, imm);
 }
@@ -2138,20 +2243,64 @@
 }
 
 
-void Assembler::AddImmediate(Register reg, const Immediate& imm) {
+void Assembler::AddImmediate(Register reg, const Immediate& imm, Register pp) {
   int64_t value = imm.value();
   if (value > 0) {
     if (value == 1) {
       incq(reg);
     } else if (value != 0) {
-      addq(reg, imm);
+      if (CanLoadImmediateFromPool(imm, pp)) {
+        ASSERT(reg != TMP);
+        LoadImmediate(TMP, imm, pp);
+        addq(reg, TMP);
+      } else {
+        addq(reg, imm);
+      }
     }
   } else if (value < 0) {
     value = -value;
     if (value == 1) {
       decq(reg);
     } else if (value != 0) {
-      subq(reg, Immediate(value));
+      const Immediate& s = Immediate(value);
+      if (CanLoadImmediateFromPool(s, pp)) {
+        ASSERT(reg != TMP);
+        LoadImmediate(TMP, s, pp);
+        subq(reg, TMP);
+      } else {
+        subq(reg, Immediate(value));
+      }
+    }
+  }
+}
+
+
+void Assembler::AddImmediate(const Address& address, const Immediate& imm,
+                             Register pp) {
+  int64_t value = imm.value();
+  if (value > 0) {
+    if (value == 1) {
+      incq(address);
+    } else if (value != 0) {
+      if (CanLoadImmediateFromPool(imm, pp)) {
+        LoadImmediate(TMP, imm, pp);
+        addq(address, TMP);
+      } else {
+        addq(address, imm);
+      }
+    }
+  } else if (value < 0) {
+    value = -value;
+    if (value == 1) {
+      decq(address);
+    } else if (value != 0) {
+      const Immediate& s = Immediate(value);
+      if (CanLoadImmediateFromPool(s, pp)) {
+        LoadImmediate(TMP, s, pp);
+        subq(address, TMP);
+      } else {
+        subq(address, s);
+      }
     }
   }
 }
@@ -2261,38 +2410,86 @@
     ASSERT((Isolate::Current() == Dart::vm_isolate()) ||
            object.IsSmi() ||
            object.InVMHeap());
-    movq(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
+    LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp);
   }
 }
 
 
-void Assembler::StoreObject(const Address& dst, const Object& object) {
+void Assembler::StoreObject(const Address& dst, const Object& object,
+                            Register pp) {
   if (CanLoadFromObjectPool(object)) {
-    LoadObject(TMP, object, PP);
+    LoadObject(TMP, object, pp);
     movq(dst, TMP);
   } else {
-    movq(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
+    LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())), pp);
   }
 }
 
 
-void Assembler::PushObject(const Object& object) {
+void Assembler::PushObject(const Object& object, Register pp) {
   if (CanLoadFromObjectPool(object)) {
-    LoadObject(TMP, object, PP);
+    LoadObject(TMP, object, pp);
     pushq(TMP);
   } else {
-    pushq(Immediate(reinterpret_cast<int64_t>(object.raw())));
+    PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw())), pp);
   }
 }
 
 
-void Assembler::CompareObject(Register reg, const Object& object) {
+void Assembler::CompareObject(Register reg, const Object& object, Register pp) {
   if (CanLoadFromObjectPool(object)) {
     ASSERT(reg != TMP);
-    LoadObject(TMP, object, PP);
+    LoadObject(TMP, object, pp);
     cmpq(reg, TMP);
   } else {
-    cmpq(reg, Immediate(reinterpret_cast<int64_t>(object.raw())));
+    CompareImmediate(
+        reg, Immediate(reinterpret_cast<int64_t>(object.raw())), pp);
+  }
+}
+
+
+intptr_t Assembler::FindImmediate(int64_t imm) {
+  ASSERT(Isolate::Current() != Dart::vm_isolate());
+  ASSERT(!object_pool_.IsNull());
+  const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm));
+  return FindObject(smi, kNotPatchable);
+}
+
+
+bool Assembler::CanLoadImmediateFromPool(const Immediate& imm, Register pp) {
+  return !imm.is_int32() &&
+         (pp != kNoRegister) &&
+         (Isolate::Current() != Dart::vm_isolate());
+}
+
+
+void Assembler::LoadImmediate(Register reg, const Immediate& imm, Register pp) {
+  if (CanLoadImmediateFromPool(imm, pp)) {
+    // It's a 64-bit constant and we're not in the VM isolate, so load from
+    // object pool.
+    int64_t val = imm.value();
+    // Save the bits that must be masked-off for the SmiTag
+    int64_t val_smi_tag = val & kSmiTagMask;
+    val &= ~kSmiTagMask;  // Mask off the tag bits.
+    const int32_t offset = Array::element_offset(FindImmediate(val));
+    LoadWordFromPoolOffset(reg, pp, offset - kHeapObjectTag);
+    if (val_smi_tag != 0) {
+      // Add back the tag bits.
+      orq(reg, Immediate(val_smi_tag));
+    }
+  } else {
+    movq(reg, imm);
+  }
+}
+
+
+void Assembler::LoadImmediate(const Address& dst, const Immediate& imm,
+                              Register pp) {
+  if (CanLoadImmediateFromPool(imm, pp)) {
+    LoadImmediate(TMP, imm, pp);
+    movq(dst, TMP);
+  } else {
+    movq(dst, imm);
   }
 }
 
@@ -2383,7 +2580,8 @@
     uint64_t b;
   } double_negate_constant =
       {0x8000000000000000LL, 0x8000000000000000LL};
-  movq(TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)));
+  LoadImmediate(
+      TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)), PP);
   xorpd(d, Address(TMP, 0));
 }
 
@@ -2394,7 +2592,8 @@
     uint64_t b;
   } double_abs_constant =
       {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
-  movq(TMP, Immediate(reinterpret_cast<intptr_t>(&double_abs_constant)));
+  LoadImmediate(TMP,
+      Immediate(reinterpret_cast<intptr_t>(&double_abs_constant)), PP);
   andpd(reg, Address(TMP, 0));
 }
 
@@ -2404,7 +2603,7 @@
   if (FLAG_print_stop_message) {
     pushq(TMP);  // Preserve TMP register.
     pushq(RDI);  // Preserve RDI register.
-    movq(RDI, Immediate(message_address));
+    LoadImmediate(RDI, Immediate(message_address), PP);
     call(&StubCode::PrintStopMessageLabel());
     popq(RDI);  // Restore RDI register.
     popq(TMP);  // Restore TMP register.
@@ -2477,7 +2676,9 @@
 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
   // Reserve space for arguments and align frame before entering
   // the C++ world.
-  AddImmediate(RSP, Immediate(-frame_space));
+  if (frame_space != 0) {
+    subq(RSP, Immediate(frame_space));
+  }
   if (OS::ActivationFrameAlignment() > 1) {
     andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
   }
@@ -2667,29 +2868,31 @@
 void Assembler::TryAllocate(const Class& cls,
                             Label* failure,
                             bool near_jump,
-                            Register instance_reg) {
+                            Register instance_reg,
+                            Register pp) {
   ASSERT(failure != NULL);
   if (FLAG_inline_alloc) {
     Heap* heap = Isolate::Current()->heap();
     const intptr_t instance_size = cls.instance_size();
-    movq(TMP, Immediate(heap->TopAddress()));
+    LoadImmediate(TMP, Immediate(heap->TopAddress()), pp);
     movq(instance_reg, Address(TMP, 0));
-    addq(instance_reg, Immediate(instance_size));
+    AddImmediate(instance_reg, Immediate(instance_size), pp);
     // instance_reg: potential next object start.
-    movq(TMP, Immediate(heap->EndAddress()));
+    LoadImmediate(TMP, Immediate(heap->EndAddress()), pp);
     cmpq(instance_reg, Address(TMP, 0));
     j(ABOVE_EQUAL, failure, near_jump);
     // Successfully allocated the object, now update top to point to
     // next object start and store the class in the class field of object.
-    movq(TMP, Immediate(heap->TopAddress()));
+    LoadImmediate(TMP, Immediate(heap->TopAddress()), pp);
     movq(Address(TMP, 0), instance_reg);
     ASSERT(instance_size >= kHeapObjectTag);
-    subq(instance_reg, Immediate(instance_size - kHeapObjectTag));
+    AddImmediate(instance_reg, Immediate(kHeapObjectTag - instance_size), pp);
     uword tags = 0;
     tags = RawObject::SizeTag::update(instance_size, tags);
     ASSERT(cls.id() != kIllegalCid);
     tags = RawObject::ClassIdTag::update(cls.id(), tags);
-    movq(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags));
+    LoadImmediate(FieldAddress(instance_reg, Object::tags_offset()),
+                  Immediate(tags), pp);
   } else {
     jmp(failure);
   }
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index 4aa070c..5f17299 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -356,6 +356,7 @@
   void pushq(Register reg);
   void pushq(const Address& address);
   void pushq(const Immediate& imm);
+  void PushImmediate(const Immediate& imm, Register pp);
 
   void popq(Register reg);
   void popq(const Address& address);
@@ -489,6 +490,10 @@
   void cmpq(Register reg0, Register reg1);
   void cmpq(Register reg, const Address& address);
 
+  void CompareImmediate(Register reg, const Immediate& imm, Register pp);
+  void CompareImmediate(const Address& address, const Immediate& imm,
+                        Register pp);
+
   void testl(Register reg1, Register reg2);
   void testl(Register reg, const Immediate& imm);
 
@@ -506,15 +511,18 @@
   void andq(Register dst, Register src);
   void andq(Register dst, const Address& address);
   void andq(Register dst, const Immediate& imm);
+  void AndImmediate(Register dst, const Immediate& imm, Register pp);
 
   void orq(Register dst, Register src);
   void orq(Register dst, const Address& address);
   void orq(Register dst, const Immediate& imm);
+  void OrImmediate(Register dst, const Immediate& imm, Register pp);
 
   void xorq(Register dst, Register src);
   void xorq(Register dst, const Address& address);
   void xorq(const Address& dst, Register src);
   void xorq(Register dst, const Immediate& imm);
+  void XorImmediate(Register dst, const Immediate& imm, Register pp);
 
   void addl(Register dst, Register src);
   void addl(const Address& address, const Immediate& imm);
@@ -541,10 +549,13 @@
   void imulq(Register dst, Register src);
   void imulq(Register dst, const Address& address);
   void imulq(Register dst, const Immediate& imm);
+  void MulImmediate(Register reg, const Immediate& imm, Register pp);
 
   void subq(Register dst, Register src);
   void subq(Register reg, const Immediate& imm);
   void subq(Register reg, const Address& address);
+  void subq(const Address& address, Register reg);
+  void subq(const Address& address, const Immediate& imm);
 
   void shll(Register reg, const Immediate& imm);
   void shll(Register operand, Register shifter);
@@ -657,7 +668,8 @@
   void MoveRegister(Register to, Register from);
   void PopRegister(Register r);
 
-  void AddImmediate(Register reg, const Immediate& imm);
+  void AddImmediate(Register reg, const Immediate& imm, Register pp);
+  void AddImmediate(const Address& address, const Immediate& imm, Register pp);
 
   void Drop(intptr_t stack_elements);
 
@@ -666,15 +678,18 @@
     kNotPatchable,
   };
 
+  bool CanLoadImmediateFromPool(const Immediate& imm, Register pp);
+  void LoadImmediate(Register reg, const Immediate& imm, Register pp);
+  void LoadImmediate(const Address& dst, const Immediate& imm, Register pp);
   void LoadObject(Register dst, const Object& obj, Register pp);
   void JmpPatchable(const ExternalLabel* label, Register pp);
   void Jmp(const ExternalLabel* label, Register pp);
   void J(Condition condition, const ExternalLabel* label, Register pp);
   void CallPatchable(const ExternalLabel* label);
   void Call(const ExternalLabel* label, Register pp);
-  void StoreObject(const Address& dst, const Object& obj);
-  void PushObject(const Object& object);
-  void CompareObject(Register reg, const Object& object);
+  void StoreObject(const Address& dst, const Object& obj, Register pp);
+  void PushObject(const Object& object, Register pp);
+  void CompareObject(Register reg, const Object& object, Register pp);
   void LoadDoubleConstant(XmmRegister dst, double value);
 
   // Destroys value.
@@ -812,10 +827,13 @@
   // calls. Jump to 'failure' if the instance cannot be allocated here.
   // Allocated instance is returned in 'instance_reg'.
   // Only the tags field of the object is initialized.
+  // Loads large immediates from the object pool with pool pointer in PP if it
+  // is not kNoRegister
   void TryAllocate(const Class& cls,
                    Label* failure,
                    bool near_jump,
-                   Register instance_reg);
+                   Register instance_reg,
+                   Register pp);
 
   // Debugging and bringup support.
   void Stop(const char* message);
@@ -901,6 +919,7 @@
   intptr_t FindObject(const Object& obj, Patchability patchable);
   intptr_t FindExternalLabel(const ExternalLabel* label,
                              Patchability patchable);
+  intptr_t FindImmediate(int64_t imm);
   void LoadExternalLabel(Register dst,
                          const ExternalLabel* label,
                          Patchability patchable,
diff --git a/runtime/vm/assembler_x64_test.cc b/runtime/vm/assembler_x64_test.cc
index 2d148cd..fd68d8e 100644
--- a/runtime/vm/assembler_x64_test.cc
+++ b/runtime/vm/assembler_x64_test.cc
@@ -1292,14 +1292,14 @@
   ExternalLabel call2("LeafReturnArgument",
                       reinterpret_cast<uword>(LeafReturnArgument));
   int space = ComputeStackSpaceReservation(0, 8);
-  __ AddImmediate(RSP, Immediate(-space));
+  __ subq(RSP, Immediate(space));
   __ call(&call1);
-  __ AddImmediate(RSP, Immediate(space));
+  __ addq(RSP, Immediate(space));
   space = ComputeStackSpaceReservation(0, 8);
-  __ AddImmediate(RSP, Immediate(-space));
+  __ subq(RSP, Immediate(space));
   __ movl(RDI, RAX);
   __ call(&call2);
-  __ AddImmediate(RSP, Immediate(space));
+  __ addq(RSP, Immediate(space));
   __ ret();
 }
 
@@ -1314,9 +1314,9 @@
   ExternalLabel call1("LeafReturn42", reinterpret_cast<uword>(LeafReturn42));
   Label L;
   int space = ComputeStackSpaceReservation(0, 8);
-  __ AddImmediate(RSP, Immediate(-space));
+  __ subq(RSP, Immediate(space));
   __ call(&L);
-  __ AddImmediate(RSP, Immediate(space));
+  __ addq(RSP, Immediate(space));
   __ ret();
   __ Bind(&L);
   __ jmp(&call1);
@@ -1625,11 +1625,13 @@
 
 
 ASSEMBLER_TEST_GENERATE(PackedNegate, assembler) {
+  __ EnterDartFrame(0);
   __ movl(RAX, Immediate(bit_cast<int32_t, float>(12.3f)));
   __ movd(XMM0, RAX);
   __ shufps(XMM0, XMM0, Immediate(0x0));
   __ negateps(XMM0);
   __ shufps(XMM0, XMM0, Immediate(0xAA));  // Copy third lane into all 4 lanes.
+  __ LeaveFrameWithPP();
   __ ret();
 }
 
@@ -1642,11 +1644,13 @@
 
 
 ASSEMBLER_TEST_GENERATE(PackedAbsolute, assembler) {
+  __ EnterDartFrame(0);
   __ movl(RAX, Immediate(bit_cast<int32_t, float>(-15.3f)));
   __ movd(XMM0, RAX);
   __ shufps(XMM0, XMM0, Immediate(0x0));
   __ absps(XMM0);
   __ shufps(XMM0, XMM0, Immediate(0xAA));  // Copy third lane into all 4 lanes.
+  __ LeaveFrameWithPP();
   __ ret();
 }
 
@@ -1659,9 +1663,11 @@
 
 
 ASSEMBLER_TEST_GENERATE(PackedSetWZero, assembler) {
+  __ EnterDartFrame(0);
   __ set1ps(XMM0, RAX, Immediate(bit_cast<int32_t, float>(12.3f)));
   __ zerowps(XMM0);
   __ shufps(XMM0, XMM0, Immediate(0xFF));  // Copy the W lane which is now 0.0.
+  __ LeaveFrameWithPP();
   __ ret();
 }
 
@@ -1778,13 +1784,15 @@
     uint32_t d;
   } constant1 =
       { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
-  __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1)));
+  __ EnterDartFrame(0);
+  __ LoadImmediate(RAX, Immediate(reinterpret_cast<intptr_t>(&constant1)), PP);
   __ movups(XMM9, Address(RAX, 0));
   __ notps(XMM9);
   __ movaps(XMM0, XMM9);
   __ pushq(RAX);
   __ movss(Address(RSP, 0), XMM0);
   __ popq(RAX);
+  __ LeaveFrameWithPP();
   __ ret();
 }
 
@@ -2183,24 +2191,24 @@
   Label fail;
   __ EnterDartFrame(0);
   __ LoadObject(RAX, obj, PP);
-  __ CompareObject(RAX, obj);
+  __ CompareObject(RAX, obj, PP);
   __ j(NOT_EQUAL, &fail);
   __ LoadObject(RCX, obj, PP);
-  __ CompareObject(RCX, obj);
+  __ CompareObject(RCX, obj, PP);
   __ j(NOT_EQUAL, &fail);
   const Smi& smi = Smi::ZoneHandle(Smi::New(15));
   __ LoadObject(RCX, smi, PP);
-  __ CompareObject(RCX, smi);
+  __ CompareObject(RCX, smi, PP);
   __ j(NOT_EQUAL, &fail);
   __ pushq(RAX);
-  __ StoreObject(Address(RSP, 0), obj);
+  __ StoreObject(Address(RSP, 0), obj, PP);
   __ popq(RCX);
-  __ CompareObject(RCX, obj);
+  __ CompareObject(RCX, obj, PP);
   __ j(NOT_EQUAL, &fail);
   __ pushq(RAX);
-  __ StoreObject(Address(RSP, 0), smi);
+  __ StoreObject(Address(RSP, 0), smi, PP);
   __ popq(RCX);
-  __ CompareObject(RCX, smi);
+  __ CompareObject(RCX, smi, PP);
   __ j(NOT_EQUAL, &fail);
   __ movl(RAX, Immediate(1));  // OK
   __ LeaveFrameWithPP();
@@ -2539,7 +2547,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(DoubleAbs, assembler) {
+  __ EnterDartFrame(0);
   __ DoubleAbs(XMM0);
+  __ LeaveFrameWithPP();
   __ ret();
 }
 
diff --git a/runtime/vm/ast.cc b/runtime/vm/ast.cc
index 2c911eb..ded8a96 100644
--- a/runtime/vm/ast.cc
+++ b/runtime/vm/ast.cc
@@ -376,6 +376,25 @@
 }
 
 
+bool ConditionalExprNode::IsPotentiallyConst() const {
+  return this->condition()->IsPotentiallyConst() &&
+    this->true_expr()->IsPotentiallyConst() &&
+    this->false_expr()->IsPotentiallyConst();
+}
+
+
+const Instance* ConditionalExprNode::EvalConstExpr() const {
+  const Instance* cond = this->condition()->EvalConstExpr();
+  if ((cond != NULL) &&
+      cond->IsBool() &&
+      (this->true_expr()->EvalConstExpr() != NULL) &&
+      (this->false_expr()->EvalConstExpr() != NULL)) {
+    return cond;
+  }
+  return NULL;
+}
+
+
 bool ClosureNode::IsPotentiallyConst() const {
   if (function().IsImplicitStaticClosureFunction()) {
     return true;
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index 2f7af98..c294eeb 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -699,6 +699,9 @@
     false_expr_ = false_expr;
   }
 
+  virtual bool IsPotentiallyConst() const;
+  virtual const Instance* EvalConstExpr() const;
+
   virtual void VisitChildren(AstNodeVisitor* visitor) const {
     condition()->Visit(visitor);
     true_expr()->Visit(visitor);
diff --git a/runtime/vm/block_scheduler.cc b/runtime/vm/block_scheduler.cc
index 2594e8a..27d2a9e 100644
--- a/runtime/vm/block_scheduler.cc
+++ b/runtime/vm/block_scheduler.cc
@@ -5,6 +5,7 @@
 #include "vm/block_scheduler.h"
 
 #include "vm/allocation.h"
+#include "vm/code_patcher.h"
 #include "vm/flow_graph.h"
 
 namespace dart {
@@ -14,25 +15,9 @@
                                  intptr_t deopt_id) {
   ASSERT(deopt_id != Isolate::kNoDeoptId);
 
-  // Intrinsified functions do not have edge counts, so give all edges equal
-  // weights.
-  if (unoptimized_code.pointer_offsets_length() == 0) return 1;
-
   uword pc = unoptimized_code.GetPcForDeoptId(deopt_id, PcDescriptors::kDeopt);
   Array& array = Array::Handle();
-  // Pointer offsets are sorted in decreasing order.  Find the first one
-  // after the deopt id's pc.
-  // TODO(kmillikin): Use a more reliable way to find the counter.
-  for (intptr_t j = unoptimized_code.pointer_offsets_length() - 1;
-       j >= 0;
-       --j) {
-    uword addr =
-        unoptimized_code.GetPointerOffsetAt(j) + unoptimized_code.EntryPoint();
-    if (addr > pc) {
-      array ^= *reinterpret_cast<RawObject**>(addr);
-      break;
-    }
-  }
+  array ^= CodePatcher::GetEdgeCounterAt(pc, unoptimized_code);
   ASSERT(!array.IsNull());
   return Smi::Value(Smi::RawCast(array.At(0)));
 }
@@ -208,7 +193,7 @@
   for (intptr_t i = block_count - 1; i >= 0; --i) {
     if (chains[i]->first->block == flow_graph()->postorder()[i]) {
       for (Link* link = chains[i]->first; link != NULL; link = link->next) {
-        flow_graph()->codegen_block_order(true)->Add(link->block);
+        flow_graph()->CodegenBlockOrder(true)->Add(link->block);
       }
     }
   }
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index f4b947c..48844b2 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -82,11 +82,11 @@
   V(JSSyntaxRegExp_getIsCaseSensitive, 1)                                      \
   V(JSSyntaxRegExp_getGroupCount, 1)                                           \
   V(JSSyntaxRegExp_ExecuteMatch, 3)                                            \
-  V(ObjectArray_allocate, 2)                                                   \
-  V(ObjectArray_getIndexed, 2)                                                 \
-  V(ObjectArray_setIndexed, 3)                                                 \
-  V(ObjectArray_getLength, 1)                                                  \
-  V(ObjectArray_copyFromObjectArray, 5)                                        \
+  V(List_allocate, 2)                                                          \
+  V(List_getIndexed, 2)                                                        \
+  V(List_setIndexed, 3)                                                        \
+  V(List_getLength, 1)                                                         \
+  V(List_copyFromObjectArray, 5)                                               \
   V(StringBase_createFromCodePoints, 1)                                        \
   V(StringBase_substringUnchecked, 3)                                          \
   V(StringBuffer_createStringFromUint16Array, 3)                               \
@@ -101,7 +101,7 @@
   V(String_concat, 2)                                                          \
   V(String_toLowerCase, 1)                                                     \
   V(String_toUpperCase, 1)                                                     \
-  V(Strings_concatAll, 1)                                                      \
+  V(Strings_concatAll, 3)                                                      \
   V(Math_sqrt, 1)                                                              \
   V(Math_sin, 1)                                                               \
   V(Math_cos, 1)                                                               \
@@ -292,13 +292,13 @@
   V(ParameterMirror_type, 2)                                                   \
   V(TypedefMirror_referent, 1)                                                 \
   V(VariableMirror_type, 1)                                                    \
-  V(GrowableObjectArray_allocate, 2)                                           \
-  V(GrowableObjectArray_getIndexed, 2)                                         \
-  V(GrowableObjectArray_setIndexed, 3)                                         \
-  V(GrowableObjectArray_getLength, 1)                                          \
-  V(GrowableObjectArray_getCapacity, 1)                                        \
-  V(GrowableObjectArray_setLength, 2)                                          \
-  V(GrowableObjectArray_setData, 2)                                            \
+  V(GrowableList_allocate, 2)                                                  \
+  V(GrowableList_getIndexed, 2)                                                \
+  V(GrowableList_setIndexed, 3)                                                \
+  V(GrowableList_getLength, 1)                                                 \
+  V(GrowableList_getCapacity, 1)                                               \
+  V(GrowableList_setLength, 2)                                                 \
+  V(GrowableList_setData, 2)                                                   \
   V(WeakProperty_new, 2)                                                       \
   V(WeakProperty_getKey, 1)                                                    \
   V(WeakProperty_getValue, 1)                                                  \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index dff2717..b5c6103 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -337,7 +337,7 @@
     // Replace the type with a malformed type and compile a throw when called.
     type = NewFinalizedMalformedType(
         Error::Handle(),  // No previous error.
-        cls,
+        Script::Handle(cls.script()),
         factory.token_pos(),
         "factory may not redirect to 'dynamic'");
     factory.SetRedirectionType(type);
@@ -364,7 +364,7 @@
     // Replace the type with a malformed type and compile a throw when called.
     type = NewFinalizedMalformedType(
         Error::Handle(),  // No previous error.
-        cls,
+        Script::Handle(target_class.script()),
         factory.token_pos(),
         "class '%s' has no constructor or factory named '%s'",
         target_class_name.ToCString(),
@@ -378,8 +378,9 @@
     // Verify that the target is compatible with the redirecting factory.
     Error& error = Error::Handle();
     if (!target.HasCompatibleParametersWith(factory, &error)) {
+      const Script& script = Script::Handle(target_class.script());
       type = NewFinalizedMalformedType(
-          error, target_class, target.token_pos(),
+          error, script, target.token_pos(),
           "constructor '%s' has incompatible parameters with "
           "redirecting factory '%s'",
           String::Handle(target.name()).ToCString(),
@@ -428,7 +429,8 @@
       if (malformed_error.IsNull()) {
         target_type ^= FinalizeType(cls, target_type, kCanonicalize);
       } else {
-        FinalizeMalformedType(malformed_error, cls, target_type,
+        const Script& script = Script::Handle(target_class.script());
+        FinalizeMalformedType(malformed_error, script, target_type,
                               "cannot resolve redirecting factory");
         target_target = Function::null();
       }
@@ -471,7 +473,7 @@
         // The type class could not be resolved. The type is malformed.
         FinalizeMalformedType(
             Error::Handle(),  // No previous error.
-            cls,
+            Script::Handle(cls.script()),
             parameterized_type,
             "cannot resolve class '%s' from '%s'",
             String::Handle(unresolved_class.Name()).ToCString(),
@@ -908,7 +910,7 @@
         parameterized_type.UserVisibleName());
     const Type& malformed_bound = Type::Handle(
         NewFinalizedMalformedType(bound_error,
-                                  cls,
+                                  Script::Handle(cls.script()),
                                   parameterized_type.token_pos(),
                                   "type '%s' has an out of bound type argument",
                                   parameterized_type_name.ToCString()));
@@ -2460,12 +2462,11 @@
 
 // Either report an error or mark the type as malformed.
 void ClassFinalizer::ReportMalformedType(const Error& prev_error,
-                                         const Class& cls,
+                                         const Script& script,
                                          const Type& type,
                                          const char* format,
                                          va_list args) {
   LanguageError& error = LanguageError::Handle();
-  const Script& script = Script::Handle(cls.script());
   if (prev_error.IsNull()) {
     error ^= Parser::FormatError(
         script, type.token_pos(), "Error", format, args);
@@ -2493,7 +2494,7 @@
 
 
 RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error,
-                                                   const Class& cls,
+                                                   const Script& script,
                                                    intptr_t type_pos,
                                                    const char* format, ...) {
   va_list args;
@@ -2504,7 +2505,7 @@
                            type_pos));
   const Type& type = Type::Handle(
       Type::New(unresolved_class, TypeArguments::Handle(), type_pos));
-  ReportMalformedType(prev_error, cls, type, format, args);
+  ReportMalformedType(prev_error, script, type, format, args);
   va_end(args);
   ASSERT(type.IsMalformed());
   ASSERT(type.IsFinalized());
@@ -2513,12 +2514,12 @@
 
 
 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error,
-                                           const Class& cls,
+                                           const Script& script,
                                            const Type& type,
                                            const char* format, ...) {
   va_list args;
   va_start(args, format);
-  ReportMalformedType(prev_error, cls, type, format, args);
+  ReportMalformedType(prev_error, script, type, format, args);
   va_end(args);
 }
 
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index e2689d0..cc94684 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -52,7 +52,7 @@
   // If not null, prepend prev_error to the error message built from the format
   // string and its arguments.
   static RawType* NewFinalizedMalformedType(const Error& prev_error,
-                                            const Class& cls,
+                                            const Script& script,
                                             intptr_t type_pos,
                                             const char* format, ...)
        PRINTF_ATTRIBUTE(4, 5);
@@ -62,7 +62,7 @@
   // If not null, prepend prev_error to the error message built from the format
   // string and its arguments.
   static void FinalizeMalformedType(const Error& prev_error,
-                                    const Class& cls,
+                                    const Script& script,
                                     const Type& type,
                                     const char* format, ...)
        PRINTF_ATTRIBUTE(4, 5);
@@ -145,7 +145,7 @@
   static void CollectInterfaces(const Class& cls,
                                 const GrowableObjectArray& interfaces);
   static void ReportMalformedType(const Error& prev_error,
-                                  const Class& cls,
+                                  const Script& script,
                                   const Type& type,
                                   const char* format,
                                   va_list args);
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 9bfd2a5..162e702 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1494,8 +1494,9 @@
 }
 
 
-// Copy saved registers into the isolate buffer.
-static void CopySavedRegisters(uword saved_registers_address) {
+static void CopySavedRegisters(uword saved_registers_address,
+                               fpu_register_t** fpu_registers,
+                               intptr_t** cpu_registers) {
   ASSERT(sizeof(fpu_register_t) == kFpuRegisterSize);
   fpu_register_t* fpu_registers_copy =
       new fpu_register_t[kNumberOfFpuRegisters];
@@ -1505,7 +1506,7 @@
         *reinterpret_cast<fpu_register_t*>(saved_registers_address);
     saved_registers_address += kFpuRegisterSize;
   }
-  Isolate::Current()->set_deopt_fpu_registers_copy(fpu_registers_copy);
+  *fpu_registers = fpu_registers_copy;
 
   ASSERT(sizeof(intptr_t) == kWordSize);
   intptr_t* cpu_registers_copy = new intptr_t[kNumberOfCpuRegisters];
@@ -1515,14 +1516,16 @@
         *reinterpret_cast<intptr_t*>(saved_registers_address);
     saved_registers_address += kWordSize;
   }
-  Isolate::Current()->set_deopt_cpu_registers_copy(cpu_registers_copy);
+  *cpu_registers = cpu_registers_copy;
 }
 
 
-// Copy optimized frame into the isolate buffer.
-// The first incoming argument is stored at the last entry in the
-// copied frame buffer.
-static void CopyFrame(const Code& optimized_code, const StackFrame& frame) {
+// Copy optimized frame. The first incoming argument is stored at the
+// last entry in the copied frame buffer.
+static void CopyFrame(const Code& optimized_code,
+                      const StackFrame& frame,
+                      intptr_t** frame_start,
+                      intptr_t* frame_size) {
   const Function& function = Function::Handle(optimized_code.function());
   // Do not copy incoming arguments if there are optional arguments (they
   // are copied into local space at method entry).
@@ -1545,7 +1548,8 @@
   for (intptr_t i = 0; i < frame_copy_size; i++) {
     frame_copy[i] = *(start + i);
   }
-  Isolate::Current()->SetDeoptFrameCopy(frame_copy, frame_copy_size);
+  *frame_start = frame_copy;
+  *frame_size = frame_copy_size;
 }
 
 
@@ -1562,7 +1566,6 @@
                         + (kNumberOfCpuRegisters * kWordSize)
                         + (kNumberOfFpuRegisters * kFpuRegisterSize)
                         - ((kFirstLocalSlotFromFp + 1) * kWordSize);
-  CopySavedRegisters(saved_registers_address);
 
   // Get optimized code and frame that need to be deoptimized.
   DartFrameIterator iterator(last_fp);
@@ -1576,9 +1579,28 @@
       optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason));
   ASSERT(!deopt_info.IsNull());
 
-  CopyFrame(optimized_code, *caller_frame);
+  // Create the DeoptContext for this deoptimization.  Store in isolate.
+  const Function& function = Function::Handle(optimized_code.function());
+  const intptr_t num_args =
+      function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
+  DeoptContext* deopt_context = new DeoptContext(
+      Array::Handle(optimized_code.object_table()),
+      num_args,
+      static_cast<DeoptReasonId>(deopt_reason));
+  isolate->set_deopt_context(deopt_context);
+
+  // Copy the saved registers and the source frame.
+  fpu_register_t* fpu_registers;
+  intptr_t* cpu_registers;
+  intptr_t* frame_start;
+  intptr_t frame_size;
+  CopySavedRegisters(saved_registers_address, &fpu_registers, &cpu_registers);
+  CopyFrame(optimized_code, *caller_frame, &frame_start, &frame_size);
+  deopt_context->SetSourceArgs(frame_start, frame_size,
+                               fpu_registers, cpu_registers,
+                               true);  // true = source frame is a copy.
+
   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",
         deopt_reason,
@@ -1591,9 +1613,6 @@
   // Compute the stack size of the unoptimized frame.  For functions with
   // optional arguments the deoptimization info does not describe the
   // incoming arguments.
-  const Function& function = Function::Handle(optimized_code.function());
-  const intptr_t num_args =
-      function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
   const intptr_t unoptimized_stack_size =
       + deopt_info.FrameSize()
       - kDartFrameFixedSize
@@ -1605,10 +1624,10 @@
 END_LEAF_RUNTIME_ENTRY
 
 
-static void DeoptimizeWithDeoptInfo(const Code& code,
+static void DeoptimizeWithDeoptInfo(DeoptContext* deopt_context,
+                                    const Code& code,
                                     const DeoptInfo& deopt_info,
-                                    const StackFrame& caller_frame,
-                                    intptr_t deopt_reason) {
+                                    const StackFrame& caller_frame) {
   const intptr_t len = deopt_info.TranslationLength();
   GrowableArray<DeoptInstr*> deopt_instructions(len);
   const Array& deopt_table = Array::Handle(code.deopt_info_array());
@@ -1626,11 +1645,9 @@
       + 1  // For fp.
       + kParamEndSlotFromFp
       + num_args;
-  DeoptimizationContext deopt_context(start,
-                                      to_frame_size,
-                                      Array::Handle(code.object_table()),
-                                      num_args,
-                                      static_cast<DeoptReasonId>(deopt_reason));
+
+  deopt_context->SetDestArgs(start, to_frame_size);
+
   const intptr_t frame_size = deopt_info.FrameSize();
 
   // All kMaterializeObject instructions are emitted before the instructions
@@ -1642,15 +1659,15 @@
   // frame. They will be used during materialization and removed from the stack
   // right before control switches to the unoptimized code.
   const intptr_t num_materializations = len - frame_size;
-  Isolate::Current()->PrepareForDeferredMaterialization(num_materializations);
+  deopt_context->PrepareForDeferredMaterialization(num_materializations);
   for (intptr_t from_index = 0, to_index = kDartFrameFixedSize;
        from_index < num_materializations;
        from_index++) {
     const intptr_t field_count =
         DeoptInstr::GetFieldCount(deopt_instructions[from_index]);
-    intptr_t* args = deopt_context.GetToFrameAddressAt(to_index);
+    intptr_t* args = deopt_context->GetDestFrameAddressAt(to_index);
     DeferredObject* obj = new DeferredObject(field_count, args);
-    Isolate::Current()->SetDeferredObjectAt(from_index, obj);
+    deopt_context->SetDeferredObjectAt(from_index, obj);
     to_index += obj->ArgumentCount();
   }
 
@@ -1658,8 +1675,8 @@
   for (intptr_t to_index = frame_size - 1, from_index = len - 1;
        to_index >= 0;
        to_index--, from_index--) {
-    intptr_t* to_addr = deopt_context.GetToFrameAddressAt(to_index);
-    deopt_instructions[from_index]->Execute(&deopt_context, to_addr);
+    intptr_t* to_addr = deopt_context->GetDestFrameAddressAt(to_index);
+    deopt_instructions[from_index]->Execute(deopt_context, to_addr);
   }
 
   if (FLAG_trace_deoptimization_verbose) {
@@ -1691,26 +1708,16 @@
   ASSERT(!optimized_code.IsNull() && optimized_code.is_optimized());
   ASSERT(!unoptimized_code.IsNull() && !unoptimized_code.is_optimized());
 
-  intptr_t* frame_copy = isolate->deopt_frame_copy();
-  intptr_t* cpu_registers_copy = isolate->deopt_cpu_registers_copy();
-  fpu_register_t* fpu_registers_copy = isolate->deopt_fpu_registers_copy();
-
   intptr_t deopt_reason = kDeoptUnknown;
   const DeoptInfo& deopt_info = DeoptInfo::Handle(
       optimized_code.GetDeoptInfoAtPc(caller_frame->pc(), &deopt_reason));
   ASSERT(!deopt_info.IsNull());
 
-  DeoptimizeWithDeoptInfo(optimized_code,
+  DeoptContext* deopt_context = isolate->deopt_context();
+  DeoptimizeWithDeoptInfo(deopt_context,
+                          optimized_code,
                           deopt_info,
-                          *caller_frame,
-                          deopt_reason);
-
-  isolate->SetDeoptFrameCopy(NULL, 0);
-  isolate->set_deopt_cpu_registers_copy(NULL);
-  isolate->set_deopt_fpu_registers_copy(NULL);
-  delete[] frame_copy;
-  delete[] cpu_registers_copy;
-  delete[] fpu_registers_copy;
+                          *caller_frame);
 }
 END_LEAF_RUNTIME_ENTRY
 
@@ -1721,25 +1728,15 @@
 // under return address to keep them discoverable by GC that can occur during
 // materialization phase.
 DEFINE_RUNTIME_ENTRY(DeoptimizeMaterialize, 0) {
-  // First materialize all unboxed "primitive" values (doubles, mints, simd)
-  // then materialize objects. The order is important: objects might be
-  // referencing boxes allocated on the first step. At the same time
-  // objects can't be referencing other deferred objects because storing
-  // an object into a field is always conservatively treated as escaping by
-  // allocation sinking and load forwarding.
-  isolate->MaterializeDeferredBoxes();
-  isolate->MaterializeDeferredObjects();
+  DeoptContext* deopt_context = isolate->deopt_context();
 
-  // Compute total number of artificial arguments used during deoptimization.
-  intptr_t deopt_arguments = 0;
-  for (intptr_t i = 0; i < isolate->DeferredObjectsCount(); i++) {
-    deopt_arguments += isolate->GetDeferredObject(i)->ArgumentCount();
-  }
-  Isolate::Current()->DeleteDeferredObjects();
+  intptr_t deopt_arg_count = deopt_context->MaterializeDeferredObjects();
+  isolate->set_deopt_context(NULL);
+  delete deopt_context;
 
   // Return value tells deoptimization stub to remove the given number of bytes
   // from the stack.
-  arguments.SetReturn(Smi::Handle(Smi::New(deopt_arguments * kWordSize)));
+  arguments.SetReturn(Smi::Handle(Smi::New(deopt_arg_count * kWordSize)));
 
   // Since this is the only step where GC can occur during deoptimization,
   // use it to report the source line where deoptimization occured.
@@ -1756,7 +1753,7 @@
     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("  Deopt args: %" Pd "\n", deopt_arg_count);
   }
 }
 
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index fea3ba4..9294e0e 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -19,6 +19,7 @@
 class RawArray;
 class RawFunction;
 class RawICData;
+class RawObject;
 class String;
 
 class CodePatcher : public AllStatic {
@@ -70,6 +71,8 @@
   static intptr_t InstanceCallSizeInBytes();
 
   static void InsertCallAt(uword start, uword target);
+
+  static RawObject* GetEdgeCounterAt(uword pc, const Code& code);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc
index 105d3a1..759bf54 100644
--- a/runtime/vm/code_patcher_arm.cc
+++ b/runtime/vm/code_patcher_arm.cc
@@ -84,6 +84,47 @@
   return ic_data.GetTargetAt(0);
 }
 
+
+// This class pattern matches on a load from the object pool.  Loading on
+// ARM is complicated because it can take four possible different forms.  We
+// match backwards from the end of the sequence so we can reuse the code for
+// matching object pool loads at calls.
+class EdgeCounter : public ValueObject {
+ public:
+  EdgeCounter(uword pc, const Code& code)
+      : end_(pc - kAdjust), object_pool_(Array::Handle(code.ObjectPool())) {
+    // An IsValid predicate is complicated and duplicates the code in the
+    // decoding function.  Instead we rely on decoding the pattern which
+    // will assert partial validity.
+  }
+
+  RawObject* edge_counter() const {
+    Register ignored;
+    intptr_t index;
+    InstructionPattern::DecodeLoadWordFromPool(end_, &ignored, &index);
+    ASSERT(ignored == R0);
+    return object_pool_.At(index);
+  }
+
+ private:
+  // The object pool load is followed by the fixed-size edge counter
+  // incrementing code:
+  //     ldr ip, [r0, #+11]
+  //     adds ip, ip, #2
+  //     str ip, [r0, #+11]
+  static const intptr_t kAdjust = 3 * Instr::kInstrSize;
+
+  uword end_;
+  const Array& object_pool_;
+};
+
+
+RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  EdgeCounter counter(pc, code);
+  return counter.edge_counter();
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index 9cccd56..8143d69 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -149,7 +149,7 @@
 };
 
 
-// The expected pattern of a dart closure call:
+// The expected pattern of a Dart closure call:
 //   mov EDX, arguments_descriptor_array
 //   call target_address
 //   <- return address
@@ -259,6 +259,39 @@
   return InstanceCall::kNumInstructions * InstanceCall::kInstructionSize;
 }
 
+
+// The expected code pattern of an edge counter in unoptimized code:
+//  b8 imm32    mov EAX, immediate
+class EdgeCounter : public ValueObject {
+ public:
+  EdgeCounter(uword pc, const Code& ignored) : end_(pc - kAdjust) {
+    ASSERT(IsValid(end_));
+  }
+
+  static bool IsValid(uword end) {
+    return (*reinterpret_cast<uint8_t*>(end - 5) == 0xb8);
+  }
+
+  RawObject* edge_counter() const {
+    return *reinterpret_cast<RawObject**>(end_ - 4);
+  }
+
+ private:
+  // The edge counter load is followed by the fixed-size edge counter
+  // incrementing code:
+  //     83 40 0b 02               add [eax+0xb],0x2
+  static const intptr_t kAdjust = 4;
+
+  uword end_;
+};
+
+
+RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  EdgeCounter counter(pc, code);
+  return counter.edge_counter();
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/code_patcher_mips.cc b/runtime/vm/code_patcher_mips.cc
index f25b460..7a84596 100644
--- a/runtime/vm/code_patcher_mips.cc
+++ b/runtime/vm/code_patcher_mips.cc
@@ -84,6 +84,47 @@
   return ic_data.GetTargetAt(0);
 }
 
+
+// This class pattern matches on a load from the object pool.  Loading on
+// MIPS is complicated because it can take four possible different forms.
+// We match backwards from the end of the sequence so we can reuse the code
+// for matching object pool loads at calls.
+class EdgeCounter : public ValueObject {
+ public:
+  EdgeCounter(uword pc, const Code& code)
+      : end_(pc - kAdjust), object_pool_(Array::Handle(code.ObjectPool())) {
+    // An IsValid predicate is complicated and duplicates the code in the
+    // decoding function.  Instead we rely on decoding the pattern which
+    // will assert partial validity.
+  }
+
+  RawObject* edge_counter() const {
+    Register ignored;
+    intptr_t index;
+    InstructionPattern::DecodeLoadWordFromPool(end_, &ignored, &index);
+    ASSERT(ignored == T0);
+    return object_pool_.At(index);
+  }
+
+ private:
+  // The object pool load is followed by the fixed-size edge counter
+  // incrementing code:
+  //     lw r9, 11(r8)
+  //     addiu r9, r9, 2
+  //     sw r9, 11(r8)
+  static const intptr_t kAdjust = 3 * Instr::kInstrSize;
+
+  uword end_;
+  const Array& object_pool_;
+};
+
+
+RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  EdgeCounter counter(pc, code);
+  return counter.edge_counter();
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index 5782527..0de7bd6 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -142,7 +142,7 @@
 };
 
 
-// The expected code pattern of a dart closure call:
+// The expected code pattern of a Dart closure call:
 //  00: 49 ba imm64     mov R10, immediate 2      ; 10 bytes
 //  10: 4d 8b 9f imm32  mov R11, [PP + off]
 //  17: 41 ff d3        call R11                  ; 3 bytes
@@ -248,6 +248,42 @@
   return ic_data.GetTargetAt(0);
 }
 
+
+// The expected code pattern of an edge counter in unoptimized code:
+//  49 8b 87 imm32    mov RAX, [PP + offset]
+class EdgeCounter : public ValueObject {
+ public:
+  EdgeCounter(uword pc, const Code& code)
+      : end_(pc - kAdjust), object_pool_(Array::Handle(code.ObjectPool())) {
+    ASSERT(IsValid(end_));
+  }
+
+  static bool IsValid(uword end) {
+    uint8_t* bytes = reinterpret_cast<uint8_t*>(end - 7);
+    return (bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x87);
+  }
+
+  RawObject* edge_counter() const {
+    return object_pool_.At(InstructionPattern::IndexFromPPLoad(end_ - 4));
+  }
+
+ private:
+  // The edge counter load is followed by the fixed-size edge counter
+  // incrementing code:
+  //     48 83 40 17 02             addq [rax+0x17],0x2
+  static const intptr_t kAdjust = 5;
+
+  uword end_;
+  const Array& object_pool_;
+};
+
+
+RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) {
+  ASSERT(code.ContainsInstructionAt(pc));
+  EdgeCounter counter(pc, code);
+  return counter.edge_counter();
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_X64
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index d9f1a53..5a9ff9d 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -307,7 +307,9 @@
       }
 
       BlockScheduler block_scheduler(flow_graph);
-      if (optimized && FLAG_reorder_basic_blocks) {
+      const bool reorder_blocks =
+          FlowGraph::ShouldReorderBlocks(function, optimized);
+      if (reorder_blocks) {
         block_scheduler.AssignEdgeWeights();
       }
 
@@ -508,7 +510,7 @@
         // Perform register allocation on the SSA graph.
         FlowGraphAllocator allocator(*flow_graph);
         allocator.AllocateRegisters();
-        if (FLAG_reorder_basic_blocks) block_scheduler.ReorderBlocks();
+        if (reorder_blocks) block_scheduler.ReorderBlocks();
 
         if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
           FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
@@ -739,8 +741,8 @@
     TIMERSCOPE(time_compilation);
     Timer per_compile_timer(FLAG_trace_compiler, "Compilation time");
     per_compile_timer.Start();
-    ParsedFunction* parsed_function = new ParsedFunction(
-        Function::ZoneHandle(function.raw()));
+    ParsedFunction* parsed_function =
+        new ParsedFunction(Function::ZoneHandle(function.raw()));
     if (FLAG_trace_compiler) {
       OS::Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n",
                 (osr_id == Isolate::kNoDeoptId ? "" : "osr "),
diff --git a/runtime/vm/coverage.cc b/runtime/vm/coverage.cc
index 5d284d2..56733f4 100644
--- a/runtime/vm/coverage.cc
+++ b/runtime/vm/coverage.cc
@@ -6,6 +6,7 @@
 
 #include "include/dart_api.h"
 
+#include "vm/compiler.h"
 #include "vm/isolate.h"
 #include "vm/json_stream.h"
 #include "vm/object.h"
@@ -16,64 +17,105 @@
 DEFINE_FLAG(charp, coverage_dir, NULL,
             "Enable writing coverage data into specified directory.");
 
+
+void CodeCoverage::CompileAndAdd(const Function& function,
+                                 const JSONArray& hits_arr) {
+  if (!function.HasCode()) {
+    if (Compiler::CompileFunction(function) != Error::null()) {
+      return;
+    }
+  }
+  ASSERT(function.HasCode());
+
+  Isolate* isolate = Isolate::Current();
+  // Print the hit counts for all IC datas.
+  const Script& script = Script::Handle(function.script());
+  const Code& code = Code::Handle(function.unoptimized_code());
+  const Array& ic_array = Array::Handle(code.ExtractTypeFeedbackArray());
+  const PcDescriptors& descriptors = PcDescriptors::Handle(
+      code.pc_descriptors());
+  ICData& ic_data = ICData::Handle();
+
+  for (int j = 0; j < descriptors.Length(); j++) {
+    HANDLESCOPE(isolate);
+    PcDescriptors::Kind kind = descriptors.DescriptorKind(j);
+    // Only IC based calls have counting.
+    if ((kind == PcDescriptors::kIcCall) ||
+        (kind == PcDescriptors::kUnoptStaticCall)) {
+      intptr_t deopt_id = descriptors.DeoptId(j);
+      ic_data ^= ic_array.At(deopt_id);
+      if (!ic_data.IsNull()) {
+        intptr_t token_pos = descriptors.TokenPos(j);
+        intptr_t line = -1;
+        script.GetTokenLocation(token_pos, &line, NULL);
+        hits_arr.AddValue(line);
+        hits_arr.AddValue(ic_data.AggregateCount());
+      }
+    }
+  }
+}
+
+
 void CodeCoverage::PrintClass(const Class& cls, const JSONArray& jsarr) {
-  const Array& functions = Array::Handle(cls.functions());
+  Isolate* isolate = Isolate::Current();
+  Array& functions = Array::Handle(cls.functions());
   ASSERT(!functions.IsNull());
   Function& function = Function::Handle();
-  Code& code = Code::Handle();
   Script& script = Script::Handle();
+  String& saved_url = String::Handle();
   String& url = String::Handle();
-  String& name = String::Handle();
-  PcDescriptors& descriptors = PcDescriptors::Handle();
-  Array& ic_array = Array::Handle();
-  ICData& ic_data = ICData::Handle();
-  for (int i = 0; i < functions.Length(); i++) {
-    function ^= functions.At(i);
 
+  int i = 0;
+  while (i < functions.Length()) {
+    HANDLESCOPE(isolate);
+    function ^= functions.At(i);
     JSONObject jsobj(&jsarr);
     script = function.script();
-    url = script.url();
-    name = function.QualifiedUserVisibleName();
-    jsobj.AddProperty("source", url.ToCString());
-    jsobj.AddProperty("function", name.ToCString());
+    saved_url = script.url();
+    jsobj.AddProperty("source", saved_url.ToCString());
+    JSONArray hits_arr(&jsobj, "hits");
 
-    JSONArray jsarr(&jsobj, "hits");
-
-    if (function.HasCode()) {
-      // Print the hit counts for all IC datas.
-      code = function.unoptimized_code();
-      ic_array = code.ExtractTypeFeedbackArray();
-      descriptors = code.pc_descriptors();
-
-      for (int j = 0; j < descriptors.Length(); j++) {
-        PcDescriptors::Kind kind = descriptors.DescriptorKind(j);
-        // Only IC based calls have counting.
-        if ((kind == PcDescriptors::kIcCall) ||
-            (kind == PcDescriptors::kUnoptStaticCall)) {
-          intptr_t deopt_id = descriptors.DeoptId(j);
-          ic_data ^= ic_array.At(deopt_id);
-          if (!ic_data.IsNull()) {
-            intptr_t token_pos = descriptors.TokenPos(j);
-            intptr_t line = -1;
-            intptr_t col = -1;
-            script.GetTokenLocation(token_pos, &line, &col);
-            JSONObject ic_info(&jsarr);
-            ic_info.AddProperty("line", line);
-            ic_info.AddProperty("col", col);
-            ic_info.AddProperty("count", ic_data.AggregateCount());
-          }
-        }
+    // We stay within this loop while we are seeing functions from the same
+    // source URI.
+    while (i < functions.Length()) {
+      function ^= functions.At(i);
+      script = function.script();
+      url = script.url();
+      if (!url.Equals(saved_url)) {
+        break;
       }
-    } else {
-      // The function has no code so it was never executed and thus we add one
-      // zero count hit at the first token index.
-      intptr_t line = -1;
-      intptr_t col = -1;
-      script.GetTokenLocation(function.token_pos(), &line, &col);
-      JSONObject func_info(&jsarr);
-      func_info.AddProperty("line", line);
-      func_info.AddProperty("col", col);
-      func_info.AddProperty("count", static_cast<intptr_t>(0));
+      CompileAndAdd(function, hits_arr);
+      i++;
+    }
+  }
+
+  GrowableObjectArray& closures =
+      GrowableObjectArray::Handle(cls.closures());
+  if (!closures.IsNull()) {
+    i = 0;
+    // We need to keep rechecking the length of the closures array, as handling
+    // a closure potentially adds new entries to the end.
+    while (i < closures.Length()) {
+      HANDLESCOPE(isolate);
+      function ^= closures.At(i);
+      JSONObject jsobj(&jsarr);
+      script = function.script();
+      saved_url = script.url();
+      jsobj.AddProperty("source", saved_url.ToCString());
+      JSONArray hits_arr(&jsobj, "hits");
+
+      // We stay within this loop while we are seeing functions from the same
+      // source URI.
+      while (i < closures.Length()) {
+        function ^= closures.At(i);
+        script = function.script();
+        url = script.url();
+        if (!url.Equals(saved_url)) {
+          break;
+        }
+        CompileAndAdd(function, hits_arr);
+        i++;
+      }
     }
   }
 }
@@ -103,7 +145,7 @@
       ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
       while (it.HasNext()) {
         cls = it.GetNextClass();
-        if (cls.is_finalized()) {
+        if (cls.EnsureIsFinalized(isolate) == Error::null()) {
           // Only classes that have been finalized do have a meaningful list of
           // functions.
           PrintClass(cls, jsarr);
diff --git a/runtime/vm/coverage.h b/runtime/vm/coverage.h
index ef7ee82..0c17bda 100644
--- a/runtime/vm/coverage.h
+++ b/runtime/vm/coverage.h
@@ -14,6 +14,7 @@
 
 // Forward declarations.
 class Class;
+class Function;
 class Isolate;
 class JSONArray;
 
@@ -23,6 +24,8 @@
 
  private:
   static void PrintClass(const Class& cls, const JSONArray& arr);
+  static void CompileAndAdd(const Function& function,
+                            const JSONArray& hits_arr);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 7a6bc66..680476e 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -2834,12 +2834,14 @@
   }
 
   // Get the class to instantiate.
-  const Type& type_obj = Api::UnwrapTypeHandle(isolate, type);
-  if (type_obj.IsNull()) {
+  Object& unchecked_type = Object::Handle(Api::UnwrapHandle(type));
+  if (unchecked_type.IsNull() || !unchecked_type.IsType()) {
     RETURN_TYPE_ERROR(isolate, type, Type);
   }
+  Type& type_obj = Type::Handle();
+  type_obj ^= unchecked_type.raw();
   Class& cls = Class::Handle(isolate, type_obj.type_class());
-  const AbstractTypeArguments& type_arguments =
+  AbstractTypeArguments& type_arguments =
       AbstractTypeArguments::Handle(isolate, type_obj.arguments());
 
   const String& base_constructor_name = String::Handle(isolate, cls.Name());
@@ -2877,13 +2879,28 @@
   Instance& new_object = Instance::Handle(isolate);
   if (constructor.IsRedirectingFactory()) {
     ClassFinalizer::ResolveRedirectingFactory(cls, constructor);
-    const Type& type = Type::Handle(constructor.RedirectionType());
+    Type& redirect_type = Type::Handle(constructor.RedirectionType());
     constructor = constructor.RedirectionTarget();
     if (constructor.IsNull()) {
-      ASSERT(type.IsMalformed());
-      return Api::NewHandle(isolate, type.malformed_error());
+      ASSERT(redirect_type.IsMalformed());
+      return Api::NewHandle(isolate, redirect_type.malformed_error());
     }
-    cls = type.type_class();
+
+    if (!redirect_type.IsInstantiated()) {
+      // The type arguments of the redirection type are instantiated from the
+      // type arguments of the type argument.
+      Error& malformed_error = Error::Handle();
+      redirect_type ^= redirect_type.InstantiateFrom(type_arguments,
+                                                     &malformed_error);
+      if (!malformed_error.IsNull()) {
+        return Api::NewHandle(isolate, malformed_error.raw());
+      }
+    }
+
+    type_obj = redirect_type.raw();
+    type_arguments = redirect_type.arguments();
+
+    cls = type_obj.type_class();
   }
   if (constructor.IsConstructor()) {
     // Create the new object.
@@ -3613,7 +3630,7 @@
   CHECK_ISOLATE(isolate);
   ReusableObjectHandleScope reused_obj_handle(isolate);
   Object& obj = reused_obj_handle.Handle();
-  obj = arguments->NativeArgAt(0);
+  obj = arguments->NativeArg0();
   intptr_t cid = obj.GetClassId();
   if (cid <= kNumPredefinedCids) {
     if (cid == kNullCid) {
@@ -4208,9 +4225,9 @@
 }
 
 
-DART_EXPORT Dart_Handle Dart_LoadPatch(Dart_Handle library,
-                                       Dart_Handle url,
-                                       Dart_Handle patch_source) {
+DART_EXPORT Dart_Handle Dart_LibraryLoadPatch(Dart_Handle library,
+                                              Dart_Handle url,
+                                              Dart_Handle patch_source) {
   TIMERSCOPE(time_script_loading);
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index e5fce0d..aa860ea 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -2711,19 +2711,6 @@
 }
 
 
-#define CHECK_CLASS(handle, name)                                              \
-  {                                                                            \
-    Dart_Handle tmp = (handle);                                                \
-    EXPECT_VALID(tmp);                                                         \
-    EXPECT(Dart_IsClass(tmp));                                                 \
-    Dart_Handle intf_name = Dart_TypeName(tmp);                                \
-    EXPECT_VALID(intf_name);                                                   \
-    const char* intf_name_cstr = "";                                           \
-    EXPECT_VALID(Dart_StringToCString(intf_name, &intf_name_cstr));            \
-    EXPECT_STREQ((name), intf_name_cstr);                                      \
-  }
-
-
 TEST_CASE(TypeGetNonParamtericTypes) {
   const char* kScriptChars =
       "class MyClass0 {\n"
@@ -5258,7 +5245,7 @@
   url = NewString("patch_url");
   source = NewString(kPatchChars);
 
-  result = Dart_LoadPatch(lib, url, source);
+  result = Dart_LibraryLoadPatch(lib, url, source);
   EXPECT_VALID(result);
 
   result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 66930ed..c085f5c 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1595,6 +1595,9 @@
   if (!IsDebuggable(func)) {
     return;
   }
+  if (frame->TokenPos() == Scanner::kDummyTokenIndex) {
+    return;
+  }
 
   if (FLAG_verbose_debug) {
     OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n",
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 130decd..3ffff4a 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -507,6 +507,7 @@
                          CURRENT_FUNC);
   }
   UNWRAP_AND_CHECK_PARAM(String, expr, expr_in);
+  // Type extends Instance, must check first.
   if (target.IsType()) {
     const Class& cls = Class::Handle(isolate, Type::Cast(target).type_class());
     return Api::NewHandle(isolate, cls.Evaluate(expr));
@@ -514,6 +515,8 @@
     return Api::NewHandle(isolate, Instance::Cast(target).Evaluate(expr));
   } else if (target.IsLibrary()) {
     return Api::NewHandle(isolate, Library::Cast(target).Evaluate(expr));
+  } else if (target.IsClass()) {
+    return Api::NewHandle(isolate, Class::Cast(target).Evaluate(expr));
   }
   return Api::NewError("%s: unsupported target type", CURRENT_FUNC);
 }
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index d73e812..5bd2084 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -1583,14 +1583,16 @@
   EXPECT(Dart_IsNumber(len));
   EXPECT_EQ(3, ToInt64(len));
 
-  Dart_Handle point_class = Dart_GetClass(script_lib, NewString("Point"));
-  EXPECT_VALID(point_class);
-  Dart_Handle elem = Dart_EvaluateExpr(point_class, NewString("m['\"']"));
+  Dart_Handle point_type =
+      Dart_GetType(script_lib, NewString("Point"), 0, NULL);
+  EXPECT_VALID(point_type);
+  EXPECT(Dart_IsType(point_type));
+  Dart_Handle elem = Dart_EvaluateExpr(point_type, NewString("m['\"']"));
   EXPECT_VALID(elem);
   EXPECT(Dart_IsString(elem));
   EXPECT_STREQ("quote", ToCString(elem));
 
-  elem = Dart_EvaluateExpr(point_class, NewString("m[\"\\t\"]"));
+  elem = Dart_EvaluateExpr(point_type, NewString("m[\"\\t\"]"));
   EXPECT_VALID(elem);
   EXPECT(Dart_IsString(elem));
   EXPECT_STREQ("tab", ToCString(elem));
@@ -1617,6 +1619,10 @@
   EXPECT_VALID(len);
   EXPECT(Dart_IsNumber(len));
   EXPECT_EQ(6, ToInt64(len));
+
+  Dart_Handle error =
+      Dart_EvaluateExpr(script_lib, NewString("new NonexistingType()"));
+  EXPECT(Dart_IsError(error));
 }
 
 
diff --git a/runtime/vm/deferred_objects.cc b/runtime/vm/deferred_objects.cc
new file mode 100644
index 0000000..76f5be7
--- /dev/null
+++ b/runtime/vm/deferred_objects.cc
@@ -0,0 +1,127 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/deferred_objects.h"
+
+#include "vm/deopt_instructions.h"
+#include "vm/flags.h"
+#include "vm/object.h"
+
+namespace dart {
+
+DECLARE_FLAG(bool, trace_deoptimization_verbose);
+
+
+void DeferredDouble::Materialize() {
+  RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot());
+  *double_slot = Double::New(value());
+
+  if (FLAG_trace_deoptimization_verbose) {
+    OS::PrintErr("materializing double at %" Px ": %g\n",
+                 reinterpret_cast<uword>(slot()), value());
+  }
+}
+
+
+void DeferredMint::Materialize() {
+  RawMint** mint_slot = reinterpret_cast<RawMint**>(slot());
+  ASSERT(!Smi::IsValid64(value()));
+  Mint& mint = Mint::Handle();
+  mint ^= Integer::New(value());
+  *mint_slot = mint.raw();
+
+  if (FLAG_trace_deoptimization_verbose) {
+    OS::PrintErr("materializing mint at %" Px ": %" Pd64 "\n",
+                 reinterpret_cast<uword>(slot()), value());
+  }
+}
+
+
+void DeferredFloat32x4::Materialize() {
+  RawFloat32x4** float32x4_slot = reinterpret_cast<RawFloat32x4**>(slot());
+  RawFloat32x4* raw_float32x4 = Float32x4::New(value());
+  *float32x4_slot = raw_float32x4;
+
+  if (FLAG_trace_deoptimization_verbose) {
+    float x = raw_float32x4->x();
+    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",
+                 reinterpret_cast<uword>(slot()), x, y, z, w);
+  }
+}
+
+
+void DeferredUint32x4::Materialize() {
+  RawUint32x4** uint32x4_slot = reinterpret_cast<RawUint32x4**>(slot());
+  RawUint32x4* raw_uint32x4 = Uint32x4::New(value());
+  *uint32x4_slot = raw_uint32x4;
+
+  if (FLAG_trace_deoptimization_verbose) {
+    uint32_t x = raw_uint32x4->x();
+    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",
+                 reinterpret_cast<uword>(slot()), x, y, z, w);
+  }
+}
+
+
+void DeferredObjectRef::Materialize() {
+  // TODO(turnidge): Consider passing the deopt_context to materialize
+  // instead of accessing it through the current isolate.  It would
+  // make it easier to test deferred object materialization in a unit
+  // test eventually.
+  DeferredObject* obj =
+      Isolate::Current()->deopt_context()->GetDeferredObject(index());
+  *slot() = obj->object();
+  if (FLAG_trace_deoptimization_verbose) {
+    OS::PrintErr("writing instance ref at %" Px ": %s\n",
+                 reinterpret_cast<uword>(slot()),
+                 Instance::Handle(obj->object()).ToCString());
+  }
+}
+
+
+RawInstance* DeferredObject::object() {
+  if (object_ == NULL) {
+    Materialize();
+  }
+  return object_->raw();
+}
+
+
+void DeferredObject::Materialize() {
+  Class& cls = Class::Handle();
+  cls ^= GetClass();
+
+  if (FLAG_trace_deoptimization_verbose) {
+    OS::PrintErr("materializing instance of %s (%" Px ", %" Pd " fields)\n",
+                 cls.ToCString(),
+                 reinterpret_cast<uword>(args_),
+                 field_count_);
+  }
+
+  const Instance& obj = Instance::ZoneHandle(Instance::New(cls));
+
+  Field& field = Field::Handle();
+  Object& value = Object::Handle();
+  for (intptr_t i = 0; i < field_count_; i++) {
+    field ^= GetField(i);
+    value = GetValue(i);
+    obj.SetField(field, value);
+
+    if (FLAG_trace_deoptimization_verbose) {
+      OS::PrintErr("    %s <- %s\n",
+                   String::Handle(field.name()).ToCString(),
+                   value.ToCString());
+    }
+  }
+
+  object_ = &obj;
+}
+
+}  // namespace dart
diff --git a/runtime/vm/deferred_objects.h b/runtime/vm/deferred_objects.h
new file mode 100644
index 0000000..7e2c3c9
--- /dev/null
+++ b/runtime/vm/deferred_objects.h
@@ -0,0 +1,187 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_DEFERRED_OBJECTS_H_
+#define VM_DEFERRED_OBJECTS_H_
+
+#include "platform/globals.h"
+
+namespace dart {
+
+// Forward declarations.
+class Instance;
+class RawInstance;
+class RawObject;
+
+// Used by the deoptimization infrastructure to defer allocation of
+// unboxed objects until frame is fully rewritten and GC is safe.
+// Describes a stack slot that should be populated with a reference to
+// the materialized object.
+class DeferredSlot {
+ public:
+  DeferredSlot(RawInstance** slot, DeferredSlot* next)
+      : slot_(slot), next_(next) { }
+  virtual ~DeferredSlot() { }
+
+  RawInstance** slot() const { return slot_; }
+  DeferredSlot* next() const { return next_; }
+
+  virtual void Materialize() = 0;
+
+ private:
+  RawInstance** const slot_;
+  DeferredSlot* const next_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeferredSlot);
+};
+
+
+class DeferredDouble : public DeferredSlot {
+ public:
+  DeferredDouble(double value, RawInstance** slot, DeferredSlot* next)
+      : DeferredSlot(slot, next), value_(value) { }
+
+  virtual void Materialize();
+
+  double value() const { return value_; }
+
+ private:
+  const double value_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeferredDouble);
+};
+
+
+class DeferredMint : public DeferredSlot {
+ public:
+  DeferredMint(int64_t value, RawInstance** slot, DeferredSlot* next)
+      : DeferredSlot(slot, next), value_(value) { }
+
+  virtual void Materialize();
+
+  int64_t value() const { return value_; }
+
+ private:
+  const int64_t value_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeferredMint);
+};
+
+
+class DeferredFloat32x4 : public DeferredSlot {
+ public:
+  DeferredFloat32x4(simd128_value_t value, RawInstance** slot,
+                    DeferredSlot* next)
+      : DeferredSlot(slot, next), value_(value) { }
+
+  virtual void Materialize();
+
+  simd128_value_t value() const { return value_; }
+
+ private:
+  const simd128_value_t value_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeferredFloat32x4);
+};
+
+
+class DeferredUint32x4 : public DeferredSlot {
+ public:
+  DeferredUint32x4(simd128_value_t value, RawInstance** slot,
+                   DeferredSlot* next)
+      : DeferredSlot(slot, next), value_(value) { }
+
+  virtual void Materialize();
+
+  simd128_value_t value() const { return value_; }
+
+ private:
+  const simd128_value_t value_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeferredUint32x4);
+};
+
+
+// Describes a slot that contains a reference to an object that had its
+// allocation removed by AllocationSinking pass.
+// Object itself is described and materialized by DeferredObject.
+class DeferredObjectRef : public DeferredSlot {
+ public:
+  DeferredObjectRef(intptr_t index, RawInstance** slot, DeferredSlot* next)
+      : DeferredSlot(slot, next), index_(index) { }
+
+  virtual void Materialize();
+
+  intptr_t index() const { return index_; }
+
+ private:
+  const intptr_t index_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeferredObjectRef);
+};
+
+
+// Describes an object which allocation was removed by AllocationSinking pass.
+// Arguments for materialization are stored as a part of expression stack
+// for the bottommost deoptimized frame so that GC could discover them.
+// They will be removed from the stack at the very end of deoptimization.
+class DeferredObject {
+ public:
+  DeferredObject(intptr_t field_count, intptr_t* args)
+      : field_count_(field_count),
+        args_(reinterpret_cast<RawObject**>(args)),
+        object_(NULL) { }
+
+  intptr_t ArgumentCount() const {
+    return kFieldsStartIndex + kFieldEntrySize * field_count_;
+  }
+
+  RawInstance* object();
+
+ private:
+  enum {
+    kClassIndex = 0,
+    kFieldsStartIndex = kClassIndex + 1
+  };
+
+  enum {
+    kFieldIndex = 0,
+    kValueIndex,
+    kFieldEntrySize,
+  };
+
+  // Materializes the object. Returns amount of values that were consumed
+  // and should be removed from the expression stack at the very end of
+  // deoptimization.
+  void Materialize();
+
+  RawObject* GetClass() const {
+    return args_[kClassIndex];
+  }
+
+  RawObject* GetField(intptr_t index) const {
+    return args_[kFieldsStartIndex + kFieldEntrySize * index + kFieldIndex];
+  }
+
+  RawObject* GetValue(intptr_t index) const {
+    return args_[kFieldsStartIndex + kFieldEntrySize * index + kValueIndex];
+  }
+
+  // Amount of fields that have to be initialized.
+  const intptr_t field_count_;
+
+  // Pointer to the first materialization argument on the stack.
+  // The first argument is Class of the instance to materialize followed by
+  // Field, value pairs.
+  RawObject** args_;
+
+  // Object materialized from this description.
+  const Instance* object_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeferredObject);
+};
+
+}  // namespace dart
+
+#endif  // VM_DEFERRED_OBJECTS_H_
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index adca206..f7a7c53 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -18,71 +18,158 @@
 DECLARE_FLAG(bool, trace_deoptimization);
 DECLARE_FLAG(bool, trace_deoptimization_verbose);
 
-DeoptimizationContext::DeoptimizationContext(intptr_t* to_frame_start,
-                                             intptr_t to_frame_size,
-                                             const Array& object_table,
-                                             intptr_t num_args,
-                                             DeoptReasonId deopt_reason)
-    : object_table_(object_table),
-      to_frame_(to_frame_start),
-      to_frame_size_(to_frame_size),
-      from_frame_(NULL),
-      from_frame_size_(0),
-      registers_copy_(NULL),
-      fpu_registers_copy_(NULL),
+DeoptContext::DeoptContext(const Array& object_table,
+                           intptr_t num_args,
+                           DeoptReasonId deopt_reason)
+    : object_table_(object_table.raw()),
+      dest_frame_(NULL),
+      dest_frame_size_(0),
+      source_frame_is_copy_(false),
+      source_frame_(NULL),
+      source_frame_size_(0),
+      cpu_registers_(NULL),
+      fpu_registers_(NULL),
       num_args_(num_args),
       deopt_reason_(deopt_reason),
-      isolate_(Isolate::Current()) {
-  from_frame_ = isolate_->deopt_frame_copy();
-  from_frame_size_ = isolate_->deopt_frame_copy_size();
-  registers_copy_ = isolate_->deopt_cpu_registers_copy();
-  fpu_registers_copy_ = isolate_->deopt_fpu_registers_copy();
-  // The deoptimized frame is filled starting just below the sp of its caller
-  // down to kDartFrameFixedSize words below its own sp.
-  // The chain of frame pointers is recreated from the fp of the caller.
-  caller_fp_ = GetFromFp();
+      isolate_(Isolate::Current()),
+      deferred_boxes_(NULL),
+      deferred_object_refs_(NULL),
+      deferred_objects_count_(0),
+      deferred_objects_(NULL) {
 }
 
 
-intptr_t DeoptimizationContext::GetFromFp() const {
-  return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp];
+DeoptContext::~DeoptContext() {
+  // Delete memory for source frame and registers.
+  if (source_frame_is_copy_) {
+    delete[] source_frame_;
+  }
+  source_frame_ = NULL;
+  delete[] fpu_registers_;
+  delete[] cpu_registers_;
+  fpu_registers_ = NULL;
+  cpu_registers_ = NULL;
+
+  // Delete all deferred objects.
+  for (intptr_t i = 0; i < deferred_objects_count_; i++) {
+    delete deferred_objects_[i];
+  }
+  delete[] deferred_objects_;
+  deferred_objects_ = NULL;
+  deferred_objects_count_ = 0;
 }
 
 
-intptr_t DeoptimizationContext::GetFromPp() const {
-  return from_frame_[from_frame_size_ - 1 - num_args_ - kParamEndSlotFromFp +
-      StackFrame::SavedCallerPpSlotFromFp()];
+void DeoptContext::SetSourceArgs(intptr_t* frame_start,
+                                 intptr_t frame_size,
+                                 fpu_register_t* fpu_registers,
+                                 intptr_t* cpu_registers,
+                                 bool source_frame_is_copy) {
+  ASSERT(frame_start != NULL);
+  ASSERT(frame_size >= 0);
+  ASSERT(source_frame_ == NULL);
+  ASSERT(cpu_registers_ == NULL && fpu_registers_ == NULL);
+  source_frame_ = frame_start;
+  source_frame_size_ = frame_size;
+  caller_fp_ = GetSourceFp();
+  cpu_registers_ = cpu_registers;
+  fpu_registers_ = fpu_registers;
+  source_frame_is_copy_ = source_frame_is_copy;
 }
 
 
-intptr_t DeoptimizationContext::GetFromPc() const {
-  return from_frame_[from_frame_size_ - num_args_ + kSavedPcSlotFromSp];
+void DeoptContext::SetDestArgs(intptr_t* frame_start,
+                               intptr_t frame_size) {
+  ASSERT(frame_start != NULL);
+  ASSERT(frame_size >= 0);
+  ASSERT(dest_frame_ == NULL);
+  dest_frame_ = frame_start;
+  dest_frame_size_ = frame_size;
 }
 
 
-intptr_t DeoptimizationContext::GetCallerFp() const {
+void DeoptContext::VisitObjectPointers(ObjectPointerVisitor* visitor) {
+  visitor->VisitPointer(reinterpret_cast<RawObject**>(&object_table_));
+}
+
+
+intptr_t DeoptContext::GetSourceFp() const {
+  return source_frame_[source_frame_size_ - 1 - num_args_ -
+                       kParamEndSlotFromFp];
+}
+
+
+intptr_t DeoptContext::GetSourcePp() const {
+  return source_frame_[source_frame_size_ - 1 - num_args_ -
+                       kParamEndSlotFromFp +
+                       StackFrame::SavedCallerPpSlotFromFp()];
+}
+
+
+intptr_t DeoptContext::GetSourcePc() const {
+  return source_frame_[source_frame_size_ - num_args_ + kSavedPcSlotFromSp];
+}
+
+
+intptr_t DeoptContext::GetCallerFp() const {
   return caller_fp_;
 }
 
 
-void DeoptimizationContext::SetCallerFp(intptr_t caller_fp) {
+void DeoptContext::SetCallerFp(intptr_t caller_fp) {
   caller_fp_ = caller_fp;
 }
 
 
+static void FillDeferredSlots(DeferredSlot** slot_list) {
+  DeferredSlot* slot = *slot_list;
+  *slot_list = NULL;
+
+  while (slot != NULL) {
+    DeferredSlot* current = slot;
+    slot = slot->next();
+
+    current->Materialize();
+
+    delete current;
+  }
+}
+
+
+// Materializes all deferred objects.  Returns the total number of
+// artificial arguments used during deoptimization.
+intptr_t DeoptContext::MaterializeDeferredObjects() {
+  // First materialize all unboxed "primitive" values (doubles, mints, simd)
+  // then materialize objects. The order is important: objects might be
+  // referencing boxes allocated on the first step. At the same time
+  // objects can't be referencing other deferred objects because storing
+  // an object into a field is always conservatively treated as escaping by
+  // allocation sinking and load forwarding.
+  FillDeferredSlots(&deferred_boxes_);
+  FillDeferredSlots(&deferred_object_refs_);
+
+  // Compute total number of artificial arguments used during deoptimization.
+  intptr_t deopt_arguments = 0;
+  for (intptr_t i = 0; i < DeferredObjectsCount(); i++) {
+    deopt_arguments += GetDeferredObject(i)->ArgumentCount();
+  }
+  return deopt_arguments;
+}
+
+
 // Deoptimization instruction moving value from optimized frame at
-// 'from_index' to specified slots in the unoptimized frame.
-// 'from_index' represents the slot index of the frame (0 being first argument)
-// and accounts for saved return address, frame pointer, pool pointer and pc
-// marker.
+// 'source_index' to specified slots in the unoptimized frame.
+// 'source_index' represents the slot index of the frame (0 being
+// first argument) and accounts for saved return address, frame
+// pointer, pool pointer and pc marker.
 class DeoptStackSlotInstr : public DeoptInstr {
  public:
-  explicit DeoptStackSlotInstr(intptr_t from_index)
-      : stack_slot_index_(from_index) {
+  explicit DeoptStackSlotInstr(intptr_t source_index)
+      : stack_slot_index_(source_index) {
     ASSERT(stack_slot_index_ >= 0);
   }
 
-  virtual intptr_t from_index() const { return stack_slot_index_; }
+  virtual intptr_t source_index() const { return stack_slot_index_; }
   virtual DeoptInstr::Kind kind() const { return kStackSlot; }
 
   virtual const char* ToCString() const {
@@ -90,11 +177,12 @@
         "s%" Pd "", stack_slot_index_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
-    intptr_t from_index =
-       deopt_context->from_frame_size() - stack_slot_index_ - 1;
-    intptr_t* from_addr = deopt_context->GetFromFrameAddressAt(from_index);
-    *to_addr = *from_addr;
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+    intptr_t source_index =
+       deopt_context->source_frame_size() - stack_slot_index_ - 1;
+    intptr_t* source_addr =
+        deopt_context->GetSourceFrameAddressAt(source_index);
+    *dest_addr = *source_addr;
   }
 
  private:
@@ -106,12 +194,12 @@
 
 class DeoptDoubleStackSlotInstr : public DeoptInstr {
  public:
-  explicit DeoptDoubleStackSlotInstr(intptr_t from_index)
-      : stack_slot_index_(from_index) {
+  explicit DeoptDoubleStackSlotInstr(intptr_t source_index)
+      : stack_slot_index_(source_index) {
     ASSERT(stack_slot_index_ >= 0);
   }
 
-  virtual intptr_t from_index() const { return stack_slot_index_; }
+  virtual intptr_t source_index() const { return stack_slot_index_; }
   virtual DeoptInstr::Kind kind() const { return kDoubleStackSlot; }
 
   virtual const char* ToCString() const {
@@ -119,14 +207,14 @@
         "ds%" Pd "", stack_slot_index_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
-    intptr_t from_index =
-       deopt_context->from_frame_size() - stack_slot_index_ - 1;
-    double* from_addr = reinterpret_cast<double*>(
-        deopt_context->GetFromFrameAddressAt(from_index));
-    *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
-    Isolate::Current()->DeferDoubleMaterialization(
-        *from_addr, reinterpret_cast<RawDouble**>(to_addr));
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+    intptr_t source_index =
+       deopt_context->source_frame_size() - stack_slot_index_ - 1;
+    double* source_addr = reinterpret_cast<double*>(
+        deopt_context->GetSourceFrameAddressAt(source_index));
+    *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+    deopt_context->DeferDoubleMaterialization(
+        *source_addr, reinterpret_cast<RawDouble**>(dest_addr));
   }
 
  private:
@@ -138,12 +226,12 @@
 
 class DeoptInt64StackSlotInstr : public DeoptInstr {
  public:
-  explicit DeoptInt64StackSlotInstr(intptr_t from_index)
-      : stack_slot_index_(from_index) {
+  explicit DeoptInt64StackSlotInstr(intptr_t source_index)
+      : stack_slot_index_(source_index) {
     ASSERT(stack_slot_index_ >= 0);
   }
 
-  virtual intptr_t from_index() const { return stack_slot_index_; }
+  virtual intptr_t source_index() const { return stack_slot_index_; }
   virtual DeoptInstr::Kind kind() const { return kInt64StackSlot; }
 
   virtual const char* ToCString() const {
@@ -151,18 +239,18 @@
         "ms%" Pd "", stack_slot_index_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
-    intptr_t from_index =
-       deopt_context->from_frame_size() - stack_slot_index_ - 1;
-    int64_t* from_addr = reinterpret_cast<int64_t*>(
-        deopt_context->GetFromFrameAddressAt(from_index));
-    *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
-    if (Smi::IsValid64(*from_addr)) {
-      *to_addr = reinterpret_cast<intptr_t>(
-          Smi::New(static_cast<intptr_t>(*from_addr)));
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+    intptr_t source_index =
+       deopt_context->source_frame_size() - stack_slot_index_ - 1;
+    int64_t* source_addr = reinterpret_cast<int64_t*>(
+        deopt_context->GetSourceFrameAddressAt(source_index));
+    *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+    if (Smi::IsValid64(*source_addr)) {
+      *dest_addr = reinterpret_cast<intptr_t>(
+          Smi::New(static_cast<intptr_t>(*source_addr)));
     } else {
-      Isolate::Current()->DeferMintMaterialization(
-          *from_addr, reinterpret_cast<RawMint**>(to_addr));
+      deopt_context->DeferMintMaterialization(
+          *source_addr, reinterpret_cast<RawMint**>(dest_addr));
     }
   }
 
@@ -175,12 +263,12 @@
 
 class DeoptFloat32x4StackSlotInstr : public DeoptInstr {
  public:
-  explicit DeoptFloat32x4StackSlotInstr(intptr_t from_index)
-      : stack_slot_index_(from_index) {
+  explicit DeoptFloat32x4StackSlotInstr(intptr_t source_index)
+      : stack_slot_index_(source_index) {
     ASSERT(stack_slot_index_ >= 0);
   }
 
-  virtual intptr_t from_index() const { return stack_slot_index_; }
+  virtual intptr_t source_index() const { return stack_slot_index_; }
   virtual DeoptInstr::Kind kind() const { return kFloat32x4StackSlot; }
 
   virtual const char* ToCString() const {
@@ -188,14 +276,14 @@
         "f32x4s%" Pd "", stack_slot_index_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
-    intptr_t from_index =
-       deopt_context->from_frame_size() - stack_slot_index_ - 1;
-    simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>(
-        deopt_context->GetFromFrameAddressAt(from_index));
-    *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
-    Isolate::Current()->DeferFloat32x4Materialization(
-        *from_addr, reinterpret_cast<RawFloat32x4**>(to_addr));
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+    intptr_t source_index =
+       deopt_context->source_frame_size() - stack_slot_index_ - 1;
+    simd128_value_t* source_addr = reinterpret_cast<simd128_value_t*>(
+        deopt_context->GetSourceFrameAddressAt(source_index));
+    *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+    deopt_context->DeferFloat32x4Materialization(
+        *source_addr, reinterpret_cast<RawFloat32x4**>(dest_addr));
   }
 
  private:
@@ -207,12 +295,12 @@
 
 class DeoptUint32x4StackSlotInstr : public DeoptInstr {
  public:
-  explicit DeoptUint32x4StackSlotInstr(intptr_t from_index)
-      : stack_slot_index_(from_index) {
+  explicit DeoptUint32x4StackSlotInstr(intptr_t source_index)
+      : stack_slot_index_(source_index) {
     ASSERT(stack_slot_index_ >= 0);
   }
 
-  virtual intptr_t from_index() const { return stack_slot_index_; }
+  virtual intptr_t source_index() const { return stack_slot_index_; }
   virtual DeoptInstr::Kind kind() const { return kUint32x4StackSlot; }
 
   virtual const char* ToCString() const {
@@ -220,14 +308,14 @@
         "ui32x4s%" Pd "", stack_slot_index_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
-    intptr_t from_index =
-       deopt_context->from_frame_size() - stack_slot_index_ - 1;
-    simd128_value_t* from_addr = reinterpret_cast<simd128_value_t*>(
-        deopt_context->GetFromFrameAddressAt(from_index));
-    *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
-    Isolate::Current()->DeferUint32x4Materialization(
-        *from_addr, reinterpret_cast<RawUint32x4**>(to_addr));
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+    intptr_t source_index =
+       deopt_context->source_frame_size() - stack_slot_index_ - 1;
+    simd128_value_t* source_addr = reinterpret_cast<simd128_value_t*>(
+        deopt_context->GetSourceFrameAddressAt(source_index));
+    *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+    deopt_context->DeferUint32x4Materialization(
+        *source_addr, reinterpret_cast<RawUint32x4**>(dest_addr));
   }
 
  private:
@@ -247,12 +335,12 @@
     ASSERT(deopt_id >= 0);
   }
 
-  explicit DeoptRetAddressInstr(intptr_t from_index)
-      : object_table_index_(ObjectTableIndex::decode(from_index)),
-        deopt_id_(DeoptId::decode(from_index)) {
+  explicit DeoptRetAddressInstr(intptr_t source_index)
+      : object_table_index_(ObjectTableIndex::decode(source_index)),
+        deopt_id_(DeoptId::decode(source_index)) {
   }
 
-  virtual intptr_t from_index() const {
+  virtual intptr_t source_index() const {
     return ObjectTableIndex::encode(object_table_index_) |
         DeoptId::encode(deopt_id_);
   }
@@ -264,7 +352,7 @@
         "ret oti:%" Pd "(%" Pd ")", object_table_index_, deopt_id_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     Function& function = Function::Handle(deopt_context->isolate());
     function ^= deopt_context->ObjectAt(object_table_index_);
     const Code& code =
@@ -273,7 +361,7 @@
     uword continue_at_pc = code.GetPcForDeoptId(deopt_id_,
                                                 PcDescriptors::kDeopt);
     ASSERT(continue_at_pc != 0);
-    *to_addr = continue_at_pc;
+    *dest_addr = continue_at_pc;
 
     uword pc = code.GetPcForDeoptId(deopt_id_, PcDescriptors::kIcCall);
     if (pc != 0) {
@@ -310,7 +398,7 @@
     ASSERT(object_table_index >= 0);
   }
 
-  virtual intptr_t from_index() const { return object_table_index_; }
+  virtual intptr_t source_index() const { return object_table_index_; }
   virtual DeoptInstr::Kind kind() const { return kConstant; }
 
   virtual const char* ToCString() const {
@@ -318,10 +406,10 @@
         "const oti:%" Pd "", object_table_index_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     const Object& obj = Object::Handle(
         deopt_context->isolate(), deopt_context->ObjectAt(object_table_index_));
-    *reinterpret_cast<RawObject**>(to_addr) = obj.raw();
+    *reinterpret_cast<RawObject**>(dest_addr) = obj.raw();
   }
 
  private:
@@ -337,15 +425,15 @@
   explicit DeoptRegisterInstr(intptr_t reg_as_int)
       : reg_(static_cast<Register>(reg_as_int)) {}
 
-  virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
+  virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
   virtual DeoptInstr::Kind kind() const { return kRegister; }
 
   virtual const char* ToCString() const {
     return Assembler::RegisterName(reg_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
-    *to_addr = deopt_context->RegisterValue(reg_);
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+    *dest_addr = deopt_context->RegisterValue(reg_);
   }
 
  private:
@@ -361,18 +449,18 @@
   explicit DeoptFpuRegisterInstr(intptr_t reg_as_int)
       : reg_(static_cast<FpuRegister>(reg_as_int)) {}
 
-  virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
+  virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
   virtual DeoptInstr::Kind kind() const { return kFpuRegister; }
 
   virtual const char* ToCString() const {
     return Assembler::FpuRegisterName(reg_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     double value = deopt_context->FpuRegisterValue(reg_);
-    *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
-    Isolate::Current()->DeferDoubleMaterialization(
-        value, reinterpret_cast<RawDouble**>(to_addr));
+    *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+    deopt_context->DeferDoubleMaterialization(
+        value, reinterpret_cast<RawDouble**>(dest_addr));
   }
 
  private:
@@ -387,7 +475,7 @@
   explicit DeoptInt64FpuRegisterInstr(intptr_t reg_as_int)
       : reg_(static_cast<FpuRegister>(reg_as_int)) {}
 
-  virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
+  virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
   virtual DeoptInstr::Kind kind() const { return kInt64FpuRegister; }
 
   virtual const char* ToCString() const {
@@ -395,15 +483,15 @@
         "%s(m)", Assembler::FpuRegisterName(reg_));
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     int64_t value = deopt_context->FpuRegisterValueAsInt64(reg_);
-    *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
+    *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
     if (Smi::IsValid64(value)) {
-      *to_addr = reinterpret_cast<intptr_t>(
+      *dest_addr = reinterpret_cast<intptr_t>(
           Smi::New(static_cast<intptr_t>(value)));
     } else {
-      Isolate::Current()->DeferMintMaterialization(
-          value, reinterpret_cast<RawMint**>(to_addr));
+      deopt_context->DeferMintMaterialization(
+          value, reinterpret_cast<RawMint**>(dest_addr));
     }
   }
 
@@ -420,7 +508,7 @@
   explicit DeoptFloat32x4FpuRegisterInstr(intptr_t reg_as_int)
       : reg_(static_cast<FpuRegister>(reg_as_int)) {}
 
-  virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
+  virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
   virtual DeoptInstr::Kind kind() const { return kFloat32x4FpuRegister; }
 
   virtual const char* ToCString() const {
@@ -428,11 +516,11 @@
         "%s(f32x4)", Assembler::FpuRegisterName(reg_));
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_);
-    *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
-    Isolate::Current()->DeferFloat32x4Materialization(
-        value, reinterpret_cast<RawFloat32x4**>(to_addr));
+    *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+    deopt_context->DeferFloat32x4Materialization(
+        value, reinterpret_cast<RawFloat32x4**>(dest_addr));
   }
 
  private:
@@ -448,7 +536,7 @@
   explicit DeoptUint32x4FpuRegisterInstr(intptr_t reg_as_int)
       : reg_(static_cast<FpuRegister>(reg_as_int)) {}
 
-  virtual intptr_t from_index() const { return static_cast<intptr_t>(reg_); }
+  virtual intptr_t source_index() const { return static_cast<intptr_t>(reg_); }
   virtual DeoptInstr::Kind kind() const { return kUint32x4FpuRegister; }
 
   virtual const char* ToCString() const {
@@ -456,11 +544,11 @@
         "%s(f32x4)", Assembler::FpuRegisterName(reg_));
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     simd128_value_t value = deopt_context->FpuRegisterValueAsSimd128(reg_);
-    *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
-    Isolate::Current()->DeferUint32x4Materialization(
-        value, reinterpret_cast<RawUint32x4**>(to_addr));
+    *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+    deopt_context->DeferUint32x4Materialization(
+        value, reinterpret_cast<RawUint32x4**>(dest_addr));
   }
 
  private:
@@ -479,7 +567,7 @@
     ASSERT(object_table_index >= 0);
   }
 
-  virtual intptr_t from_index() const { return object_table_index_; }
+  virtual intptr_t source_index() const { return object_table_index_; }
   virtual DeoptInstr::Kind kind() const { return kPcMarker; }
 
   virtual const char* ToCString() const {
@@ -487,12 +575,12 @@
         "pcmark oti:%" Pd "", object_table_index_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     Function& function = Function::Handle(deopt_context->isolate());
     function ^= deopt_context->ObjectAt(object_table_index_);
     if (function.IsNull()) {
       // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0.
-      *to_addr = 0;
+      *dest_addr = 0;
       return;
     }
     const Code& code =
@@ -500,7 +588,7 @@
     ASSERT(!code.IsNull());
     const intptr_t pc_marker =
         code.EntryPoint() + Assembler::kEntryPointToPcMarkerOffset;
-    *to_addr = pc_marker;
+    *dest_addr = pc_marker;
     // Increment the deoptimization counter. This effectively increments each
     // function occurring in the optimized frame.
     function.set_deoptimization_counter(function.deoptimization_counter() + 1);
@@ -531,7 +619,7 @@
     ASSERT(object_table_index >= 0);
   }
 
-  virtual intptr_t from_index() const { return object_table_index_; }
+  virtual intptr_t source_index() const { return object_table_index_; }
   virtual DeoptInstr::Kind kind() const { return kPp; }
 
   virtual const char* ToCString() const {
@@ -539,14 +627,14 @@
         "pp oti:%" Pd "", object_table_index_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     Function& function = Function::Handle(deopt_context->isolate());
     function ^= deopt_context->ObjectAt(object_table_index_);
     const Code& code =
         Code::Handle(deopt_context->isolate(), function.unoptimized_code());
     ASSERT(!code.IsNull());
     const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool());
-    *to_addr = pp;
+    *dest_addr = pp;
   }
 
  private:
@@ -561,17 +649,17 @@
  public:
   DeoptCallerFpInstr() {}
 
-  virtual intptr_t from_index() const { return 0; }
+  virtual intptr_t source_index() const { return 0; }
   virtual DeoptInstr::Kind kind() const { return kCallerFp; }
 
   virtual const char* ToCString() const {
     return "callerfp";
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
-    *to_addr = deopt_context->GetCallerFp();
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+    *dest_addr = deopt_context->GetCallerFp();
     deopt_context->SetCallerFp(reinterpret_cast<intptr_t>(
-        to_addr - (kSavedCallerFpSlotFromFp * kWordSize)));
+        dest_addr - (kSavedCallerFpSlotFromFp * kWordSize)));
   }
 
  private:
@@ -584,15 +672,15 @@
  public:
   DeoptCallerPpInstr() {}
 
-  virtual intptr_t from_index() const { return 0; }
+  virtual intptr_t source_index() const { return 0; }
   virtual DeoptInstr::Kind kind() const { return kCallerPp; }
 
   virtual const char* ToCString() const {
     return "callerpp";
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
-    *to_addr = deopt_context->GetFromPp();
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+    *dest_addr = deopt_context->GetSourcePp();
   }
 
  private:
@@ -606,15 +694,15 @@
  public:
   DeoptCallerPcInstr() {}
 
-  virtual intptr_t from_index() const { return 0; }
+  virtual intptr_t source_index() const { return 0; }
   virtual DeoptInstr::Kind kind() const { return kCallerPc; }
 
   virtual const char* ToCString() const {
     return "callerpc";
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
-    *to_addr = deopt_context->GetFromPc();
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+    *dest_addr = deopt_context->GetSourcePc();
   }
 
  private:
@@ -634,12 +722,12 @@
     ASSERT(suffix_length >= 0);
   }
 
-  explicit DeoptSuffixInstr(intptr_t from_index)
-      : info_number_(InfoNumber::decode(from_index)),
-        suffix_length_(SuffixLength::decode(from_index)) {
+  explicit DeoptSuffixInstr(intptr_t source_index)
+      : info_number_(InfoNumber::decode(source_index)),
+        suffix_length_(SuffixLength::decode(source_index)) {
   }
 
-  virtual intptr_t from_index() const {
+  virtual intptr_t source_index() const {
     return InfoNumber::encode(info_number_) |
         SuffixLength::encode(suffix_length_);
   }
@@ -650,7 +738,7 @@
         "suffix %" Pd ":%" Pd, info_number_, suffix_length_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     // The deoptimization info is uncompressed by translating away suffixes
     // before executing the instructions.
     UNREACHABLE();
@@ -681,7 +769,7 @@
     ASSERT(index >= 0);
   }
 
-  virtual intptr_t from_index() const { return index_; }
+  virtual intptr_t source_index() const { return index_; }
   virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; }
 
   virtual const char* ToCString() const {
@@ -689,10 +777,10 @@
         "mat ref #%" Pd "", index_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
-    *reinterpret_cast<RawSmi**>(to_addr) = Smi::New(0);
-    Isolate::Current()->DeferMaterializedObjectRef(
-        index_, to_addr);
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
+    *reinterpret_cast<RawSmi**>(dest_addr) = Smi::New(0);
+    deopt_context->DeferMaterializedObjectRef(
+        index_, dest_addr);
   }
 
  private:
@@ -712,7 +800,7 @@
     ASSERT(field_count >= 0);
   }
 
-  virtual intptr_t from_index() const { return field_count_; }
+  virtual intptr_t source_index() const { return field_count_; }
   virtual DeoptInstr::Kind kind() const { return kMaterializeObject; }
 
   virtual const char* ToCString() const {
@@ -720,7 +808,7 @@
         "mat obj len:%" Pd "", field_count_);
   }
 
-  void Execute(DeoptimizationContext* deopt_context, intptr_t* to_addr) {
+  void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     // This instructions are executed manually by the DeoptimizeWithDeoptInfo.
     UNREACHABLE();
   }
@@ -732,9 +820,10 @@
 };
 
 
-intptr_t DeoptInstr::DecodeSuffix(intptr_t from_index, intptr_t* info_number) {
-  *info_number = DeoptSuffixInstr::InfoNumber::decode(from_index);
-  return DeoptSuffixInstr::SuffixLength::decode(from_index);
+intptr_t DeoptInstr::DecodeSuffix(intptr_t source_index,
+                                  intptr_t* info_number) {
+  *info_number = DeoptSuffixInstr::InfoNumber::decode(source_index);
+  return DeoptSuffixInstr::SuffixLength::decode(source_index);
 }
 
 
@@ -759,34 +848,35 @@
 }
 
 
-DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t from_index) {
+DeoptInstr* DeoptInstr::Create(intptr_t kind_as_int, intptr_t source_index) {
   Kind kind = static_cast<Kind>(kind_as_int);
   switch (kind) {
-    case kStackSlot: return new DeoptStackSlotInstr(from_index);
-    case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(from_index);
-    case kInt64StackSlot: return new DeoptInt64StackSlotInstr(from_index);
+    case kStackSlot: return new DeoptStackSlotInstr(source_index);
+    case kDoubleStackSlot: return new DeoptDoubleStackSlotInstr(source_index);
+    case kInt64StackSlot: return new DeoptInt64StackSlotInstr(source_index);
     case kFloat32x4StackSlot:
-        return new DeoptFloat32x4StackSlotInstr(from_index);
+        return new DeoptFloat32x4StackSlotInstr(source_index);
     case kUint32x4StackSlot:
-        return new DeoptUint32x4StackSlotInstr(from_index);
-    case kRetAddress: return new DeoptRetAddressInstr(from_index);
-    case kConstant: return new DeoptConstantInstr(from_index);
-    case kRegister: return new DeoptRegisterInstr(from_index);
-    case kFpuRegister: return new DeoptFpuRegisterInstr(from_index);
-    case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(from_index);
+        return new DeoptUint32x4StackSlotInstr(source_index);
+    case kRetAddress: return new DeoptRetAddressInstr(source_index);
+    case kConstant: return new DeoptConstantInstr(source_index);
+    case kRegister: return new DeoptRegisterInstr(source_index);
+    case kFpuRegister: return new DeoptFpuRegisterInstr(source_index);
+    case kInt64FpuRegister: return new DeoptInt64FpuRegisterInstr(source_index);
     case kFloat32x4FpuRegister:
-        return new DeoptFloat32x4FpuRegisterInstr(from_index);
+        return new DeoptFloat32x4FpuRegisterInstr(source_index);
     case kUint32x4FpuRegister:
-        return new DeoptUint32x4FpuRegisterInstr(from_index);
-    case kPcMarker: return new DeoptPcMarkerInstr(from_index);
-    case kPp: return new DeoptPpInstr(from_index);
+        return new DeoptUint32x4FpuRegisterInstr(source_index);
+    case kPcMarker: return new DeoptPcMarkerInstr(source_index);
+    case kPp: return new DeoptPpInstr(source_index);
     case kCallerFp: return new DeoptCallerFpInstr();
     case kCallerPp: return new DeoptCallerPpInstr();
     case kCallerPc: return new DeoptCallerPcInstr();
-    case kSuffix: return new DeoptSuffixInstr(from_index);
+    case kSuffix: return new DeoptSuffixInstr(source_index);
     case kMaterializedObjectRef:
-        return new DeoptMaterializedObjectRefInstr(from_index);
-    case kMaterializeObject: return new DeoptMaterializeObjectInstr(from_index);
+        return new DeoptMaterializedObjectRefInstr(source_index);
+    case kMaterializeObject:
+      return new DeoptMaterializeObjectInstr(source_index);
   }
   UNREACHABLE();
   return NULL;
@@ -850,16 +940,17 @@
 }
 
 
-intptr_t DeoptInfoBuilder::CalculateStackIndex(const Location& from_loc) const {
-  return from_loc.stack_index() < 0 ?
-            from_loc.stack_index() + num_args_ :
-            from_loc.stack_index() + num_args_ + kDartFrameFixedSize;
+intptr_t DeoptInfoBuilder::CalculateStackIndex(
+    const Location& source_loc) const {
+  return source_loc.stack_index() < 0 ?
+            source_loc.stack_index() + num_args_ :
+            source_loc.stack_index() + num_args_ + kDartFrameFixedSize;
 }
 
 
 void DeoptInfoBuilder::AddReturnAddress(const Function& function,
                                         intptr_t deopt_id,
-                                        intptr_t to_index) {
+                                        intptr_t dest_index) {
   // Check that deopt_id exists.
   // TODO(vegorov): verify after deoptimization targets as well.
 #ifdef DEBUG
@@ -868,68 +959,68 @@
       (code.GetPcForDeoptId(deopt_id, PcDescriptors::kDeopt) != 0));
 #endif
   const intptr_t object_table_index = FindOrAddObjectInTable(function);
-  ASSERT(to_index == FrameSize());
+  ASSERT(dest_index == FrameSize());
   instructions_.Add(new DeoptRetAddressInstr(object_table_index, deopt_id));
 }
 
 
 void DeoptInfoBuilder::AddPcMarker(const Function& function,
-                                   intptr_t to_index) {
+                                   intptr_t dest_index) {
   intptr_t object_table_index = FindOrAddObjectInTable(function);
-  ASSERT(to_index == FrameSize());
+  ASSERT(dest_index == FrameSize());
   instructions_.Add(new DeoptPcMarkerInstr(object_table_index));
 }
 
 
-void DeoptInfoBuilder::AddPp(const Function& function, intptr_t to_index) {
+void DeoptInfoBuilder::AddPp(const Function& function, intptr_t dest_index) {
   intptr_t object_table_index = FindOrAddObjectInTable(function);
-  ASSERT(to_index == FrameSize());
+  ASSERT(dest_index == FrameSize());
   instructions_.Add(new DeoptPpInstr(object_table_index));
 }
 
 
 void DeoptInfoBuilder::AddCopy(Value* value,
-                               const Location& from_loc,
-                               const intptr_t to_index) {
+                               const Location& source_loc,
+                               const intptr_t dest_index) {
   DeoptInstr* deopt_instr = NULL;
-  if (from_loc.IsConstant()) {
-    intptr_t object_table_index = FindOrAddObjectInTable(from_loc.constant());
+  if (source_loc.IsConstant()) {
+    intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant());
     deopt_instr = new DeoptConstantInstr(object_table_index);
-  } else if (from_loc.IsRegister()) {
+  } else if (source_loc.IsRegister()) {
     ASSERT(value->definition()->representation() == kTagged);
-    deopt_instr = new DeoptRegisterInstr(from_loc.reg());
-  } else if (from_loc.IsFpuRegister()) {
+    deopt_instr = new DeoptRegisterInstr(source_loc.reg());
+  } else if (source_loc.IsFpuRegister()) {
     if (value->definition()->representation() == kUnboxedDouble) {
-      deopt_instr = new DeoptFpuRegisterInstr(from_loc.fpu_reg());
+      deopt_instr = new DeoptFpuRegisterInstr(source_loc.fpu_reg());
     } else if (value->definition()->representation() == kUnboxedMint) {
-      deopt_instr = new DeoptInt64FpuRegisterInstr(from_loc.fpu_reg());
+      deopt_instr = new DeoptInt64FpuRegisterInstr(source_loc.fpu_reg());
     } else if (value->definition()->representation() == kUnboxedFloat32x4) {
-      deopt_instr = new DeoptFloat32x4FpuRegisterInstr(from_loc.fpu_reg());
+      deopt_instr = new DeoptFloat32x4FpuRegisterInstr(source_loc.fpu_reg());
     } else {
       ASSERT(value->definition()->representation() == kUnboxedUint32x4);
-      deopt_instr = new DeoptUint32x4FpuRegisterInstr(from_loc.fpu_reg());
+      deopt_instr = new DeoptUint32x4FpuRegisterInstr(source_loc.fpu_reg());
     }
-  } else if (from_loc.IsStackSlot()) {
+  } else if (source_loc.IsStackSlot()) {
     ASSERT(value->definition()->representation() == kTagged);
-    intptr_t from_index = CalculateStackIndex(from_loc);
-    deopt_instr = new DeoptStackSlotInstr(from_index);
-  } else if (from_loc.IsDoubleStackSlot()) {
-    intptr_t from_index = CalculateStackIndex(from_loc);
+    intptr_t source_index = CalculateStackIndex(source_loc);
+    deopt_instr = new DeoptStackSlotInstr(source_index);
+  } else if (source_loc.IsDoubleStackSlot()) {
+    intptr_t source_index = CalculateStackIndex(source_loc);
     if (value->definition()->representation() == kUnboxedDouble) {
-      deopt_instr = new DeoptDoubleStackSlotInstr(from_index);
+      deopt_instr = new DeoptDoubleStackSlotInstr(source_index);
     } else {
       ASSERT(value->definition()->representation() == kUnboxedMint);
-      deopt_instr = new DeoptInt64StackSlotInstr(from_index);
+      deopt_instr = new DeoptInt64StackSlotInstr(source_index);
     }
-  } else if (from_loc.IsQuadStackSlot()) {
-    intptr_t from_index = CalculateStackIndex(from_loc);
+  } else if (source_loc.IsQuadStackSlot()) {
+    intptr_t source_index = CalculateStackIndex(source_loc);
     if (value->definition()->representation() == kUnboxedFloat32x4) {
-      deopt_instr = new DeoptFloat32x4StackSlotInstr(from_index);
+      deopt_instr = new DeoptFloat32x4StackSlotInstr(source_index);
     } else {
       ASSERT(value->definition()->representation() == kUnboxedUint32x4);
-      deopt_instr = new DeoptUint32x4StackSlotInstr(from_index);
+      deopt_instr = new DeoptUint32x4StackSlotInstr(source_index);
     }
-  } else if (from_loc.IsInvalid() &&
+  } else if (source_loc.IsInvalid() &&
              value->definition()->IsMaterializeObject()) {
     const intptr_t index = FindMaterialization(
         value->definition()->AsMaterializeObject());
@@ -938,32 +1029,32 @@
   } else {
     UNREACHABLE();
   }
-  ASSERT(to_index == FrameSize());
+  ASSERT(dest_index == FrameSize());
   ASSERT(deopt_instr != NULL);
   instructions_.Add(deopt_instr);
 }
 
 
-void DeoptInfoBuilder::AddCallerFp(intptr_t to_index) {
-  ASSERT(to_index == FrameSize());
+void DeoptInfoBuilder::AddCallerFp(intptr_t dest_index) {
+  ASSERT(dest_index == FrameSize());
   instructions_.Add(new DeoptCallerFpInstr());
 }
 
 
-void DeoptInfoBuilder::AddCallerPp(intptr_t to_index) {
-  ASSERT(to_index == FrameSize());
+void DeoptInfoBuilder::AddCallerPp(intptr_t dest_index) {
+  ASSERT(dest_index == FrameSize());
   instructions_.Add(new DeoptCallerPpInstr());
 }
 
 
-void DeoptInfoBuilder::AddCallerPc(intptr_t to_index) {
-  ASSERT(to_index == FrameSize());
+void DeoptInfoBuilder::AddCallerPc(intptr_t dest_index) {
+  ASSERT(dest_index == FrameSize());
   instructions_.Add(new DeoptCallerPcInstr());
 }
 
 
-void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t to_index) {
-  ASSERT(to_index == FrameSize());
+void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t dest_index) {
+  ASSERT(dest_index == FrameSize());
   intptr_t object_table_index = FindOrAddObjectInTable(obj);
   instructions_.Add(new DeoptConstantInstr(object_table_index));
 }
@@ -990,20 +1081,21 @@
 }
 
 
-intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t to_index) {
-  ASSERT(to_index == kDartFrameFixedSize);
+intptr_t DeoptInfoBuilder::EmitMaterializationArguments(intptr_t dest_index) {
+  ASSERT(dest_index == kDartFrameFixedSize);
   for (intptr_t i = 0; i < materializations_.length(); i++) {
     MaterializeObjectInstr* mat = materializations_[i];
-    AddConstant(mat->cls(), to_index++);  // Class of the instance to allocate.
+    // Class of the instance to allocate.
+    AddConstant(mat->cls(), dest_index++);
     for (intptr_t i = 0; i < mat->InputCount(); i++) {
       if (!mat->InputAt(i)->BindsToConstantNull()) {
         // Emit field-value pair.
-        AddConstant(mat->FieldAt(i), to_index++);
-        AddCopy(mat->InputAt(i), mat->LocationAt(i), to_index++);
+        AddConstant(mat->FieldAt(i), dest_index++);
+        AddCopy(mat->InputAt(i), mat->LocationAt(i), dest_index++);
       }
     }
   }
-  return to_index;
+  return dest_index;
 }
 
 
@@ -1049,7 +1141,7 @@
   intptr_t write_count = (suffix_length > 1) ? length - 1 : length;
   for (intptr_t i = 0; i < write_count; ++i) {
     DeoptInstr* instr = instructions_[i];
-    deopt_info.SetAt(i, instr->kind(), instr->from_index());
+    deopt_info.SetAt(i, instr->kind(), instr->source_index());
     TrieNode* child = node;
     node = new TrieNode(instr, current_info_number_);
     node->AddChild(child);
@@ -1059,7 +1151,7 @@
     suffix->AddChild(node);
     DeoptInstr* instr =
         new DeoptSuffixInstr(suffix->info_number(), suffix_length);
-    deopt_info.SetAt(length - 1, instr->kind(), instr->from_index());
+    deopt_info.SetAt(length - 1, instr->kind(), instr->source_index());
   } else {
     trie_root_->AddChild(node);
   }
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 564b744..420ce10 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -8,6 +8,7 @@
 #include "vm/allocation.h"
 #include "vm/assembler.h"
 #include "vm/code_generator.h"
+#include "vm/deferred_objects.h"
 #include "vm/growable_array.h"
 #include "vm/object.h"
 
@@ -18,75 +19,167 @@
 class MaterializeObjectInstr;
 
 // Holds all data relevant for execution of deoptimization instructions.
-class DeoptimizationContext : public ValueObject {
+class DeoptContext {
  public:
-  // 'to_frame_start' points to the fixed size portion of the frame under sp.
   // 'num_args' is 0 if there are no arguments or if there are optional
   // arguments.
-  DeoptimizationContext(intptr_t* to_frame_start,
-                        intptr_t to_frame_size,
-                        const Array& object_table,
-                        intptr_t num_args,
-                        DeoptReasonId deopt_reason);
+  DeoptContext(const Array& object_table,
+               intptr_t num_args,
+               DeoptReasonId deopt_reason);
 
-  intptr_t* GetFromFrameAddressAt(intptr_t index) const {
-    ASSERT((0 <= index) && (index < from_frame_size_));
-    return &from_frame_[index];
+  virtual ~DeoptContext();
+
+  // Sets the sources (frame and registers) for this deoptimization.
+  //
+  // if 'frame_is_copy' is true, DeoptContext will delete the frame
+  // when it is done.
+  void SetSourceArgs(intptr_t* frame_start,
+                     intptr_t frame_size,
+                     fpu_register_t* fpu_registers,
+                     intptr_t* cpu_registers,
+                     bool frame_is_copy);
+
+  // Sets the destination fraem for this deoptimization.
+  //
+  // 'frame_start' oints to the fixed size portion of the frame under
+  // sp.
+  //
+  // DeoptContext does not claim ownership of the frame memory.
+  void SetDestArgs(intptr_t* frame_start, intptr_t frame_size);
+
+  intptr_t* GetSourceFrameAddressAt(intptr_t index) const {
+    ASSERT(source_frame_ != NULL);
+    ASSERT((0 <= index) && (index < source_frame_size_));
+    return &source_frame_[index];
   }
 
-  intptr_t* GetToFrameAddressAt(intptr_t index) const {
-    ASSERT((0 <= index) && (index < to_frame_size_));
-    return &to_frame_[index];
+  intptr_t* GetDestFrameAddressAt(intptr_t index) const {
+    ASSERT(dest_frame_ != NULL);
+    ASSERT((0 <= index) && (index < dest_frame_size_));
+    return &dest_frame_[index];
   }
 
-  intptr_t GetFromFp() const;
-  intptr_t GetFromPp() const;
-  intptr_t GetFromPc() const;
+  intptr_t GetSourceFp() const;
+  intptr_t GetSourcePp() const;
+  intptr_t GetSourcePc() const;
 
   intptr_t GetCallerFp() const;
   void SetCallerFp(intptr_t callers_fp);
 
   RawObject* ObjectAt(intptr_t index) const {
-    return object_table_.At(index);
+    const Array& object_table = Array::Handle(object_table_);
+    return object_table.At(index);
   }
 
   intptr_t RegisterValue(Register reg) const {
-    return registers_copy_[reg];
+    return cpu_registers_[reg];
   }
 
   double FpuRegisterValue(FpuRegister reg) const {
-    return *reinterpret_cast<double*>(&fpu_registers_copy_[reg]);
+    return *reinterpret_cast<double*>(&fpu_registers_[reg]);
   }
 
   int64_t FpuRegisterValueAsInt64(FpuRegister reg) const {
-    return *reinterpret_cast<int64_t*>(&fpu_registers_copy_[reg]);
+    return *reinterpret_cast<int64_t*>(&fpu_registers_[reg]);
   }
 
   simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const {
-    const float* address = reinterpret_cast<float*>(&fpu_registers_copy_[reg]);
+    const float* address = reinterpret_cast<float*>(&fpu_registers_[reg]);
     return simd128_value_t().readFrom(address);
   }
 
   Isolate* isolate() const { return isolate_; }
 
-  intptr_t from_frame_size() const { return from_frame_size_; }
+  intptr_t source_frame_size() const { return source_frame_size_; }
 
   DeoptReasonId deopt_reason() const { return deopt_reason_; }
 
+  void VisitObjectPointers(ObjectPointerVisitor* visitor);
+
+  void PrepareForDeferredMaterialization(intptr_t count) {
+    if (count > 0) {
+      deferred_objects_ = new DeferredObject*[count];
+      deferred_objects_count_ = count;
+    }
+  }
+
+  DeferredObject* GetDeferredObject(intptr_t idx) const {
+    return deferred_objects_[idx];
+  }
+
+  // Sets the materialized value for some deferred object.
+  //
+  // Claims ownership of the memory for 'object'.
+  void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) {
+    deferred_objects_[idx] = object;
+  }
+
+  intptr_t DeferredObjectsCount() const {
+    return deferred_objects_count_;
+  }
+
+  void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) {
+    deferred_object_refs_ = new DeferredObjectRef(
+        idx,
+        reinterpret_cast<RawInstance**>(slot),
+        deferred_object_refs_);
+  }
+
+  void DeferDoubleMaterialization(double value, RawDouble** slot) {
+    deferred_boxes_ = new DeferredDouble(
+        value,
+        reinterpret_cast<RawInstance**>(slot),
+        deferred_boxes_);
+  }
+
+  void DeferMintMaterialization(int64_t value, RawMint** slot) {
+    deferred_boxes_ = new DeferredMint(
+        value,
+        reinterpret_cast<RawInstance**>(slot),
+        deferred_boxes_);
+  }
+
+  void DeferFloat32x4Materialization(simd128_value_t value,
+                                     RawFloat32x4** slot) {
+    deferred_boxes_ = new DeferredFloat32x4(
+        value,
+        reinterpret_cast<RawInstance**>(slot),
+        deferred_boxes_);
+  }
+
+  void DeferUint32x4Materialization(simd128_value_t value,
+                                    RawUint32x4** slot) {
+    deferred_boxes_ = new DeferredUint32x4(
+        value,
+        reinterpret_cast<RawInstance**>(slot),
+        deferred_boxes_);
+  }
+
+  // Materializes all deferred objects.  Returns the total number of
+  // artificial arguments used during deoptimization.
+  intptr_t MaterializeDeferredObjects();
+
  private:
-  const Array& object_table_;
-  intptr_t* to_frame_;
-  const intptr_t to_frame_size_;
-  intptr_t* from_frame_;
-  intptr_t from_frame_size_;
-  intptr_t* registers_copy_;
-  fpu_register_t* fpu_registers_copy_;
+  RawArray* object_table_;
+  intptr_t* dest_frame_;
+  intptr_t dest_frame_size_;
+  bool source_frame_is_copy_;
+  intptr_t* source_frame_;
+  intptr_t source_frame_size_;
+  intptr_t* cpu_registers_;
+  fpu_register_t* fpu_registers_;
   const intptr_t num_args_;
   const DeoptReasonId deopt_reason_;
   intptr_t caller_fp_;
   Isolate* isolate_;
 
-  DISALLOW_COPY_AND_ASSIGN(DeoptimizationContext);
+  DeferredSlot* deferred_boxes_;
+  DeferredSlot* deferred_object_refs_;
+
+  intptr_t deferred_objects_count_;
+  DeferredObject** deferred_objects_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeoptContext);
 };
 
 
@@ -119,25 +212,24 @@
     kMaterializeObject
   };
 
-  static DeoptInstr* Create(intptr_t kind_as_int, intptr_t from_index);
+  static DeoptInstr* Create(intptr_t kind_as_int, intptr_t source_index);
 
   DeoptInstr() {}
   virtual ~DeoptInstr() {}
 
   virtual const char* ToCString() const = 0;
 
-  virtual void Execute(DeoptimizationContext* deopt_context,
-                       intptr_t* to_addr) = 0;
+  virtual void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) = 0;
 
   virtual DeoptInstr::Kind kind() const = 0;
 
   bool Equals(const DeoptInstr& other) const {
-    return (kind() == other.kind()) && (from_index() == other.from_index());
+    return (kind() == other.kind()) && (source_index() == other.source_index());
   }
 
   // Decode the payload of a suffix command.  Return the suffix length and
   // set the output parameter info_number to the index of the shared suffix.
-  static intptr_t DecodeSuffix(intptr_t from_index, intptr_t* info_number);
+  static intptr_t DecodeSuffix(intptr_t source_index, intptr_t* info_number);
 
   // Get the function and return address which is encoded in this
   // kRetAfterAddress deopt instruction.
@@ -149,13 +241,13 @@
   // materialized by kMaterializeObject instruction.
   static intptr_t GetFieldCount(DeoptInstr* instr) {
     ASSERT(instr->kind() == DeoptInstr::kMaterializeObject);
-    return instr->from_index();
+    return instr->source_index();
   }
 
  protected:
   friend class DeoptInfoBuilder;
 
-  virtual intptr_t from_index() const = 0;
+  virtual intptr_t source_index() const = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(DeoptInstr);
@@ -178,15 +270,15 @@
   // Return address before instruction.
   void AddReturnAddress(const Function& function,
                         intptr_t deopt_id,
-                        intptr_t to_index);
+                        intptr_t dest_index);
 
   // Copy from optimized frame to unoptimized.
-  void AddCopy(Value* value, const Location& from_loc, intptr_t to_index);
-  void AddPcMarker(const Function& function, intptr_t to_index);
-  void AddPp(const Function& function, intptr_t to_index);
-  void AddCallerFp(intptr_t to_index);
-  void AddCallerPp(intptr_t to_index);
-  void AddCallerPc(intptr_t to_index);
+  void AddCopy(Value* value, const Location& source_loc, intptr_t dest_index);
+  void AddPcMarker(const Function& function, intptr_t dest_index);
+  void AddPp(const Function& function, intptr_t dest_index);
+  void AddCallerFp(intptr_t dest_index);
+  void AddCallerPp(intptr_t dest_index);
+  void AddCallerPc(intptr_t dest_index);
 
   // Add object to be materialized. Emit kMaterializeObject instruction.
   void AddMaterialization(MaterializeObjectInstr* mat);
@@ -200,7 +292,7 @@
   // At deoptimization they will be removed by the stub at the very end:
   // after they were used to materialize objects.
   // Returns the index of the next stack slot. Used for verification.
-  intptr_t EmitMaterializationArguments(intptr_t to_index);
+  intptr_t EmitMaterializationArguments(intptr_t dest_index);
 
   RawDeoptInfo* CreateDeoptInfo(const Array& deopt_table);
 
@@ -216,13 +308,13 @@
 
   intptr_t FindOrAddObjectInTable(const Object& obj) const;
   intptr_t FindMaterialization(MaterializeObjectInstr* mat) const;
-  intptr_t CalculateStackIndex(const Location& from_loc) const;
+  intptr_t CalculateStackIndex(const Location& source_loc) const;
 
   intptr_t FrameSize() const {
     return instructions_.length() - frame_start_;
   }
 
-  void AddConstant(const Object& obj, intptr_t to_index);
+  void AddConstant(const Object& obj, intptr_t dest_index);
 
   GrowableArray<DeoptInstr*> instructions_;
   const GrowableObjectArray& object_table_;
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 04cf4f5..5365419 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -609,6 +609,13 @@
 }
 
 
+void Exceptions::ThrowArgumentError(const Instance& arg) {
+  const Array& args = Array::Handle(Array::New(1));
+  args.SetAt(0, arg);
+  Exceptions::ThrowByType(Exceptions::kArgument, args);
+}
+
+
 RawObject* Exceptions::Create(ExceptionType type, const Array& arguments) {
   Library& library = Library::Handle();
   const String* class_name = NULL;
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 79f7e3a..46d8120 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -65,6 +65,7 @@
   static void ThrowByType(ExceptionType type, const Array& arguments);
   static void ThrowOOM();
   static void ThrowStackOverflow();
+  static void ThrowArgumentError(const Instance& arg);
 
   // Returns a RawInstance if the exception is successfully created,
   // otherwise returns a RawError.
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 0f6dce3..b39671b 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -60,9 +60,15 @@
 }
 
 
-GrowableArray<BlockEntryInstr*>* FlowGraph::codegen_block_order(
+bool FlowGraph::ShouldReorderBlocks(const Function& function,
+                                    bool is_optimized) {
+  return is_optimized && FLAG_reorder_basic_blocks && !function.is_intrinsic();
+}
+
+
+GrowableArray<BlockEntryInstr*>* FlowGraph::CodegenBlockOrder(
     bool is_optimized) {
-  return (is_optimized && FLAG_reorder_basic_blocks)
+  return ShouldReorderBlocks(parsed_function().function(), is_optimized)
       ? &optimized_block_order_
       : &reverse_postorder_;
 }
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index db384d0..517a9eb 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -82,7 +82,8 @@
   const GrowableArray<BlockEntryInstr*>& reverse_postorder() const {
     return reverse_postorder_;
   }
-  GrowableArray<BlockEntryInstr*>* codegen_block_order(bool is_optimized);
+  static bool ShouldReorderBlocks(const Function& function, bool is_optimized);
+  GrowableArray<BlockEntryInstr*>* CodegenBlockOrder(bool is_optimized);
 
   // Iterators.
   BlockIterator reverse_postorder_iterator() const {
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index ec2b202..69199f0 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -2151,18 +2151,6 @@
 }
 
 
-void EffectGraphVisitor::TranslateArgumentList(
-    const ArgumentListNode& node,
-    ZoneGrowableArray<Value*>* values) {
-  for (intptr_t i = 0; i < node.length(); ++i) {
-    ValueGraphVisitor for_argument(owner(), temp_index());
-    node.NodeAt(i)->Visit(&for_argument);
-    Append(for_argument);
-    values->Add(for_argument.value());
-  }
-}
-
-
 void EffectGraphVisitor::BuildPushArguments(
     const ArgumentListNode& node,
     ZoneGrowableArray<PushArgumentInstr*>* values) {
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 5013f3e..d022409 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -20,9 +20,9 @@
 // (factory-name-symbol, result-cid, fingerprint).
 // TODO(srdjan): Store the values in the snapshot instead.
 #define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
-  V(ObjectArrayFactory, kArrayCid, 1558200848)                                 \
-  V(GrowableObjectArrayWithData, kGrowableObjectArrayCid, 619965861)           \
-  V(GrowableObjectArrayFactory, kGrowableObjectArrayCid, 1180134731)           \
+  V(_ListFactory, kArrayCid, 1436567945)                                       \
+  V(_GrowableListWithData, kGrowableObjectArrayCid, 461305701)                 \
+  V(_GrowableListFactory, kGrowableObjectArrayCid, 910639199)                  \
   V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 810750844)                      \
   V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1246070930)                   \
   V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 1882603960)     \
@@ -278,8 +278,6 @@
   void HandleStoreLocal(StoreLocalNode* node, bool result_is_needed);
 
   // Helpers for translating parts of the AST.
-  void TranslateArgumentList(const ArgumentListNode& node,
-                             ZoneGrowableArray<Value*>* values);
   void BuildPushArguments(const ArgumentListNode& node,
                           ZoneGrowableArray<PushArgumentInstr*>* values);
 
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 42df32d..2914711 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -69,7 +69,7 @@
     : assembler_(assembler),
       parsed_function_(flow_graph->parsed_function()),
       flow_graph_(*flow_graph),
-      block_order_(*flow_graph->codegen_block_order(is_optimizing)),
+      block_order_(*flow_graph->CodegenBlockOrder(is_optimizing)),
       current_block_(NULL),
       exception_handlers_list_(NULL),
       pc_descriptors_list_(NULL),
@@ -225,6 +225,31 @@
 }
 
 
+void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
+  if (!is_optimizing()) {
+    if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
+      AssertAssignableInstr* assert = instr->AsAssertAssignable();
+      AddCurrentDescriptor(PcDescriptors::kDeopt,
+                           assert->deopt_id(),
+                           assert->token_pos());
+    } else if (instr->IsGuardField() ||
+               (instr->CanBecomeDeoptimizationTarget() && !instr->IsGoto())) {
+      // GuardField and instructions that can be deoptimization targets need
+      // to record their deopt id.  GotoInstr records its own so that it can
+      // control the placement.
+      AddCurrentDescriptor(PcDescriptors::kDeopt,
+                           instr->deopt_id(),
+                           Scanner::kDummyTokenIndex);
+    }
+    AllocateRegistersLocally(instr);
+  } else if (instr->MayThrow()  &&
+             (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
+    // Optimized try-block: Sync locals to fixed stack locations.
+    EmitTrySync(instr, CurrentTryIndex());
+  }
+}
+
+
 void FlowGraphCompiler::VisitBlocks() {
   CompactBlocks();
 
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index f53ad0f..00f31ec 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -340,6 +340,8 @@
 
   void EmitComment(Instruction* instr);
 
+  void EmitEdgeCounter();
+
   void EmitOptimizedInstanceCall(ExternalLabel* target_label,
                                  const ICData& ic_data,
                                  intptr_t argument_count,
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 7353b27..fded60a 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -720,28 +720,6 @@
 }
 
 
-void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
-  if (!is_optimizing()) {
-    if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
-      AssertAssignableInstr* assert = instr->AsAssertAssignable();
-      AddCurrentDescriptor(PcDescriptors::kDeopt,
-                           assert->deopt_id(),
-                           assert->token_pos());
-    } else if (instr->IsGuardField() ||
-               instr->CanBecomeDeoptimizationTarget()) {
-      AddCurrentDescriptor(PcDescriptors::kDeopt,
-                           instr->deopt_id(),
-                           Scanner::kDummyTokenIndex);
-    }
-    AllocateRegistersLocally(instr);
-  } else if (instr->MayThrow()  &&
-             (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
-    // Optimized try-block: Sync locals to fixed stack locations.
-    EmitTrySync(instr, CurrentTryIndex());
-  }
-}
-
-
 void FlowGraphCompiler::EmitTrySyncMove(intptr_t dest_offset,
                                         Location loc,
                                         bool* push_emitted) {
@@ -1275,6 +1253,22 @@
 }
 
 
+void FlowGraphCompiler::EmitEdgeCounter() {
+  // We do not check for overflow when incrementing the edge counter.  The
+  // function should normally be optimized long before the counter can
+  // overflow; and though we do not reset the counters when we optimize or
+  // deoptimize, there is a bound on the number of
+  // optimization/deoptimization cycles we will attempt.
+  const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+  counter.SetAt(0, Smi::Handle(Smi::New(0)));
+  __ Comment("Edge counter");
+  __ LoadObject(R0, counter);
+  __ ldr(IP, FieldAddress(R0, Array::element_offset(0)));
+  __ adds(IP, IP, ShifterOperand(Smi::RawValue(1)));
+  __ str(IP, FieldAddress(R0, Array::element_offset(0)));
+}
+
+
 void FlowGraphCompiler::EmitOptimizedInstanceCall(
     ExternalLabel* target_label,
     const ICData& ic_data,
@@ -1457,9 +1451,11 @@
     __ Push(reg);
     __ PushObject(obj);
     if (is_optimizing()) {
-      __ BranchLink(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
+      __ BranchLinkPatchable(
+          &StubCode::OptimizedIdenticalWithNumberCheckLabel());
     } else {
-      __ BranchLink(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
+      __ BranchLinkPatchable(
+          &StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
     }
     AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
                          Isolate::kNoDeoptId,
@@ -1481,9 +1477,11 @@
     __ Push(left);
     __ Push(right);
     if (is_optimizing()) {
-      __ BranchLink(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
+      __ BranchLinkPatchable(
+          &StubCode::OptimizedIdenticalWithNumberCheckLabel());
     } else {
-      __ BranchLink(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
+      __ BranchLinkPatchable(
+          &StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
     }
     AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
                          Isolate::kNoDeoptId,
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 2ea07d5..cfcde17 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -742,28 +742,6 @@
 }
 
 
-void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
-  if (!is_optimizing()) {
-    if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
-      AssertAssignableInstr* assert = instr->AsAssertAssignable();
-      AddCurrentDescriptor(PcDescriptors::kDeopt,
-                           assert->deopt_id(),
-                           assert->token_pos());
-    } else if (instr->IsGuardField() ||
-               instr->CanBecomeDeoptimizationTarget()) {
-      AddCurrentDescriptor(PcDescriptors::kDeopt,
-                           instr->deopt_id(),
-                           Scanner::kDummyTokenIndex);
-    }
-    AllocateRegistersLocally(instr);
-  } else if (instr->MayThrow()  &&
-             (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
-    // Optimized try-block: Sync locals to fixed stack locations.
-    EmitTrySync(instr, CurrentTryIndex());
-  }
-}
-
-
 void FlowGraphCompiler::EmitTrySyncMove(intptr_t dest_offset,
                                         Location loc,
                                         bool* push_emitted) {
@@ -1323,6 +1301,21 @@
 }
 
 
+void FlowGraphCompiler::EmitEdgeCounter() {
+  // We do not check for overflow when incrementing the edge counter.  The
+  // function should normally be optimized long before the counter can
+  // overflow; and though we do not reset the counters when we optimize or
+  // deoptimize, there is a bound on the number of
+  // optimization/deoptimization cycles we will attempt.
+  const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+  counter.SetAt(0, Smi::Handle(Smi::New(0)));
+  __ Comment("Edge counter");
+  __ LoadObject(EAX, counter);
+  __ addl(FieldAddress(EAX, Array::element_offset(0)),
+          Immediate(Smi::RawValue(1)));
+}
+
+
 void FlowGraphCompiler::EmitOptimizedInstanceCall(
     ExternalLabel* target_label,
     const ICData& ic_data,
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 03b0a9a..e18577e 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -744,28 +744,6 @@
 }
 
 
-void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
-  if (!is_optimizing()) {
-    if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
-      AssertAssignableInstr* assert = instr->AsAssertAssignable();
-      AddCurrentDescriptor(PcDescriptors::kDeopt,
-                           assert->deopt_id(),
-                           assert->token_pos());
-    } else if (instr->IsGuardField() ||
-               instr->CanBecomeDeoptimizationTarget()) {
-      AddCurrentDescriptor(PcDescriptors::kDeopt,
-                           instr->deopt_id(),
-                           Scanner::kDummyTokenIndex);
-    }
-    AllocateRegistersLocally(instr);
-  } else if (instr->MayThrow()  &&
-             (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
-    // Optimized try-block: Sync locals to fixed stack locations.
-    EmitTrySync(instr, CurrentTryIndex());
-  }
-}
-
-
 void FlowGraphCompiler::EmitTrySyncMove(intptr_t dest_offset,
                                         Location loc,
                                         bool* push_emitted) {
@@ -1319,6 +1297,22 @@
 }
 
 
+void FlowGraphCompiler::EmitEdgeCounter() {
+  // We do not check for overflow when incrementing the edge counter.  The
+  // function should normally be optimized long before the counter can
+  // overflow; and though we do not reset the counters when we optimize or
+  // deoptimize, there is a bound on the number of
+  // optimization/deoptimization cycles we will attempt.
+  const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+  counter.SetAt(0, Smi::Handle(Smi::New(0)));
+  __ Comment("Edge counter");
+  __ LoadObject(T0, counter);
+  __ lw(T1, FieldAddress(T0, Array::element_offset(0)));
+  __ AddImmediate(T1, T1, Smi::RawValue(1));
+  __ sw(T1, FieldAddress(T0, Array::element_offset(0)));
+}
+
+
 void FlowGraphCompiler::EmitOptimizedInstanceCall(
     ExternalLabel* target_label,
     const ICData& ic_data,
@@ -1508,9 +1502,11 @@
     __ LoadObject(TMP1, obj);
     __ sw(TMP1, Address(SP, 0 * kWordSize));
     if (is_optimizing()) {
-      __ BranchLink(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
+      __ BranchLinkPatchable(
+          &StubCode::OptimizedIdenticalWithNumberCheckLabel());
     } else {
-      __ BranchLink(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
+      __ BranchLinkPatchable(
+          &StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
     }
     AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
                          Isolate::kNoDeoptId,
@@ -1535,9 +1531,11 @@
     __ sw(left, Address(SP, 1 * kWordSize));
     __ sw(right, Address(SP, 0 * kWordSize));
     if (is_optimizing()) {
-      __ BranchLink(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
+      __ BranchLinkPatchable(
+          &StubCode::OptimizedIdenticalWithNumberCheckLabel());
     } else {
-      __ BranchLink(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
+      __ BranchLinkPatchable(
+          &StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
     }
     AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
                          Isolate::kNoDeoptId,
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index d3c4095..3078762 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -163,9 +163,9 @@
                                            Label* is_true,
                                            Label* is_false) {
   Label fall_through;
-  __ CompareObject(bool_register, Object::null_object());
+  __ CompareObject(bool_register, Object::null_object(), PP);
   __ j(EQUAL, &fall_through, Assembler::kNearJump);
-  __ CompareObject(bool_register, Bool::True());
+  __ CompareObject(bool_register, Bool::True(), PP);
   __ j(EQUAL, is_true);
   __ jmp(is_false);
   __ Bind(&fall_through);
@@ -187,11 +187,11 @@
   __ pushq(instance_reg);  // Instance.
   if (test_kind == kTestTypeOneArg) {
     ASSERT(type_arguments_reg == kNoRegister);
-    __ PushObject(Object::null_object());
+    __ PushObject(Object::null_object(), PP);
     __ Call(&StubCode::Subtype1TestCacheLabel(), PP);
   } else if (test_kind == kTestTypeTwoArgs) {
     ASSERT(type_arguments_reg == kNoRegister);
-    __ PushObject(Object::null_object());
+    __ PushObject(Object::null_object(), PP);
     __ Call(&StubCode::Subtype2TestCacheLabel(), PP);
   } else if (test_kind == kTestTypeThreeArgs) {
     __ pushq(type_arguments_reg);
@@ -342,7 +342,7 @@
     // Check if instance is a closure.
     __ LoadClassById(R13, kClassIdReg);
     __ movq(R13, FieldAddress(R13, Class::signature_function_offset()));
-    __ CompareObject(R13, Object::null_object());
+    __ CompareObject(R13, Object::null_object(), PP);
     __ j(NOT_EQUAL, is_instance_lbl);
   }
   // Custom checking for numbers (Smi, Mint, Bigint and Double).
@@ -380,7 +380,7 @@
   // Check immediate superclass equality.
   __ movq(R13, FieldAddress(R10, Class::super_type_offset()));
   __ movq(R13, FieldAddress(R13, Type::type_class_offset()));
-  __ CompareObject(R13, type_class);
+  __ CompareObject(R13, type_class, PP);
   __ j(EQUAL, is_instance_lbl);
 
   const Register kTypeArgumentsReg = kNoRegister;
@@ -411,7 +411,7 @@
     __ movq(RDX, Address(RSP, 0));  // Get instantiator type arguments.
     // RDX: instantiator type arguments.
     // Check if type argument is dynamic.
-    __ CompareObject(RDX, Object::null_object());
+    __ CompareObject(RDX, Object::null_object(), PP);
     __ j(EQUAL, is_instance_lbl);
     // Can handle only type arguments that are instances of TypeArguments.
     // (runtime checks canonicalize type arguments).
@@ -422,21 +422,21 @@
         FieldAddress(RDX, TypeArguments::type_at_offset(type_param.index())));
     // RDI: Concrete type of type.
     // Check if type argument is dynamic.
-    __ CompareObject(RDI, Type::ZoneHandle(Type::DynamicType()));
+    __ CompareObject(RDI, Type::ZoneHandle(Type::DynamicType()), PP);
     __ j(EQUAL,  is_instance_lbl);
-    __ CompareObject(RDI, Object::null_object());
+    __ CompareObject(RDI, Object::null_object(), PP);
     __ j(EQUAL,  is_instance_lbl);
     const Type& object_type = Type::ZoneHandle(Type::ObjectType());
-    __ CompareObject(RDI, object_type);
+    __ CompareObject(RDI, object_type, PP);
     __ j(EQUAL,  is_instance_lbl);
 
     // For Smi check quickly against int and num interfaces.
     Label not_smi;
     __ testq(RAX, Immediate(kSmiTagMask));  // Value is Smi?
     __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
-    __ CompareObject(RDI, Type::ZoneHandle(Type::IntType()));
+    __ CompareObject(RDI, Type::ZoneHandle(Type::IntType()), PP);
     __ j(EQUAL,  is_instance_lbl);
-    __ CompareObject(RDI, Type::ZoneHandle(Type::Number()));
+    __ CompareObject(RDI, Type::ZoneHandle(Type::Number()), PP);
     __ j(EQUAL,  is_instance_lbl);
     // Smi must be handled in runtime.
     __ jmp(&fall_through);
@@ -577,7 +577,7 @@
     // We can only inline this null check if the type is instantiated at compile
     // time, since an uninstantiated type at compile time could be Object or
     // dynamic at run time.
-    __ CompareObject(RAX, Object::null_object());
+    __ CompareObject(RAX, Object::null_object(), PP);
     __ j(EQUAL, &is_not_instance);
   }
 
@@ -592,9 +592,9 @@
     // Generate runtime call.
     __ movq(RDX, Address(RSP, 0));  // Get instantiator type arguments.
     __ movq(RCX, Address(RSP, kWordSize));  // Get instantiator.
-    __ PushObject(Object::ZoneHandle());  // Make room for the result.
+    __ PushObject(Object::ZoneHandle(), PP);  // Make room for the result.
     __ pushq(RAX);  // Push the instance.
-    __ PushObject(type);  // Push the type.
+    __ PushObject(type, PP);  // Push the type.
     __ pushq(RCX);  // TODO(srdjan): Pass instantiator instead of null.
     __ pushq(RDX);  // Instantiator type arguments.
     __ LoadObject(RAX, test_cache, PP);
@@ -657,13 +657,13 @@
   __ pushq(RDX);  // Store instantiator type arguments.
   // A null object is always assignable and is returned as result.
   Label is_assignable, runtime_call;
-  __ CompareObject(RAX, Object::null_object());
+  __ CompareObject(RAX, Object::null_object(), PP);
   __ j(EQUAL, &is_assignable);
 
   if (!FLAG_eliminate_type_checks || dst_type.IsMalformed()) {
     // If type checks are not eliminated during the graph building then
     // a transition sentinel can be seen here.
-    __ CompareObject(RAX, Object::transition_sentinel());
+    __ CompareObject(RAX, Object::transition_sentinel(), PP);
     __ j(EQUAL, &is_assignable);
   }
 
@@ -678,10 +678,10 @@
     }
     const String& error_message = String::ZoneHandle(
         Symbols::New(error.ToErrorCString()));
-    __ PushObject(Object::ZoneHandle());  // Make room for the result.
+    __ PushObject(Object::ZoneHandle(), PP);  // Make room for the result.
     __ pushq(RAX);  // Push the source object.
-    __ PushObject(dst_name);  // Push the name of the destination.
-    __ PushObject(error_message);
+    __ PushObject(dst_name, PP);  // Push the name of the destination.
+    __ PushObject(error_message, PP);
     GenerateCallRuntime(token_pos,
                         deopt_id,
                         kMalformedTypeErrorRuntimeEntry,
@@ -704,12 +704,12 @@
   __ Bind(&runtime_call);
   __ movq(RDX, Address(RSP, 0));  // Get instantiator type arguments.
   __ movq(RCX, Address(RSP, kWordSize));  // Get instantiator.
-  __ PushObject(Object::ZoneHandle());  // Make room for the result.
+  __ PushObject(Object::ZoneHandle(), PP);  // Make room for the result.
   __ pushq(RAX);  // Push the source object.
-  __ PushObject(dst_type);  // Push the type of the destination.
+  __ PushObject(dst_type, PP);  // Push the type of the destination.
   __ pushq(RCX);  // Instantiator.
   __ pushq(RDX);  // Instantiator type arguments.
-  __ PushObject(dst_name);  // Push the name of the destination.
+  __ PushObject(dst_name, PP);  // Push the name of the destination.
   __ LoadObject(RAX, test_cache, PP);
   __ pushq(RAX);
   GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
@@ -724,28 +724,6 @@
 }
 
 
-void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
-  if (!is_optimizing()) {
-    if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
-      AssertAssignableInstr* assert = instr->AsAssertAssignable();
-      AddCurrentDescriptor(PcDescriptors::kDeopt,
-                           assert->deopt_id(),
-                           assert->token_pos());
-    } else if (instr->IsGuardField() ||
-               instr->CanBecomeDeoptimizationTarget()) {
-      AddCurrentDescriptor(PcDescriptors::kDeopt,
-                           instr->deopt_id(),
-                           Scanner::kDummyTokenIndex);
-    }
-    AllocateRegistersLocally(instr);
-  } else if (instr->MayThrow()  &&
-             (CurrentTryIndex() != CatchClauseNode::kInvalidTryIndex)) {
-    // Optimized try-block: Sync locals to fixed stack locations.
-    EmitTrySync(instr, CurrentTryIndex());
-  }
-}
-
-
 void FlowGraphCompiler::EmitTrySyncMove(intptr_t dest_offset,
                                         Location loc,
                                         bool* push_emitted) {
@@ -844,10 +822,10 @@
           FieldAddress(R10, ArgumentsDescriptor::positional_count_offset()));
   // Check that min_num_pos_args <= num_pos_args.
   Label wrong_num_arguments;
-  __ cmpq(RCX, Immediate(Smi::RawValue(min_num_pos_args)));
+  __ CompareImmediate(RCX, Immediate(Smi::RawValue(min_num_pos_args)), PP);
   __ j(LESS, &wrong_num_arguments);
   // Check that num_pos_args <= max_num_pos_args.
-  __ cmpq(RCX, Immediate(Smi::RawValue(max_num_pos_args)));
+  __ CompareImmediate(RCX, Immediate(Smi::RawValue(max_num_pos_args)), PP);
   __ j(GREATER, &wrong_num_arguments);
 
   // Copy positional arguments.
@@ -929,14 +907,15 @@
       // Load RAX with the name of the argument.
       __ movq(RAX, Address(RDI, ArgumentsDescriptor::name_offset()));
       ASSERT(opt_param[i]->name().IsSymbol());
-      __ CompareObject(RAX, opt_param[i]->name());
+      __ CompareObject(RAX, opt_param[i]->name(), PP);
       __ j(NOT_EQUAL, &load_default_value, Assembler::kNearJump);
       // Load RAX with passed-in argument at provided arg_pos, i.e. at
       // fp[kParamEndSlotFromFp + num_args - arg_pos].
       __ movq(RAX, Address(RDI, ArgumentsDescriptor::position_offset()));
       // RAX is arg_pos as Smi.
       // Point to next named entry.
-      __ addq(RDI, Immediate(ArgumentsDescriptor::named_entry_size()));
+      __ AddImmediate(
+          RDI, Immediate(ArgumentsDescriptor::named_entry_size()), PP);
       __ negq(RAX);
       Address argument_addr(RBX, RAX, TIMES_4, 0);  // RAX is a negative Smi.
       __ movq(RAX, argument_addr);
@@ -976,7 +955,7 @@
       // arguments have been passed, where k is param_pos, the position of this
       // optional parameter in the formal parameter list.
       const int param_pos = num_fixed_params + i;
-      __ cmpq(RCX, Immediate(param_pos));
+      __ CompareImmediate(RCX, Immediate(param_pos), PP);
       __ j(GREATER, &next_parameter, Assembler::kNearJump);
       // Load RAX with default argument.
       const Object& value = Object::ZoneHandle(
@@ -1101,12 +1080,16 @@
     if (is_optimizing()) {
       // Reoptimization of an optimized function is triggered by counting in
       // IC stubs, but not at the entry of the function.
-      __ cmpq(FieldAddress(function_reg, Function::usage_counter_offset()),
-              Immediate(FLAG_reoptimization_counter_threshold));
+      __ CompareImmediate(
+          FieldAddress(function_reg, Function::usage_counter_offset()),
+          Immediate(FLAG_reoptimization_counter_threshold),
+          new_pp);
     } else {
       __ incq(FieldAddress(function_reg, Function::usage_counter_offset()));
-      __ cmpq(FieldAddress(function_reg, Function::usage_counter_offset()),
-              Immediate(FLAG_optimization_counter_threshold));
+      __ CompareImmediate(
+          FieldAddress(function_reg, Function::usage_counter_offset()),
+          Immediate(FLAG_optimization_counter_threshold),
+          new_pp);
     }
     ASSERT(function_reg == RDI);
     __ J(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel(), R13);
@@ -1181,7 +1164,7 @@
       // Check that exactly num_fixed arguments are passed in.
       Label correct_num_arguments, wrong_num_arguments;
       __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-      __ cmpq(RAX, Immediate(Smi::RawValue(num_fixed_params)));
+      __ CompareImmediate(RAX, Immediate(Smi::RawValue(num_fixed_params)), PP);
       __ j(NOT_EQUAL, &wrong_num_arguments, Assembler::kNearJump);
       __ cmpq(RAX,
               FieldAddress(R10,
@@ -1353,6 +1336,21 @@
 }
 
 
+void FlowGraphCompiler::EmitEdgeCounter() {
+  // We do not check for overflow when incrementing the edge counter.  The
+  // function should normally be optimized long before the counter can
+  // overflow; and though we do not reset the counters when we optimize or
+  // deoptimize, there is a bound on the number of
+  // optimization/deoptimization cycles we will attempt.
+  const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
+  counter.SetAt(0, Smi::Handle(Smi::New(0)));
+  __ Comment("Edge counter");
+  __ LoadObject(RAX, counter, PP);
+  __ AddImmediate(FieldAddress(RAX, Array::element_offset(0)),
+                  Immediate(Smi::RawValue(1)), PP);
+}
+
+
 void FlowGraphCompiler::EmitOptimizedInstanceCall(
     ExternalLabel* target_label,
     const ICData& ic_data,
@@ -1410,7 +1408,7 @@
   __ movq(RAX, Address(RSP, (argument_count - 1) * kWordSize));
   __ testq(RAX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
-  __ movq(RAX, Immediate(Smi::RawValue(kSmiCid)));
+  __ LoadImmediate(RAX, Immediate(Smi::RawValue(kSmiCid)), PP);
   __ jmp(&load_cache);
 
   __ Bind(&not_smi);
@@ -1430,7 +1428,7 @@
   __ jmp(&loop);
 
   __ Bind(&update);
-  __ addq(RCX, Immediate(Smi::RawValue(1)));
+  __ AddImmediate(RCX, Immediate(Smi::RawValue(1)), PP);
   __ Bind(&loop);
   __ andq(RCX, RBX);
   const intptr_t base = Array::data_offset();
@@ -1453,7 +1451,8 @@
   __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
   __ LoadObject(RBX, ic_data, PP);
   __ LoadObject(R10, arguments_descriptor, PP);
-  __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
+  __ AddImmediate(
+      RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag), PP);
   __ call(RAX);
   AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
@@ -1500,7 +1499,7 @@
 
   if (needs_number_check) {
     __ pushq(reg);
-    __ PushObject(obj);
+    __ PushObject(obj, PP);
     if (is_optimizing()) {
       __ CallPatchable(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
     } else {
@@ -1514,7 +1513,7 @@
     return;
   }
 
-  __ CompareObject(reg, obj);
+  __ CompareObject(reg, obj, PP);
 }
 
 
@@ -1547,7 +1546,7 @@
   // TODO(vegorov): consider saving only caller save (volatile) registers.
   const intptr_t xmm_regs_count = locs->live_registers()->fpu_regs_count();
   if (xmm_regs_count > 0) {
-    __ subq(RSP, Immediate(xmm_regs_count * kFpuRegisterSize));
+    __ AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize), PP);
     // Store XMM registers with the lowest register number at the lowest
     // address.
     intptr_t offset = 0;
@@ -1594,7 +1593,7 @@
       }
     }
     ASSERT(offset == (xmm_regs_count * kFpuRegisterSize));
-    __ addq(RSP, Immediate(offset));
+    __ AddImmediate(RSP, Immediate(offset), PP);
   }
 }
 
@@ -1890,7 +1889,7 @@
 
 
 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) {
-  __ StoreObject(dst, obj);
+  __ StoreObject(dst, obj, PP);
 }
 
 
@@ -1926,14 +1925,14 @@
 
 
 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) {
-  __ subq(RSP, Immediate(kFpuRegisterSize));
+  __ AddImmediate(RSP, Immediate(-kFpuRegisterSize), PP);
   __ movups(Address(RSP, 0), reg);
 }
 
 
 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
   __ movups(reg, Address(RSP, 0));
-  __ addq(RSP, Immediate(kFpuRegisterSize));
+  __ AddImmediate(RSP, Immediate(kFpuRegisterSize), PP);
 }
 
 
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 7da716a..b9f6bd4 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -692,8 +692,6 @@
 
   const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks());
 
-  if (ic_data.NumberOfChecks() == 0) return kIllegalCid;
-  // TODO(vegorov): Add multiple receiver type support.
   if (ic_data.NumberOfChecks() != 1) return kIllegalCid;
   ASSERT(ic_data.HasOneTarget());
 
@@ -1069,9 +1067,13 @@
     case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed:
     case MethodRecognizer::kInt16ArrayGetIndexed:
     case MethodRecognizer::kUint16ArrayGetIndexed:
+      return TryInlineGetIndexed(kind, call, ic_data, entry, last);
+    case MethodRecognizer::kFloat32x4ArrayGetIndexed:
+      if (!ShouldInlineSimd()) return false;
+      return TryInlineGetIndexed(kind, call, ic_data, entry, last);
     case MethodRecognizer::kInt32ArrayGetIndexed:
     case MethodRecognizer::kUint32ArrayGetIndexed:
-    case MethodRecognizer::kFloat32x4ArrayGetIndexed:
+      if (!CanUnboxInt32()) return false;
       return TryInlineGetIndexed(kind, call, ic_data, entry, last);
     default:
       return false;
@@ -1176,44 +1178,22 @@
 
 
 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) {
-  const intptr_t class_id = ReceiverClassId(call);
-  switch (class_id) {
-    case kArrayCid:
-    case kImmutableArrayCid:
-    case kGrowableObjectArrayCid:
-    case kTypedDataFloat32ArrayCid:
-    case kTypedDataFloat64ArrayCid:
-    case kTypedDataInt8ArrayCid:
-    case kTypedDataUint8ArrayCid:
-    case kTypedDataUint8ClampedArrayCid:
-    case kExternalTypedDataUint8ArrayCid:
-    case kExternalTypedDataUint8ClampedArrayCid:
-    case kTypedDataInt16ArrayCid:
-    case kTypedDataUint16ArrayCid:
-      break;
-    case kTypedDataFloat32x4ArrayCid:
-      if (!ShouldInlineSimd()) {
-        return false;
-      }
-      break;
-    case kTypedDataInt32ArrayCid:
-    case kTypedDataUint32ArrayCid:
-        if (!CanUnboxInt32()) return false;
-      break;
-    default:
-      return false;
-  }
+  // Check for monomorphic IC data.
+  if (!call->HasICData()) return false;
+  const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks());
+  if (ic_data.NumberOfChecks() != 1) return false;
+  ASSERT(ic_data.HasOneTarget());
 
-  const Function& target =
-      Function::Handle(call->ic_data()->GetTargetAt(0));
+  const Function& target = Function::Handle(ic_data.GetTargetAt(0));
   TargetEntryInstr* entry;
   Definition* last;
-  ASSERT(class_id == MethodKindToCid(MethodRecognizer::RecognizeKind(target)));
-  bool success = TryInlineRecognizedMethod(target,
-                                           call,
-                                           *call->ic_data(),
-                                           &entry, &last);
-  ASSERT(success);
+  if (!TryInlineRecognizedMethod(target,
+                                 call,
+                                 *call->ic_data(),
+                                 &entry, &last)) {
+    return false;
+  }
+
   // Insert receiver class check.
   AddReceiverCheck(call);
   // Remove the original push arguments.
@@ -4168,7 +4148,7 @@
     switch (instr->tag()) {
       case Instruction::kLoadField: {
         LoadFieldInstr* load_field = instr->AsLoadField();
-        instance_ = load_field->instance()->definition();
+        instance_ = OriginalDefinition(load_field->instance()->definition());
         if (load_field->field() != NULL) {
           kind_ = kField;
           field_ = load_field->field();
@@ -4184,7 +4164,8 @@
         StoreInstanceFieldInstr* store_instance_field =
             instr->AsStoreInstanceField();
         kind_ = kField;
-        instance_ = store_instance_field->instance()->definition();
+        instance_ =
+            OriginalDefinition(store_instance_field->instance()->definition());
         field_ = &store_instance_field->field();
         break;
       }
@@ -4192,7 +4173,7 @@
       case Instruction::kStoreVMField: {
         StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField();
         kind_ = kVMField;
-        instance_ = store_vm_field->dest()->definition();
+        instance_ = OriginalDefinition(store_vm_field->dest()->definition());
         offset_in_bytes_ = store_vm_field->offset_in_bytes();
         break;
       }
@@ -4211,7 +4192,7 @@
       case Instruction::kLoadIndexed: {
         LoadIndexedInstr* load_indexed = instr->AsLoadIndexed();
         kind_ = kIndexed;
-        instance_ = load_indexed->array()->definition();
+        instance_ = OriginalDefinition(load_indexed->array()->definition());
         index_ = load_indexed->index()->definition();
         *is_load = true;
         break;
@@ -4220,7 +4201,7 @@
       case Instruction::kStoreIndexed: {
         StoreIndexedInstr* store_indexed = instr->AsStoreIndexed();
         kind_ = kIndexed;
-        instance_ = store_indexed->array()->definition();
+        instance_ = OriginalDefinition(store_indexed->array()->definition());
         index_ = store_indexed->index()->definition();
         break;
       }
@@ -4251,7 +4232,7 @@
 
   void set_instance(Definition* def) {
     ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed));
-    instance_ = def;
+    instance_ = OriginalDefinition(def);
   }
 
   const Field& field() const {
@@ -4322,6 +4303,13 @@
   static Place* Wrap(const Place& place);
 
  private:
+  static Definition* OriginalDefinition(Definition* defn) {
+    while (defn->IsRedefinition()) {
+      defn = defn->AsRedefinition()->value()->definition();
+    }
+    return defn;
+  }
+
   bool SameField(Place* other) const {
     return (kind_ == kField) ? (field().raw() == other->field().raw())
                              : (offset_in_bytes_ == other->offset_in_bytes_);
@@ -6048,6 +6036,80 @@
 
 void ConstantPropagator::VisitStaticCall(StaticCallInstr* instr) {
   SetValue(instr, non_constant_);
+  return;
+  // TODO(srdjan): Enable code below once issues resolved.
+  if (IsNonConstant(instr->constant_value())) {
+    // Do not bother with costly analysis if we already know that the
+    // instruction is not a constant.
+    SetValue(instr, non_constant_);
+    return;
+  }
+  MethodRecognizer::Kind recognized_kind =
+      MethodRecognizer::RecognizeKind(instr->function());
+  if (recognized_kind == MethodRecognizer::kStringBaseInterpolate) {
+    // static String _interpolate(List values)
+    //
+    // Code for calling interpolate is generated by the compiler:
+    //   v2 <- CreateArray(v0)
+    //   StoreIndexed(v2, v3, v4)   -- v3:constant index, v4: value.
+    //   ..
+    //   PushArgument(v2)
+    //   v8 <- StaticCall(_interpolate, v2)
+    // Detect that all values are constant, interpolate at compile
+    // time.
+    ASSERT(instr->ArgumentCount() == 1);
+    CreateArrayInstr* create_array = instr->ArgumentAt(0)->AsCreateArray();
+    ASSERT(create_array != NULL);
+    // Check if the string interpolation has only constant inputs.
+    for (Value::Iterator it(create_array->input_use_list());
+         !it.Done();
+         it.Advance()) {
+      Instruction* curr = it.Current()->instruction();
+      StoreIndexedInstr* store = curr->AsStoreIndexed();
+      // 'store' is NULL fir PushArgument instruction: skip it.
+      if ((store != NULL) &&
+          (IsNonConstant(store->value()->definition()->constant_value()))) {
+        SetValue(instr, non_constant_);
+        return;
+      }
+    }
+    // Interpolate string at compile time.
+    const Array& value_arr =
+        Array::Handle(Array::New(create_array->num_elements()));
+    // Build the array of literal values to interpolate, abort if a value is
+    // not literal.
+    for (Value::Iterator it(create_array->input_use_list());
+         !it.Done();
+         it.Advance()) {
+      Instruction* curr = it.Current()->instruction();
+      StoreIndexedInstr* store = curr->AsStoreIndexed();
+      if (store == NULL) {
+        ASSERT(curr == instr->PushArgumentAt(0));
+      } else {
+        Value* index_value = store->index();
+        ASSERT(index_value->BindsToConstant() && index_value->IsSmiValue());
+        const intptr_t ix = Smi::Cast(index_value->BoundConstant()).Value();
+        ASSERT(IsConstant(store->value()->definition()->constant_value()));
+        value_arr.SetAt(ix, store->value()->definition()->constant_value());
+      }
+    }
+    // Build argument array to pass to the interpolation function.
+    const Array& interpolate_arg = Array::Handle(Array::New(1));
+    interpolate_arg.SetAt(0, value_arr);
+    // Call interpolation function.
+    String& concatenated = String::ZoneHandle();
+    concatenated ^=
+        DartEntry::InvokeFunction(instr->function(), interpolate_arg);
+    if (concatenated.IsUnhandledException()) {
+      SetValue(instr, non_constant_);
+      return;
+    }
+
+    concatenated = Symbols::New(concatenated);
+    SetValue(instr, concatenated);
+  } else {
+    SetValue(instr, non_constant_);
+  }
 }
 
 
@@ -6300,6 +6362,16 @@
 
 
 void ConstantPropagator::VisitLoadClassId(LoadClassIdInstr* instr) {
+  intptr_t cid = instr->object()->Type()->ToCid();
+  if (cid != kDynamicCid) {
+    SetValue(instr, Smi::ZoneHandle(Smi::New(cid)));
+    return;
+  }
+  const Object& object = instr->object()->definition()->constant_value();
+  if (IsConstant(object)) {
+    SetValue(instr, Smi::ZoneHandle(Smi::New(object.GetClassId())));
+    return;
+  }
   SetValue(instr, non_constant_);
 }
 
@@ -6870,6 +6942,27 @@
 }
 
 
+// Code for calling interpolate is generated by the compiler:
+//   v2 <- CreateArray(v0)
+//   StoreIndexed(v2, v3, v4)   -- v3:constant index, v4: value.
+//   ..
+//   PushArgument(v2)
+//   v8 <- StaticCall(_interpolate, v2)
+// Remove the inputs.
+void ConstantPropagator::RemoveInterpolationInputs(
+    const StaticCallInstr& call) {
+  ASSERT(call.ArgumentCount() == 1);
+  CreateArrayInstr* create_array = call.ArgumentAt(0)->AsCreateArray();
+  ASSERT(create_array != NULL);
+  for (Value* use = create_array->input_use_list();
+      use != NULL;
+      use = create_array->input_use_list()) {
+    use->instruction()->RemoveFromGraph();
+  }
+  create_array->RemoveFromGraph();
+}
+
+
 void ConstantPropagator::Transform() {
   if (FLAG_trace_constant_propagation) {
     OS::Print("\n==== Before constant propagation ====\n");
@@ -6977,6 +7070,13 @@
         ConstantInstr* constant = graph_->GetConstant(defn->constant_value());
         defn->ReplaceUsesWith(constant);
         i.RemoveCurrentFromGraph();
+        if (defn->IsStaticCall()) {
+          MethodRecognizer::Kind recognized_kind =
+              MethodRecognizer::RecognizeKind(defn->AsStaticCall()->function());
+          if (recognized_kind == MethodRecognizer::kStringBaseInterpolate) {
+            RemoveInterpolationInputs(*defn->AsStaticCall());
+          }
+        }
       }
     }
 
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 8c9f6fe..1879186 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -282,6 +282,8 @@
                       const Value& left,
                       const Value& right);
 
+  void RemoveInterpolationInputs(const StaticCallInstr& call);
+
   virtual void VisitBlocks() { UNREACHABLE(); }
 
 #define DECLARE_VISIT(type) virtual void Visit##type(type##Instr* instr);
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index 5c442da..80817b5 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -650,7 +650,8 @@
 
 
 void Float32x4ComparisonInstr::PrintOperandsTo(BufferFormatter* f) const {
-  f->Print("Float32x4 Comparison %d", op_kind());
+  f->Print("Float32x4 Comparison %s, ",
+           MethodRecognizer::KindToCString(op_kind()));
   left()->PrintTo(f);
   f->Print(", ");
   right()->PrintTo(f);
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index 4ae5936..9cc0d58 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -13,88 +13,99 @@
 namespace dart {
 
 CallPattern::CallPattern(uword pc, const Code& code)
-    : end_(reinterpret_cast<uword*>(pc)),
+    : object_pool_(Array::Handle(code.ObjectPool())),
+      end_(pc),
+      args_desc_load_end_(0),
+      ic_data_load_end_(0),
       target_address_pool_index_(-1),
-      args_desc_load_end_(-1),
       args_desc_(Array::Handle()),
-      ic_data_load_end_(-1),
-      ic_data_(ICData::Handle()),
-      object_pool_(Array::Handle(code.ObjectPool())) {
+      ic_data_(ICData::Handle()) {
   ASSERT(code.ContainsInstructionAt(pc));
-  ASSERT(Back(1) == 0xe12fff3e);  // Last instruction: blx lr
+  // Last instruction: blx lr.
+  ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e);
+
   Register reg;
   ic_data_load_end_ =
-      DecodeLoadWordFromPool(1, &reg, &target_address_pool_index_);
+      InstructionPattern::DecodeLoadWordFromPool(end_ - Instr::kInstrSize,
+                                                 &reg,
+                                                 &target_address_pool_index_);
   ASSERT(reg == LR);
 }
 
 
-uword CallPattern::Back(int n) const {
-  ASSERT(n > 0);
-  return *(end_ - n);
-}
-
-
-// Decodes a load sequence ending at end. Returns the register being loaded and
-// the loaded object.
-// Returns the location of the load sequence, counting the number of
-// instructions back from the end of the call pattern.
-int CallPattern::DecodeLoadObject(int end, Register* reg, Object* obj) {
-  ASSERT(end > 0);
-  uword instr = Back(end + 1);
-  if ((instr & 0xfff00000) == 0xe5900000) {  // ldr reg, [reg, #+offset]
-    int index = 0;
-    end = DecodeLoadWordFromPool(end, reg, &index);
-    *obj = object_pool_.At(index);
+// Decodes a load sequence ending at 'end' (the last instruction of the load
+// sequence is the instruction before the one at end).  Returns a pointer to
+// the first instruction in the sequence.  Returns the register being loaded
+// and the loaded object in the output parameters 'reg' and 'obj'
+// respectively.
+uword InstructionPattern::DecodeLoadObject(uword end,
+                                           const Array& object_pool,
+                                           Register* reg,
+                                           Object* obj) {
+  uword start = 0;
+  Instr* instr = Instr::At(end - Instr::kInstrSize);
+  if ((instr->InstructionBits() & 0xfff00000) == 0xe5900000) {
+    // ldr reg, [reg, #+offset]
+    intptr_t index = 0;
+    start = DecodeLoadWordFromPool(end, reg, &index);
+    *obj = object_pool.At(index);
   } else {
-    int value = 0;
-    end = DecodeLoadWordImmediate(end, reg, &value);
+    intptr_t value = 0;
+    start = DecodeLoadWordImmediate(end, reg, &value);
     *obj = reinterpret_cast<RawObject*>(value);
   }
-  return end;
+  return start;
 }
 
 
-// Decodes a load sequence ending at end. Returns the register being loaded and
-// the loaded immediate value.
-// Returns the location of the load sequence, counting the number of
-// instructions back from the end of the call pattern.
-int CallPattern::DecodeLoadWordImmediate(int end, Register* reg, int* value) {
-  ASSERT(end > 0);
-  uword instr = Back(++end);
-  int imm = 0;
+// Decodes a load sequence ending at 'end' (the last instruction of the load
+// sequence is the instruction before the one at end).  Returns a pointer to
+// the first instruction in the sequence.  Returns the register being loaded
+// and the loaded immediate value in the output parameters 'reg' and 'value'
+// respectively.
+uword InstructionPattern::DecodeLoadWordImmediate(uword end,
+                                                  Register* reg,
+                                                  intptr_t* value) {
+  uword start = end - Instr::kInstrSize;
+  int32_t instr = Instr::At(start)->InstructionBits();
+  intptr_t imm = 0;
   if ((instr & 0xfff00000) == 0xe3400000) {  // movt reg, #imm_hi
     imm |= (instr & 0xf0000) << 12;
     imm |= (instr & 0xfff) << 16;
-    instr = Back(++end);
+    start -= Instr::kInstrSize;
+    instr = Instr::At(start)->InstructionBits();
   }
   ASSERT((instr & 0xfff00000) == 0xe3000000);  // movw reg, #imm_lo
   imm |= (instr & 0xf0000) >> 4;
   imm |= instr & 0xfff;
   *reg = static_cast<Register>((instr & 0xf000) >> 12);
   *value = imm;
-  return end;
+  return start;
 }
 
 
-// Decodes a load sequence ending at end. Returns the register being loaded and
-// the index in the pool being read from.
-// Returns the location of the load sequence, counting the number of
-// instructions back from the end of the call pattern.
-int CallPattern::DecodeLoadWordFromPool(int end, Register* reg, int* index) {
-  ASSERT(end > 0);
-  uword instr = Back(++end);
-  int offset = 0;
+// Decodes a load sequence ending at 'end' (the last instruction of the load
+// sequence is the instruction before the one at end).  Returns a pointer to
+// the first instruction in the sequence.  Returns the register being loaded
+// and the index in the pool being read from in the output parameters 'reg'
+// and 'index' respectively.
+uword InstructionPattern::DecodeLoadWordFromPool(uword end,
+                                                 Register* reg,
+                                                 intptr_t* index) {
+  uword start = end - Instr::kInstrSize;
+  int32_t instr = Instr::At(start)->InstructionBits();
+  intptr_t offset = 0;
   if ((instr & 0xffff0000) == 0xe59a0000) {  // ldr reg, [pp, #+offset]
     offset = instr & 0xfff;
     *reg = static_cast<Register>((instr & 0xf000) >> 12);
   } else {
     ASSERT((instr & 0xfff00000) == 0xe5900000);  // ldr reg, [reg, #+offset]
     offset = instr & 0xfff;
-    instr = Back(++end);
+    start -= Instr::kInstrSize;
+    instr = Instr::At(start)->InstructionBits();
     if ((instr & 0xffff0000) == 0xe28a0000) {  // add reg, pp, shifter_op
-      const int rot = (instr & 0xf00) >> 7;
-      const int imm8 = instr & 0xff;
+      const intptr_t rot = (instr & 0xf00) >> 7;
+      const intptr_t imm8 = instr & 0xff;
       offset += (imm8 >> rot) | (imm8 << (32 - rot));
       *reg = static_cast<Register>((instr & 0xf000) >> 12);
     } else {
@@ -104,15 +115,19 @@
   }
   offset += kHeapObjectTag;
   ASSERT(Utils::IsAligned(offset, 4));
-  *index = (offset - Array::data_offset())/4;
-  return end;
+  *index = (offset - Array::data_offset()) / 4;
+  return start;
 }
 
 
 RawICData* CallPattern::IcData() {
   if (ic_data_.IsNull()) {
     Register reg;
-    args_desc_load_end_ = DecodeLoadObject(ic_data_load_end_, &reg, &ic_data_);
+    args_desc_load_end_ =
+        InstructionPattern::DecodeLoadObject(ic_data_load_end_,
+                                             object_pool_,
+                                             &reg,
+                                             &ic_data_);
     ASSERT(reg == R5);
   }
   return ic_data_.raw();
@@ -123,7 +138,10 @@
   if (args_desc_.IsNull()) {
     IcData();  // Loading of the ic_data must be decoded first, if not already.
     Register reg;
-    DecodeLoadObject(args_desc_load_end_, &reg, &args_desc_);
+    InstructionPattern::DecodeLoadObject(args_desc_load_end_,
+                                         object_pool_,
+                                         &reg,
+                                         &args_desc_);
     ASSERT(reg == R4);
   }
   return args_desc_.raw();
@@ -198,4 +216,3 @@
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM
-
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index 59cb259..05235d1 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -15,6 +15,38 @@
 
 namespace dart {
 
+class InstructionPattern : public AllStatic {
+ public:
+  // Decodes a load sequence ending at 'end' (the last instruction of the
+  // load sequence is the instruction before the one at end).  Returns the
+  // address of the first instruction in the sequence.  Returns the register
+  // being loaded and the loaded object in the output parameters 'reg' and
+  // 'obj' respectively.
+  static uword DecodeLoadObject(uword end,
+                                const Array& object_pool,
+                                Register* reg,
+                                Object* obj);
+
+  // Decodes a load sequence ending at 'end' (the last instruction of the
+  // load sequence is the instruction before the one at end).  Returns the
+  // address of the first instruction in the sequence.  Returns the register
+  // being loaded and the loaded immediate value in the output parameters
+  // 'reg' and 'value' respectively.
+  static uword DecodeLoadWordImmediate(uword end,
+                                       Register* reg,
+                                       intptr_t* value);
+
+  // Decodes a load sequence ending at 'end' (the last instruction of the
+  // load sequence is the instruction before the one at end).  Returns the
+  // address of the first instruction in the sequence.  Returns the register
+  // being loaded and the index in the pool being read from in the output
+  // parameters 'reg' and 'index' respectively.
+  static uword DecodeLoadWordFromPool(uword end,
+                                      Register* reg,
+                                      intptr_t* index);
+};
+
+
 class CallPattern : public ValueObject {
  public:
   CallPattern(uword pc, const Code& code);
@@ -32,18 +64,16 @@
   static void InsertAt(uword pc, uword target_address);
 
  private:
-  uword Back(int n) const;
-  int DecodeLoadObject(int end, Register* reg, Object* obj);
-  int DecodeLoadWordImmediate(int end, Register* reg, int* value);
-  int DecodeLoadWordFromPool(int end, Register* reg, int* index);
-  const uword* end_;
-  int target_address_pool_index_;
-  int args_desc_load_end_;
-  Array& args_desc_;
-  int ic_data_load_end_;
-  ICData& ic_data_;
   const Array& object_pool_;
 
+  uword end_;
+  uword args_desc_load_end_;
+  uword ic_data_load_end_;
+
+  intptr_t target_address_pool_index_;
+  Array& args_desc_;
+  ICData& ic_data_;
+
   DISALLOW_COPY_AND_ASSIGN(CallPattern);
 };
 
@@ -71,4 +101,3 @@
 }  // namespace dart
 
 #endif  // VM_INSTRUCTIONS_ARM_H_
-
diff --git a/runtime/vm/instructions_mips.cc b/runtime/vm/instructions_mips.cc
index 7215ec0..ae6fbf2 100644
--- a/runtime/vm/instructions_mips.cc
+++ b/runtime/vm/instructions_mips.cc
@@ -13,82 +13,88 @@
 namespace dart {
 
 CallPattern::CallPattern(uword pc, const Code& code)
-    : end_(reinterpret_cast<uword*>(pc)),
+    : object_pool_(Array::Handle(code.ObjectPool())),
+      end_(pc),
+      args_desc_load_end_(0),
+      ic_data_load_end_(0),
       target_address_pool_index_(-1),
-      args_desc_load_end_(-1),
       args_desc_(Array::Handle()),
-      ic_data_load_end_(-1),
-      ic_data_(ICData::Handle()),
-      object_pool_(Array::Handle(code.ObjectPool())) {
+      ic_data_(ICData::Handle()) {
   ASSERT(code.ContainsInstructionAt(pc));
-  ASSERT(Back(2) == 0x0020f809);  // Last instruction: jalr RA, TMP(=R1)
+  // Last instruction: jalr RA, TMP(=R1).
+  ASSERT(*(reinterpret_cast<uword*>(end_) - 2) == 0x0020f809);
   Register reg;
-  // First end is 0 so that we begin from the delay slot of the jalr.
+  // The end of the pattern is the instruction after the delay slot of the jalr.
   ic_data_load_end_ =
-      DecodeLoadWordFromPool(2, &reg, &target_address_pool_index_);
+      InstructionPattern::DecodeLoadWordFromPool(end_ - (2 * Instr::kInstrSize),
+                                                 &reg,
+                                                 &target_address_pool_index_);
   ASSERT(reg == TMP);
 }
 
 
-uword CallPattern::Back(int n) const {
-  ASSERT(n > 0);
-  return *(end_ - n);
-}
-
-
-// Decodes a load sequence ending at end. Returns the register being loaded and
-// the loaded object.
-// Returns the location of the load sequence, counting the number of
-// instructions back from the end of the call pattern.
-int CallPattern::DecodeLoadObject(int end, Register* reg, Object* obj) {
-  ASSERT(end > 0);
-  uword i = Back(end + 1);
-  Instr* instr = Instr::At(reinterpret_cast<uword>(&i));
+// Decodes a load sequence ending at 'end' (the last instruction of the load
+// sequence is the instruction before the one at end).  Returns a pointer to
+// the first instruction in the sequence.  Returns the register being loaded
+// and the loaded object in the output parameters 'reg' and 'obj'
+// respectively.
+uword InstructionPattern::DecodeLoadObject(uword end,
+                                           const Array& object_pool,
+                                           Register* reg,
+                                           Object* obj) {
+  uword start = 0;
+  Instr* instr = Instr::At(end - Instr::kInstrSize);
   if (instr->OpcodeField() == LW) {
-    int index = 0;
-    end = DecodeLoadWordFromPool(end, reg, &index);
-    *obj = object_pool_.At(index);
+    intptr_t index = 0;
+    start = DecodeLoadWordFromPool(end, reg, &index);
+    *obj = object_pool.At(index);
   } else {
-    int value = 0;
-    end = DecodeLoadWordImmediate(end, reg, &value);
+    intptr_t value = 0;
+    start = DecodeLoadWordImmediate(end, reg, &value);
     *obj = reinterpret_cast<RawObject*>(value);
   }
-  return end;
+  return start;
 }
 
 
-// Decodes a load sequence ending at end. Returns the register being loaded and
-// the loaded immediate value.
-// Returns the location of the load sequence, counting the number of
-// instructions back from the end of the call pattern.
-int CallPattern::DecodeLoadWordImmediate(int end, Register* reg, int* value) {
-  ASSERT(end > 0);
-  int imm = 0;
-  uword i = Back(++end);
-  Instr* instr = Instr::At(reinterpret_cast<uword>(&i));
+// Decodes a load sequence ending at 'end' (the last instruction of the load
+// sequence is the instruction before the one at end).  Returns a pointer to
+// the first instruction in the sequence.  Returns the register being loaded
+// and the loaded immediate value in the output parameters 'reg' and 'value'
+// respectively.
+uword InstructionPattern::DecodeLoadWordImmediate(uword end,
+                                                  Register* reg,
+                                                  intptr_t* value) {
+  // The pattern is a fixed size, but match backwards for uniformity with
+  // DecodeLoadWordFromPool.
+  uword start = end - Instr::kInstrSize;
+  Instr* instr = Instr::At(start);
+  intptr_t imm = 0;
   ASSERT(instr->OpcodeField() == ORI);
   imm = instr->UImmField();
   *reg = instr->RtField();
 
-  i = Back(++end);
-  instr = Instr::At(reinterpret_cast<uword>(&i));
+  start -= Instr::kInstrSize;
+  instr = Instr::At(start);
   ASSERT(instr->OpcodeField() == LUI);
   ASSERT(instr->RtField() == *reg);
   imm |= (instr->UImmField() << 16);
   *value = imm;
-  return end;
+  return start;
 }
 
 
-// Decodes a load sequence ending at end. Returns the register being loaded and
-// the index in the pool being read from.
-// Returns the location of the load sequence, counting the number of
-// instructions back from the end of the call pattern.
-int CallPattern::DecodeLoadWordFromPool(int end, Register* reg, int* index) {
-  ASSERT(end > 0);
-  uword i = Back(++end);
-  Instr* instr = Instr::At(reinterpret_cast<uword>(&i));
-  int offset = 0;
+// Decodes a load sequence ending at 'end' (the last instruction of the load
+// sequence is the instruction before the one at end).  Returns a pointer to
+// the first instruction in the sequence.  Returns the register being loaded
+// and the index in the pool being read from in the output parameters 'reg'
+// and 'index' respectively.
+uword InstructionPattern::DecodeLoadWordFromPool(uword end,
+                                                 Register* reg,
+                                                 intptr_t* index) {
+  uword start = end - Instr::kInstrSize;
+  Instr* instr = Instr::At(start);
+  intptr_t offset = 0;
   if ((instr->OpcodeField() == LW) && (instr->RsField() == PP)) {
     offset = instr->SImmField();
     *reg = instr->RtField();
@@ -97,16 +103,16 @@
     offset = instr->SImmField();
     *reg = instr->RtField();
 
-    i = Back(++end);
-    instr = Instr::At(reinterpret_cast<uword>(&i));
+    start -= Instr::kInstrSize;
+    instr = Instr::At(start);
     ASSERT(instr->OpcodeField() == SPECIAL);
     ASSERT(instr->FunctionField() == ADDU);
     ASSERT(instr->RdField() == *reg);
     ASSERT(instr->RsField() == *reg);
     ASSERT(instr->RtField() == PP);
 
-    i = Back(++end);
-    instr = Instr::At(reinterpret_cast<uword>(&i));
+    start -= Instr::kInstrSize;
+    instr = Instr::At(start);
     ASSERT(instr->OpcodeField() == LUI);
     ASSERT(instr->RtField() == *reg);
     // Offset is signed, so add the upper 16 bits.
@@ -114,15 +120,19 @@
   }
   offset += kHeapObjectTag;
   ASSERT(Utils::IsAligned(offset, 4));
-  *index = (offset - Array::data_offset())/4;
-  return end;
+  *index = (offset - Array::data_offset()) / 4;
+  return start;
 }
 
 
 RawICData* CallPattern::IcData() {
   if (ic_data_.IsNull()) {
     Register reg;
-    args_desc_load_end_ = DecodeLoadObject(ic_data_load_end_, &reg, &ic_data_);
+    args_desc_load_end_ =
+        InstructionPattern::DecodeLoadObject(ic_data_load_end_,
+                                             object_pool_,
+                                             &reg,
+                                             &ic_data_);
     ASSERT(reg == S5);
   }
   return ic_data_.raw();
@@ -133,7 +143,10 @@
   if (args_desc_.IsNull()) {
     IcData();  // Loading of the ic_data must be decoded first, if not already.
     Register reg;
-    DecodeLoadObject(args_desc_load_end_, &reg, &args_desc_);
+    InstructionPattern::DecodeLoadObject(args_desc_load_end_,
+                                         object_pool_,
+                                         &reg,
+                                         &args_desc_);
     ASSERT(reg == S4);
   }
   return args_desc_.raw();
@@ -217,4 +230,3 @@
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_MIPS
-
diff --git a/runtime/vm/instructions_mips.h b/runtime/vm/instructions_mips.h
index 7cecc70..b4864b7 100644
--- a/runtime/vm/instructions_mips.h
+++ b/runtime/vm/instructions_mips.h
@@ -15,6 +15,38 @@
 
 namespace dart {
 
+class InstructionPattern : public AllStatic {
+ public:
+  // Decodes a load sequence ending at 'end' (the last instruction of the
+  // load sequence is the instruction before the one at end).  Returns the
+  // address of the first instruction in the sequence.  Returns the register
+  // being loaded and the loaded object in the output parameters 'reg' and
+  // 'obj' respectively.
+  static uword DecodeLoadObject(uword end,
+                                const Array& object_pool,
+                                Register* reg,
+                                Object* obj);
+
+  // Decodes a load sequence ending at 'end' (the last instruction of the
+  // load sequence is the instruction before the one at end).  Returns the
+  // address of the first instruction in the sequence.  Returns the register
+  // being loaded and the loaded immediate value in the output parameters
+  // 'reg' and 'value' respectively.
+  static uword DecodeLoadWordImmediate(uword end,
+                                       Register* reg,
+                                       intptr_t* value);
+
+  // Decodes a load sequence ending at 'end' (the last instruction of the
+  // load sequence is the instruction before the one at end).  Returns the
+  // address of the first instruction in the sequence.  Returns the register
+  // being loaded and the index in the pool being read from in the output
+  // parameters 'reg' and 'index' respectively.
+  static uword DecodeLoadWordFromPool(uword end,
+                                      Register* reg,
+                                      intptr_t* index);
+};
+
+
 class CallPattern : public ValueObject {
  public:
   CallPattern(uword pc, const Code& code);
@@ -32,18 +64,16 @@
   static void InsertAt(uword pc, uword target_address);
 
  private:
-  uword Back(int n) const;
-  int DecodeLoadObject(int end, Register* reg, Object* obj);
-  int DecodeLoadWordImmediate(int end, Register* reg, int* value);
-  int DecodeLoadWordFromPool(int end, Register* reg, int* index);
-  const uword* end_;
-  int target_address_pool_index_;
-  int args_desc_load_end_;
-  Array& args_desc_;
-  int ic_data_load_end_;
-  ICData& ic_data_;
   const Array& object_pool_;
 
+  uword end_;
+  uword args_desc_load_end_;
+  uword ic_data_load_end_;
+
+  intptr_t target_address_pool_index_;
+  Array& args_desc_;
+  ICData& ic_data_;
+
   DISALLOW_COPY_AND_ASSIGN(CallPattern);
 };
 
@@ -72,4 +102,3 @@
 }  // namespace dart
 
 #endif  // VM_INSTRUCTIONS_MIPS_H_
-
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index 0f788073..7b0b4ae 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -13,7 +13,7 @@
 
 intptr_t InstructionPattern::IndexFromPPLoad(uword start) {
   int32_t offset = *reinterpret_cast<int32_t*>(start);
-  offset +=  kHeapObjectTag;
+  offset += kHeapObjectTag;
   return (offset - Array::data_offset()) / kWordSize;
 }
 
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 147ea56..50c4930 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -362,12 +362,12 @@
 
 MethodRecognizer::Kind MethodRecognizer::RecognizeKind(
     const Function& function) {
-  const Class& function_class = Class::Handle(function.Owner());
-  const Library& lib = Library::Handle(function_class.library());
-  if (!IsRecognizedLibrary(lib)) {
+  if (!function.is_recognized()) {
     return kUnknown;
   }
 
+  const Class& function_class = Class::Handle(function.Owner());
+  const Library& lib = Library::Handle(function_class.library());
   const String& function_name = String::Handle(function.name());
   const String& class_name = String::Handle(function_class.Name());
 
@@ -379,6 +379,7 @@
   }
 RECOGNIZED_LIST(RECOGNIZE_FUNCTION)
 #undef RECOGNIZE_FUNCTION
+  UNREACHABLE();
   return kUnknown;
 }
 
@@ -414,7 +415,25 @@
 }
 
 
+void MethodRecognizer::InitializeState() {
+  GrowableArray<Library*> libs(3);
+  libs.Add(&Library::ZoneHandle(Library::CoreLibrary()));
+  libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
+  libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
+  Function& func = Function::Handle();
+
+#define SET_IS_RECOGNIZED(class_name, function_name, dest, fp)                 \
+  func = Library::GetFunction(libs, #class_name, #function_name);              \
+  ASSERT(!func.IsNull());                                                      \
+  func.set_is_recognized(true);                                                \
+
+  RECOGNIZED_LIST(SET_IS_RECOGNIZED);
+
+#undef SET_IS_RECOGNIZED
+}
+
 // ==== Support for visiting flow graphs.
+
 #define DEFINE_ACCEPT(ShortName)                                               \
 void ShortName##Instr::Accept(FlowGraphVisitor* visitor) {                     \
   visitor->Visit##ShortName(this);                                             \
@@ -1645,6 +1664,12 @@
 
 
 LocationSummary* TargetEntryInstr::MakeLocationSummary() const {
+  // FlowGraphCompiler::EmitInstructionPrologue is not called for block
+  // entry instructions, so this function is unused.  If it becomes
+  // reachable, note that the deoptimization descriptor in unoptimized code
+  // comes after the point of local register allocation due to pattern
+  // matching the edge counter code backwards (as a code reuse convenience
+  // on some platforms).
   UNREACHABLE();
   return NULL;
 }
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 766fcaa..35ca39c 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -41,8 +41,8 @@
   V(::, identical, ObjectIdentical, 496869842)                                 \
   V(Object, Object., ObjectConstructor, 1058585294)                            \
   V(Object, get:_cid, ObjectCid, 1498721510)                                   \
-  V(_ObjectArray, get:length, ObjectArrayLength, 259382695)                    \
-  V(_ImmutableArray, get:length, ImmutableArrayLength, 1342001998)             \
+  V(_List, get:length, ObjectArrayLength, 215153395)                           \
+  V(_ImmutableList, get:length, ImmutableArrayLength, 578733070)               \
   V(_TypedList, get:length, TypedDataLength, 26616328)                         \
   V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 272598802)                     \
   V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 831354841)                   \
@@ -62,14 +62,15 @@
   V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1457395244)              \
   V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 49127618)                \
   V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 1261559935)          \
-  V(_GrowableObjectArray, get:length, GrowableArrayLength, 1160417196)         \
-  V(_GrowableObjectArray, get:_capacity, GrowableArrayCapacity, 1509841570)    \
-  V(_GrowableObjectArray, _setData, GrowableArraySetData, 1574432374)          \
-  V(_GrowableObjectArray, _setLength, GrowableArraySetLength, 1112774552)      \
+  V(_GrowableList, get:length, GrowableArrayLength, 1654225242)                \
+  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 817090003)            \
+  V(_GrowableList, _setData, GrowableArraySetData, 1375509957)                 \
+  V(_GrowableList, _setLength, GrowableArraySetLength, 1227678442)             \
   V(_StringBase, get:length, StringBaseLength, 1483520063)                     \
   V(_StringBase, get:isEmpty, StringBaseIsEmpty, 879849436)                    \
   V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 1958436584)                 \
   V(_StringBase, [], StringBaseCharAt, 990046076)                              \
+  V(_StringBase, _interpolate, StringBaseInterpolate, 908021574)               \
   V(_OneByteString, _setAt, OneByteStringSetAt, 308408714)                     \
   V(_IntegerImplementation, toDouble, IntegerToDouble, 2011998508)             \
   V(_IntegerImplementation, _leftShiftWithMask32, IntegerLeftShiftWithMask32,  \
@@ -134,9 +135,9 @@
   V(_Uint32x4, withFlagY, Uint32x4WithFlagY, 830610988)                        \
   V(_Uint32x4, withFlagZ, Uint32x4WithFlagZ, 1714792414)                       \
   V(_Uint32x4, withFlagW, Uint32x4WithFlagW, 1516924162)                       \
-  V(_ObjectArray, [], ObjectArrayGetIndexed, 544020319)                        \
-  V(_ImmutableArray, [], ImmutableArrayGetIndexed, 1345387065)                 \
-  V(_GrowableObjectArray, [], GrowableArrayGetIndexed, 951312767)              \
+  V(_List, [], ObjectArrayGetIndexed, 1079829188)                              \
+  V(_ImmutableList, [], ImmutableArrayGetIndexed, 25983597)                    \
+  V(_GrowableList, [], GrowableArrayGetIndexed, 1686777561)                    \
   V(_Float32Array, [], Float32ArrayGetIndexed, 1225286513)                     \
   V(_Float64Array, [], Float64ArrayGetIndexed, 871118335)                      \
   V(_Int8Array, [], Int8ArrayGetIndexed, 199925538)                            \
@@ -154,14 +155,14 @@
 
 // A list of core function that should always be inlined.
 #define INLINE_WHITE_LIST(V)                                                   \
-  V(_ObjectArray, get:length, ObjectArrayLength, 259382695)                    \
-  V(_ImmutableArray, get:length, ImmutableArrayLength, 1342001998)             \
+  V(_List, get:length, ObjectArrayLength, 215153395)                           \
+  V(_ImmutableList, get:length, ImmutableArrayLength, 578733070)               \
   V(_TypedList, get:length, TypedDataLength, 26616328)                         \
-  V(_GrowableObjectArray, get:length, GrowableArrayLength, 1160417196)         \
+  V(_GrowableList, get:length, GrowableArrayLength, 1654225242)                \
   V(_StringBase, get:length, StringBaseLength, 1483520063)                     \
   V(ListIterator, moveNext, ListIteratorMoveNext, 90930587)                    \
-  V(_GrowableObjectArray, get:iterator, GrowableArrayIterator, 2129691657)     \
-  V(_GrowableObjectArray, forEach, GrowableArrayForEach, 1669274418)
+  V(_GrowableList, get:iterator, GrowableArrayIterator, 1305127405)            \
+  V(_GrowableList, forEach, GrowableArrayForEach, 1675430533)
 
 
 // Class that recognizes the name and owner of a function and returns the
@@ -179,6 +180,7 @@
   static Kind RecognizeKind(const Function& function);
   static bool AlwaysInline(const Function& function);
   static const char* KindToCString(Kind kind);
+  static void InitializeState();
 };
 
 
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 00df26b..35b43d9 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -361,14 +361,6 @@
   const Array& kNoArgumentNames = Object::null_array();
   const int kNumArgumentsChecked = 2;
 
-  Label check_identity;
-  __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
-  __ ldm(IA, SP, (1 << R0) | (1 << R1));
-  __ cmp(R1, ShifterOperand(IP));
-  __ b(&check_identity, EQ);
-  __ cmp(R0, ShifterOperand(IP));
-  __ b(&check_identity, EQ);
-
   ICData& equality_ic_data = ICData::ZoneHandle();
   if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
     ASSERT(!original_ic_data.IsNull());
@@ -395,42 +387,12 @@
                                  kNoArgumentNames,
                                  locs,
                                  equality_ic_data);
-  Label check_ne;
-  __ b(&check_ne);
-
-  __ Bind(&check_identity);
-  Label equality_done;
-  if (compiler->is_optimizing()) {
-    // No need to update IC data.
-    __ PopList((1 << R0) | (1 << R1));
-    __ cmp(R0, ShifterOperand(R1));
-    __ LoadObject(R0, Bool::Get(kind != Token::kEQ), NE);
-    __ LoadObject(R0, Bool::Get(kind == Token::kEQ), EQ);
-    if (kind == Token::kNE) {
-      // Skip not-equal result conversion.
-      __ b(&equality_done);
-    }
-  } else {
-    // Call stub, load IC data in register. The stub will update ICData if
-    // necessary.
-    Register ic_data_reg = locs->temp(0).reg();
-    ASSERT(ic_data_reg == R5);  // Stub depends on it.
-    __ LoadObject(ic_data_reg, equality_ic_data);
-    // Pass left in R1 and right in R0.
-    compiler->GenerateCall(token_pos,
-                           &StubCode::EqualityWithNullArgLabel(),
-                           PcDescriptors::kRuntimeCall,
-                           locs);
-    __ Drop(2);
-  }
-  __ Bind(&check_ne);
   if (kind == Token::kNE) {
     // Negate the condition: true label returns false and vice versa.
     __ CompareObject(R0, Bool::True());
     __ LoadObject(R0, Bool::True(), NE);
     __ LoadObject(R0, Bool::False(), EQ);
   }
-  __ Bind(&equality_done);
 }
 
 
@@ -612,35 +574,11 @@
   ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
   Register left = locs->in(0).reg();
   Register right = locs->in(1).reg();
-  Label done, identity_compare, non_null_compare;
-  __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
-  __ cmp(right, ShifterOperand(IP));
-  __ b(&identity_compare, EQ);
-  __ cmp(left, ShifterOperand(IP));
-  __ b(&non_null_compare, NE);
-  // Comparison with NULL is "===".
-  __ Bind(&identity_compare);
-  __ cmp(left, ShifterOperand(right));
-  Condition cond = TokenKindToSmiCondition(kind);
-  if (branch != NULL) {
-    branch->EmitBranchOnCondition(compiler, cond);
-  } else {
-    Register result = locs->out().reg();
-    Label load_true;
-    __ b(&load_true, cond);
-    __ LoadObject(result, Bool::False());
-    __ b(&done);
-    __ Bind(&load_true);
-    __ LoadObject(result, Bool::True());
-  }
-  __ b(&done);
-  __ Bind(&non_null_compare);  // Receiver is not null.
   ASSERT(left == R1);
   ASSERT(right == R0);
   __ PushList((1 << R0) | (1 << R1));
   EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
                                 deopt_id, token_pos);
-  __ Bind(&done);
 }
 
 
@@ -4444,18 +4382,14 @@
 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   __ Bind(compiler->GetJumpLabel(this));
   if (!compiler->is_optimizing()) {
+    compiler->EmitEdgeCounter();
+    // Add an edge counter.
+    // On ARM the deoptimization descriptor points after the edge counter
+    // code so that we can reuse the same pattern matching code as at call
+    // sites, which matches backwards from the end of the pattern.
     compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
                                    deopt_id_,
                                    Scanner::kDummyTokenIndex);
-    // Add an edge counter.
-    const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
-    counter.SetAt(0, Smi::Handle(Smi::New(0)));
-    __ Comment("Edge counter");
-    __ LoadObject(R0, counter);
-    __ ldr(IP, FieldAddress(R0, Array::element_offset(0)));
-    __ adds(IP, IP, ShifterOperand(Smi::RawValue(1)));
-    __ LoadImmediate(IP, Smi::RawValue(Smi::kMaxValue), VS);  // If overflow.
-    __ str(IP, FieldAddress(R0, Array::element_offset(0)));
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -4469,6 +4403,17 @@
 
 
 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  if (!compiler->is_optimizing()) {
+    compiler->EmitEdgeCounter();
+    // Add a deoptimization descriptor for deoptimizing instructions that
+    // may be inserted before this instruction.  On ARM this descriptor
+    // points after the edge counter code so that we can reuse the same
+    // pattern matching code as at call sites, which matches backwards from
+    // the end of the pattern.
+    compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+                                   GetDeoptId(),
+                                   Scanner::kDummyTokenIndex);
+  }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
   }
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 279051c..bbbbe97 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -310,14 +310,6 @@
   const Array& kNoArgumentNames = Object::null_array();
   const int kNumArgumentsChecked = 2;
 
-  const Immediate& raw_null =
-      Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  Label check_identity;
-  __ cmpl(Address(ESP, 0 * kWordSize), raw_null);
-  __ j(EQUAL, &check_identity);
-  __ cmpl(Address(ESP, 1 * kWordSize), raw_null);
-  __ j(EQUAL, &check_identity);
-
   ICData& equality_ic_data = ICData::ZoneHandle();
   if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
     ASSERT(!original_ic_data.IsNull());
@@ -344,39 +336,6 @@
                                  kNoArgumentNames,
                                  locs,
                                  equality_ic_data);
-  Label check_ne;
-  __ jmp(&check_ne);
-
-  __ Bind(&check_identity);
-  Label equality_done;
-  if (compiler->is_optimizing()) {
-    // No need to update IC data.
-    Label is_true;
-    __ popl(EAX);
-    __ popl(EDX);
-    __ cmpl(EAX, EDX);
-    __ j(EQUAL, &is_true);
-    __ LoadObject(EAX, Bool::Get(kind != Token::kEQ));
-    __ jmp(&equality_done);
-    __ Bind(&is_true);
-    __ LoadObject(EAX, Bool::Get(kind == Token::kEQ));
-    if (kind == Token::kNE) {
-      // Skip not-equal result conversion.
-      __ jmp(&equality_done);
-    }
-  } else {
-    // Call stub, load IC data in register. The stub will update ICData if
-    // necessary.
-    Register ic_data_reg = locs->temp(0).reg();
-    ASSERT(ic_data_reg == ECX);  // Stub depends on it.
-    __ LoadObject(ic_data_reg, equality_ic_data);
-    compiler->GenerateCall(token_pos,
-                           &StubCode::EqualityWithNullArgLabel(),
-                           PcDescriptors::kRuntimeCall,
-                           locs);
-    __ Drop(2);
-  }
-  __ Bind(&check_ne);
   if (kind == Token::kNE) {
     Label true_label, done;
     // Negate the condition: true label returns false and vice versa.
@@ -388,7 +347,6 @@
     __ LoadObject(EAX, Bool::False());
     __ Bind(&done);
   }
-  __ Bind(&equality_done);
 }
 
 
@@ -562,35 +520,10 @@
   ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
   Register left = locs->in(0).reg();
   Register right = locs->in(1).reg();
-  const Immediate& raw_null =
-      Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  Label done, identity_compare, non_null_compare;
-  __ cmpl(right, raw_null);
-  __ j(EQUAL, &identity_compare, Assembler::kNearJump);
-  __ cmpl(left, raw_null);
-  __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
-  // Comparison with NULL is "===".
-  __ Bind(&identity_compare);
-  __ cmpl(left, right);
-  Condition cond = TokenKindToSmiCondition(kind);
-  if (branch != NULL) {
-    branch->EmitBranchOnCondition(compiler, cond);
-  } else {
-    Register result = locs->out().reg();
-    Label load_true;
-    __ j(cond, &load_true, Assembler::kNearJump);
-    __ LoadObject(result, Bool::False());
-    __ jmp(&done);
-    __ Bind(&load_true);
-    __ LoadObject(result, Bool::True());
-  }
-  __ jmp(&done);
-  __ Bind(&non_null_compare);  // Receiver is not null.
   __ pushl(left);
   __ pushl(right);
   EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
                                 deopt_id, token_pos);
-  __ Bind(&done);
 }
 
 
@@ -1827,7 +1760,7 @@
           __ movl(value_cid_reg,
                   FieldAddress(value_reg, TypedData::length_offset()));
         }
-        __ cmpl(value_cid_reg, Immediate(field_length));
+        __ cmpl(value_cid_reg, Immediate(Smi::RawValue(field_length)));
         if (ok_is_fall_through) {
           __ j(NOT_EQUAL, fail);
         }
@@ -4780,21 +4713,13 @@
 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   __ Bind(compiler->GetJumpLabel(this));
   if (!compiler->is_optimizing()) {
+    compiler->EmitEdgeCounter();
+    // The deoptimization descriptor points after the edge counter code for
+    // uniformity with ARM and MIPS, where we can reuse pattern matching
+    // code that matches backwards from the end of the pattern.
     compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
                                    deopt_id_,
                                    Scanner::kDummyTokenIndex);
-    // Add an edge counter.
-    const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
-    counter.SetAt(0, Smi::Handle(Smi::New(0)));
-    Label done;
-    __ Comment("Edge counter");
-    __ LoadObject(EAX, counter);
-    __ addl(FieldAddress(EAX, Array::element_offset(0)),
-            Immediate(Smi::RawValue(1)));
-    __ j(NO_OVERFLOW, &done);
-    __ movl(FieldAddress(EAX, Array::element_offset(0)),
-            Immediate(Smi::RawValue(Smi::kMaxValue)));
-    __ Bind(&done);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -4809,23 +4734,15 @@
 
 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   if (!compiler->is_optimizing()) {
-    // Add deoptimization descriptor for deoptimizing instructions that may
-    // be inserted before this instruction.
+    compiler->EmitEdgeCounter();
+    // Add a deoptimization descriptor for deoptimizing instructions that
+    // may be inserted before this instruction.  This descriptor points
+    // after the edge counter for uniformity with ARM and MIPS, where we can
+    // reuse pattern matching that matches backwards from the end of the
+    // pattern.
     compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   0);  // No token position.
-    // Add an edge counter.
-    const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
-    counter.SetAt(0, Smi::Handle(Smi::New(0)));
-    Label done;
-    __ Comment("Edge counter");
-    __ LoadObject(EAX, counter);
-    __ addl(FieldAddress(EAX, Array::element_offset(0)),
-            Immediate(Smi::RawValue(1)));
-    __ j(NO_OVERFLOW, &done);
-    __ movl(FieldAddress(EAX, Array::element_offset(0)),
-            Immediate(Smi::RawValue(Smi::kMaxValue)));
-    __ Bind(&done);
+                                   Scanner::kDummyTokenIndex);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index a1d5b18..4456f6e 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -356,12 +356,6 @@
 
   __ TraceSimMsg("EmitEqualityAsInstanceCall");
   __ Comment("EmitEqualityAsInstanceCall");
-  Label check_identity;
-  __ lw(A1, Address(SP, 1 * kWordSize));
-  __ lw(A0, Address(SP, 0 * kWordSize));
-  __ LoadImmediate(CMPRES1, reinterpret_cast<int32_t>(Object::null()));
-  __ beq(A1, CMPRES1, &check_identity);
-  __ beq(A0, CMPRES1, &check_identity);
 
   ICData& equality_ic_data = ICData::ZoneHandle();
   if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
@@ -389,40 +383,6 @@
                                  kNoArgumentNames,
                                  locs,
                                  equality_ic_data);
-  Label check_ne;
-  __ b(&check_ne);
-
-  __ Bind(&check_identity);
-  Label equality_done;
-  if (compiler->is_optimizing()) {
-    // No need to update IC data.
-    Label is_true;
-    __ lw(A1, Address(SP, 1 * kWordSize));
-    __ lw(A0, Address(SP, 0 * kWordSize));
-    __ addiu(SP, SP, Immediate(2 * kWordSize));
-    __ beq(A1, A0, &is_true);
-    __ LoadObject(V0, Bool::Get(kind != Token::kEQ));
-    __ b(&equality_done);
-    __ Bind(&is_true);
-    __ LoadObject(V0, Bool::Get(kind == Token::kEQ));
-    if (kind == Token::kNE) {
-      // Skip not-equal result conversion.
-      __ b(&equality_done);
-    }
-  } else {
-    // Call stub, load IC data in register. The stub will update ICData if
-    // necessary.
-    Register ic_data_reg = locs->temp(0).reg();
-    ASSERT(ic_data_reg == T0);  // Stub depends on it.
-    __ LoadObject(ic_data_reg, equality_ic_data);
-    // Pass left in A1 and right in A0.
-    compiler->GenerateCall(token_pos,
-                           &StubCode::EqualityWithNullArgLabel(),
-                           PcDescriptors::kRuntimeCall,
-                           locs);
-    __ Drop(2);
-  }
-  __ Bind(&check_ne);
   if (kind == Token::kNE) {
     Label true_label, done;
     // Negate the condition: true label returns false and vice versa.
@@ -433,7 +393,6 @@
     __ LoadObject(V0, Bool::False());
     __ Bind(&done);
   }
-  __ Bind(&equality_done);
 }
 
 
@@ -649,31 +608,8 @@
   ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
   Register left = locs->in(0).reg();
   Register right = locs->in(1).reg();
-  Label done, identity_compare, non_null_compare;
   __ TraceSimMsg("EmitGenericEqualityCompare");
   __ Comment("EmitGenericEqualityCompare");
-  __ LoadImmediate(CMPRES1, reinterpret_cast<int32_t>(Object::null()));
-  __ beq(right, CMPRES1, &identity_compare);
-  __ bne(left, CMPRES1, &non_null_compare);
-
-  // Comparison with NULL is "===".
-  __ Bind(&identity_compare);
-  Condition cond = TokenKindToSmiCondition(kind);
-  __ slt(CMPRES1, left, right);
-  __ slt(CMPRES2, right, left);
-  if (branch != NULL) {
-    branch->EmitBranchOnCondition(compiler, cond);
-  } else {
-    Register result = locs->out().reg();
-    Label load_true;
-    EmitBranchAfterCompare(compiler, cond, &load_true);
-    __ LoadObject(result, Bool::False());
-    __ b(&done);
-    __ Bind(&load_true);
-    __ LoadObject(result, Bool::True());
-  }
-  __ b(&done);
-  __ Bind(&non_null_compare);  // Receiver is not null.
   ASSERT(left == A1);
   ASSERT(right == A0);
   __ addiu(SP, SP, Immediate(-2 * kWordSize));
@@ -681,7 +617,6 @@
   __ sw(A0, Address(SP, 0 * kWordSize));
   EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
                                 deopt_id, token_pos);
-  __ Bind(&done);
 }
 
 
@@ -3838,22 +3773,13 @@
 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   __ Bind(compiler->GetJumpLabel(this));
   if (!compiler->is_optimizing()) {
+    compiler->EmitEdgeCounter();
+    // On MIPS the deoptimization descriptor points after the edge counter
+    // code so that we can reuse the same pattern matching code as at call
+    // sites, which matches backwards from the end of the pattern.
     compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
                                    deopt_id_,
                                    Scanner::kDummyTokenIndex);
-    // Add an edge counter.
-    const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
-    counter.SetAt(0, Smi::Handle(Smi::New(0)));
-    Label done;
-    __ Comment("Edge counter");
-    __ LoadObject(T0, counter);
-    __ lw(T1, FieldAddress(T0, Array::element_offset(0)));
-    __ AddImmediateDetectOverflow(T1, T1, Smi::RawValue(1), CMPRES, T2);
-    __ bgez(CMPRES, &done);
-    __ delay_slot()->sw(T1, FieldAddress(T0, Array::element_offset(0)));
-    __ LoadImmediate(TMP1, Smi::RawValue(Smi::kMaxValue));
-    __ sw(TMP1, FieldAddress(T0, Array::element_offset(0)));  // If overflow.
-    __ Bind(&done);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -3868,6 +3794,17 @@
 
 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   __ TraceSimMsg("GotoInstr");
+  if (!compiler->is_optimizing()) {
+    compiler->EmitEdgeCounter();
+    // Add a deoptimization descriptor for deoptimizing instructions that
+    // may be inserted before this instruction.  On MIPS this descriptor
+    // points after the edge counter code so that we can reuse the same
+    // pattern matching code as at call sites, which matches backwards from
+    // the end of the pattern.
+    compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+                                   GetDeoptId(),
+                                   Scanner::kDummyTokenIndex);
+  }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
   }
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 096ff06..4b5562b 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -52,7 +52,7 @@
     if (value.IsRegister()) {
       __ pushq(value.reg());
     } else if (value.IsConstant()) {
-      __ PushObject(value.constant());
+      __ PushObject(value.constant(), PP);
     } else {
       ASSERT(value.IsStackSlot());
       __ pushq(value.ToStackSlotAddress());
@@ -90,7 +90,7 @@
     ASSERT(fp_sp_dist <= 0);
     __ movq(RDI, RSP);
     __ subq(RDI, RBP);
-    __ cmpq(RDI, Immediate(fp_sp_dist));
+    __ CompareImmediate(RDI, Immediate(fp_sp_dist), PP);
     __ j(EQUAL, &done, Assembler::kNearJump);
     __ int3();
     __ Bind(&done);
@@ -196,9 +196,9 @@
     if ((kind_ == Token::kNE_STRICT) || (kind_ == Token::kNE)) {
       result = !result;
     }
-    __ movq(locs()->out().reg(),
+    __ LoadImmediate(locs()->out().reg(),
             Immediate(reinterpret_cast<int64_t>(
-                Smi::New(result ? if_true_ : if_false_))));
+                Smi::New(result ? if_true_ : if_false_))), PP);
     return;
   }
 
@@ -212,9 +212,9 @@
   // TODO(vegorov): reuse code from the other comparison instructions instead of
   // generating it inline here.
   if (left.IsConstant()) {
-    __ CompareObject(right.reg(), left.constant());
+    __ CompareObject(right.reg(), left.constant(), PP);
   } else if (right.IsConstant()) {
-    __ CompareObject(left.reg(), right.constant());
+    __ CompareObject(left.reg(), right.constant(), PP);
   } else {
     __ cmpq(left.reg(), right.reg());
   }
@@ -251,11 +251,11 @@
         Utils::ShiftForPowerOfTwo(Utils::Maximum(true_value, false_value));
     __ shlq(RDX, Immediate(shift + kSmiTagSize));
   } else {
-    __ subq(RDX, Immediate(1));
-    __ andq(RDX, Immediate(
-        Smi::RawValue(true_value) - Smi::RawValue(false_value)));
+    __ AddImmediate(RDX, Immediate(-1), PP);
+    __ AndImmediate(RDX,
+        Immediate(Smi::RawValue(true_value) - Smi::RawValue(false_value)), PP);
     if (false_value != 0) {
-      __ addq(RDX, Immediate(Smi::RawValue(false_value)));
+      __ AddImmediate(RDX, Immediate(Smi::RawValue(false_value)), PP);
     }
   }
 }
@@ -341,9 +341,9 @@
   // Call the runtime if the object is not bool::true or bool::false.
   ASSERT(locs->always_calls());
   Label done;
-  __ CompareObject(reg, Bool::True());
+  __ CompareObject(reg, Bool::True(), PP);
   __ j(EQUAL, &done, Assembler::kNearJump);
-  __ CompareObject(reg, Bool::False());
+  __ CompareObject(reg, Bool::False(), PP);
   __ j(EQUAL, &done, Assembler::kNearJump);
 
   __ pushq(reg);  // Push the source object.
@@ -453,13 +453,6 @@
   const Array& kNoArgumentNames = Object::null_array();
   const int kNumArgumentsChecked = 2;
 
-  Label check_identity;
-  __ LoadObject(TMP, Object::null_object(), PP);
-  __ cmpq(Address(RSP, 0 * kWordSize), TMP);
-  __ j(EQUAL, &check_identity);
-  __ cmpq(Address(RSP, 1 * kWordSize), TMP);
-  __ j(EQUAL, &check_identity);
-
   ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw());
   if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
     ASSERT(!original_ic_data.IsNull());
@@ -486,43 +479,10 @@
                                  kNoArgumentNames,
                                  locs,
                                  equality_ic_data);
-  Label check_ne;
-  __ jmp(&check_ne);
-
-  __ Bind(&check_identity);
-  Label equality_done;
-  if (compiler->is_optimizing()) {
-    // No need to update IC data.
-    Label is_true;
-    __ popq(RAX);
-    __ popq(RDX);
-    __ cmpq(RAX, RDX);
-    __ j(EQUAL, &is_true);
-    __ LoadObject(RAX, Bool::Get(kind != Token::kEQ), PP);
-    __ jmp(&equality_done);
-    __ Bind(&is_true);
-    __ LoadObject(RAX, Bool::Get(kind == Token::kEQ), PP);
-    if (kind == Token::kNE) {
-      // Skip not-equal result conversion.
-      __ jmp(&equality_done);
-    }
-  } else {
-    // Call stub, load IC data in register. The stub will update ICData if
-    // necessary.
-    Register ic_data_reg = locs->temp(0).reg();
-    ASSERT(ic_data_reg == RBX);  // Stub depends on it.
-    __ LoadObject(ic_data_reg, equality_ic_data, PP);
-    compiler->GenerateCall(token_pos,
-                           &StubCode::EqualityWithNullArgLabel(),
-                           PcDescriptors::kRuntimeCall,
-                           locs);
-    __ Drop(2);
-  }
-  __ Bind(&check_ne);
   if (kind == Token::kNE) {
     Label true_label, done;
     // Negate the condition: true label returns false and vice versa.
-    __ CompareObject(RAX, Bool::True());
+    __ CompareObject(RAX, Bool::True(), PP);
     __ j(EQUAL, &true_label, Assembler::kNearJump);
     __ LoadObject(RAX, Bool::True(), PP);
     __ jmp(&done, Assembler::kNearJump);
@@ -530,7 +490,6 @@
     __ LoadObject(RAX, Bool::False(), PP);
     __ Bind(&done);
   }
-  __ Bind(&equality_done);
 }
 
 
@@ -540,7 +499,7 @@
                          Label* value_is_smi = NULL) {
   Label done;
   if (value_is_smi == NULL) {
-    __ movq(value_cid_reg, Immediate(kSmiCid));
+    __ LoadImmediate(value_cid_reg, Immediate(kSmiCid), PP);
   }
   __ testq(value_reg, Immediate(kSmiTagMask));
   if (value_is_smi == NULL) {
@@ -579,7 +538,7 @@
     // Assert that the Smi is at position 0, if at all.
     ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmiCid) || (i == 0));
     Label next_test;
-    __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
+    __ CompareImmediate(temp, Immediate(ic_data.GetReceiverClassIdAt(i)), PP);
     if (i < len - 1) {
       __ j(NOT_EQUAL, &next_test);
     } else {
@@ -614,7 +573,7 @@
       if (branch == NULL) {
         if (kind == Token::kNE) {
           Label false_label;
-          __ CompareObject(RAX, Bool::True());
+          __ CompareObject(RAX, Bool::True(), PP);
           __ j(EQUAL, &false_label, Assembler::kNearJump);
           __ LoadObject(RAX, Bool::True(), PP);
           __ jmp(&done);
@@ -625,7 +584,7 @@
         if (branch->is_checked()) {
           EmitAssertBoolean(RAX, token_pos, deopt_id, locs, compiler);
         }
-        __ CompareObject(RAX, Bool::True());
+        __ CompareObject(RAX, Bool::True(), PP);
         branch->EmitBranchOnCondition(compiler, cond);
       }
     }
@@ -655,16 +614,16 @@
   // 'left' is not Smi.
 
   Label identity_compare;
-  __ CompareObject(right, Object::null_object());
+  __ CompareObject(right, Object::null_object(), PP);
   __ j(EQUAL, &identity_compare);
-  __ CompareObject(left, Object::null_object());
+  __ CompareObject(left, Object::null_object(), PP);
   __ j(EQUAL, &identity_compare);
 
   __ LoadClassId(temp, left);
   const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
   const intptr_t len = ic_data.NumberOfChecks();
   for (intptr_t i = 0; i < len; i++) {
-    __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
+    __ CompareImmediate(temp, Immediate(ic_data.GetReceiverClassIdAt(i)), PP);
     if (i == (len - 1)) {
       __ j(NOT_EQUAL, deopt);
     } else {
@@ -704,34 +663,10 @@
   ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
   Register left = locs->in(0).reg();
   Register right = locs->in(1).reg();
-
-  Label done, identity_compare, non_null_compare;
-  __ CompareObject(right, Object::null_object());
-  __ j(EQUAL, &identity_compare, Assembler::kNearJump);
-  __ CompareObject(left, Object::null_object());
-  __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
-  // Comparison with NULL is "===".
-  __ Bind(&identity_compare);
-  __ cmpq(left, right);
-  Condition cond = TokenKindToSmiCondition(kind);
-  if (branch != NULL) {
-    branch->EmitBranchOnCondition(compiler, cond);
-  } else {
-    Register result = locs->out().reg();
-    Label load_true;
-    __ j(cond, &load_true, Assembler::kNearJump);
-    __ LoadObject(result, Bool::False(), PP);
-    __ jmp(&done);
-    __ Bind(&load_true);
-    __ LoadObject(result, Bool::True(), PP);
-  }
-  __ jmp(&done);
-  __ Bind(&non_null_compare);  // Receiver is not null.
   __ pushq(left);
   __ pushq(right);
   EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
                                 deopt_id, token_pos);
-  __ Bind(&done);
 }
 
 
@@ -765,10 +700,10 @@
   Condition true_condition = TokenKindToSmiCondition(kind);
 
   if (left.IsConstant()) {
-    __ CompareObject(right.reg(), left.constant());
+    __ CompareObject(right.reg(), left.constant(), PP);
     true_condition = FlipCondition(true_condition);
   } else if (right.IsConstant()) {
-    __ CompareObject(left.reg(), right.constant());
+    __ CompareObject(left.reg(), right.constant(), PP);
   } else if (right.IsStackSlot()) {
     __ cmpq(left.reg(), right.ToStackSlotAddress());
   } else {
@@ -897,7 +832,7 @@
     EmitAssertBoolean(RAX, token_pos(), deopt_id(), locs(), compiler);
   }
   Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
-  __ CompareObject(RAX, Bool::True());
+  __ CompareObject(RAX, Bool::True(), PP);
   branch->EmitBranchOnCondition(compiler, branch_condition);
 }
 
@@ -968,7 +903,7 @@
   Register result = locs()->out().reg();
 
   // Push the result place holder initialized to NULL.
-  __ PushObject(Object::ZoneHandle());
+  __ PushObject(Object::ZoneHandle(), PP);
   // Pass a pointer to the first argument in RAX.
   if (!function().HasOptionalParameters()) {
     __ leaq(RAX, Address(RBP, (kParamEndSlotFromFp +
@@ -977,8 +912,10 @@
     __ leaq(RAX,
             Address(RBP, kFirstLocalSlotFromFp * kWordSize));
   }
-  __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function())));
-  __ movq(R10, Immediate(NativeArguments::ComputeArgcTag(function())));
+  __ LoadImmediate(
+      RBX, Immediate(reinterpret_cast<uword>(native_c_function())), PP);
+  __ LoadImmediate(
+      R10, Immediate(NativeArguments::ComputeArgcTag(function())), PP);
   const ExternalLabel* stub_entry =
       (is_bootstrap_native()) ? &StubCode::CallBootstrapCFunctionLabel() :
                                 &StubCode::CallNativeCFunctionLabel();
@@ -1014,8 +951,8 @@
 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Register char_code = locs()->in(0).reg();
   Register result = locs()->out().reg();
-  __ movq(result,
-          Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())));
+  __ LoadImmediate(result,
+          Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())), PP);
   __ movq(result, Address(result,
                           char_code,
                           TIMES_HALF_WORD_SIZE,  // Char code is a smi.
@@ -1052,7 +989,7 @@
   Label load, done;
   __ testq(object, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &load, Assembler::kNearJump);
-  __ movq(result, Immediate(Smi::RawValue(kSmiCid)));
+  __ LoadImmediate(result, Immediate(Smi::RawValue(kSmiCid)), PP);
   __ jmp(&done);
   __ Bind(&load);
   __ LoadClassId(result, object);
@@ -1360,7 +1297,7 @@
         __ StoreIntoObject(array, element_address, value);
       } else if (locs()->in(2).IsConstant()) {
         const Object& constant = locs()->in(2).constant();
-        __ StoreObject(element_address, constant);
+        __ StoreObject(element_address, constant, PP);
       } else {
         Register value = locs()->in(2).reg();
         __ StoreIntoObjectNoBarrier(array, element_address, value);
@@ -1397,14 +1334,14 @@
         ASSERT(locs()->in(2).reg() == RAX);
         Label store_value, store_0xff;
         __ SmiUntag(RAX);
-        __ cmpq(RAX, Immediate(0xFF));
+        __ CompareImmediate(RAX, Immediate(0xFF), PP);
         __ j(BELOW_EQUAL, &store_value, Assembler::kNearJump);
         // Clamp to 0x0 or 0xFF respectively.
         __ j(GREATER, &store_0xff);
         __ xorq(RAX, RAX);
         __ jmp(&store_value, Assembler::kNearJump);
         __ Bind(&store_0xff);
-        __ movq(RAX, Immediate(0xFF));
+        __ LoadImmediate(RAX, Immediate(0xFF), PP);
         __ Bind(&store_value);
         __ movb(element_address, RAX);
       }
@@ -1538,13 +1475,15 @@
           __ pushq(value_cid_reg);
           __ movq(value_cid_reg,
                   FieldAddress(value_reg, Array::length_offset()));
-          __ cmpq(value_cid_reg, Immediate(Smi::RawValue(field_length)));
+          __ CompareImmediate(
+              value_cid_reg, Immediate(Smi::RawValue(field_length)), PP);
           __ 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(Smi::RawValue(field_length)));
+          __ CompareImmediate(
+              value_cid_reg, Immediate(Smi::RawValue(field_length)), PP);
           __ popq(value_cid_reg);
         } else {
           ASSERT(field_cid == kIllegalCid);
@@ -1558,15 +1497,18 @@
           // If length is negative the length guard is either disabled or
           // has not been initialized, either way it is safe to skip the
           // length check.
-          __ cmpq(field_length_operand, Immediate(Smi::RawValue(0)));
+          __ CompareImmediate(
+              field_length_operand, Immediate(Smi::RawValue(0)), PP);
           __ j(LESS, &skip_length_check);
-          __ cmpq(value_cid_reg, Immediate(kNullCid));
+          __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP);
           __ j(EQUAL, &no_fixed_length, Assembler::kNearJump);
           // Check for typed data array.
-          __ cmpq(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid));
+          __ CompareImmediate(
+              value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid), PP);
           // Not a typed array or a regular array.
           __ j(GREATER, &no_fixed_length, Assembler::kNearJump);
-          __ cmpq(value_cid_reg, Immediate(kTypedDataInt8ArrayCid));
+          __ CompareImmediate(
+              value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP);
           // Could still be a regular array.
           __ j(LESS, &check_array, Assembler::kNearJump);
           __ pushq(value_cid_reg);
@@ -1577,9 +1519,9 @@
           __ jmp(&length_compared, Assembler::kNearJump);
           // Check for regular array.
           __ Bind(&check_array);
-          __ cmpq(value_cid_reg, Immediate(kImmutableArrayCid));
+          __ CompareImmediate(value_cid_reg, Immediate(kImmutableArrayCid), PP);
           __ j(GREATER, &no_fixed_length, Assembler::kNearJump);
-          __ cmpq(value_cid_reg, Immediate(kArrayCid));
+          __ CompareImmediate(value_cid_reg, Immediate(kArrayCid), PP);
           __ j(LESS, &no_fixed_length, Assembler::kNearJump);
           __ pushq(value_cid_reg);
           __ movq(value_cid_reg,
@@ -1596,21 +1538,22 @@
       __ Bind(&skip_length_check);
       __ cmpq(value_cid_reg, field_nullability_operand);
     } else if (value_cid == kNullCid) {
-      __ cmpq(field_nullability_operand, Immediate(value_cid));
+      __ CompareImmediate(field_nullability_operand, Immediate(value_cid), PP);
     } else {
       Label skip_length_check;
-      __ cmpq(field_cid_operand, Immediate(value_cid));
+      __ CompareImmediate(field_cid_operand, Immediate(value_cid), PP);
       // If not equal, skip over length check.
       __ j(NOT_EQUAL, &skip_length_check);
       // Insert length check.
       if (field_has_length) {
         ASSERT(value_cid_reg != kNoRegister);
         if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
-          __ cmpq(FieldAddress(value_reg, Array::length_offset()),
-                  Immediate(Smi::RawValue(field_length)));
+          __ CompareImmediate(FieldAddress(value_reg, Array::length_offset()),
+                              Immediate(Smi::RawValue(field_length)), PP);
         } else if (RawObject::IsTypedDataClassId(value_cid)) {
-          __ cmpq(FieldAddress(value_reg, TypedData::length_offset()),
-                  Immediate(Smi::RawValue(field_length)));
+          __ CompareImmediate(
+            FieldAddress(value_reg, TypedData::length_offset()),
+            Immediate(Smi::RawValue(field_length)), PP);
         } else if (field_cid != kIllegalCid) {
           ASSERT(field_cid != value_cid);
           ASSERT(field_length >= 0);
@@ -1629,7 +1572,7 @@
     }
     __ j(EQUAL, &ok);
 
-    __ cmpq(field_cid_operand, Immediate(kIllegalCid));
+    __ CompareImmediate(field_cid_operand, Immediate(kIllegalCid), PP);
     __ j(NOT_EQUAL, fail);
 
     if (value_cid == kDynamicCid) {
@@ -1637,13 +1580,15 @@
       __ movq(field_nullability_operand, value_cid_reg);
       if (field_has_length) {
         Label check_array, length_set, no_fixed_length;
-        __ cmpq(value_cid_reg, Immediate(kNullCid));
+        __ CompareImmediate(value_cid_reg, Immediate(kNullCid), PP);
         __ j(EQUAL, &no_fixed_length, Assembler::kNearJump);
         // Check for typed data array.
-        __ cmpq(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid));
+        __ CompareImmediate(value_cid_reg,
+                            Immediate(kTypedDataFloat32x4ArrayCid), PP);
         // Not a typed array or a regular array.
         __ j(GREATER, &no_fixed_length);
-        __ cmpq(value_cid_reg, Immediate(kTypedDataInt8ArrayCid));
+        __ CompareImmediate(
+            value_cid_reg, Immediate(kTypedDataInt8ArrayCid), PP);
         // Could still be a regular array.
         __ j(LESS, &check_array, Assembler::kNearJump);
         // Destroy value_cid_reg (safe because we are finished with it).
@@ -1654,9 +1599,9 @@
         __ jmp(&length_set);
         // Check for regular array.
         __ Bind(&check_array);
-        __ cmpq(value_cid_reg, Immediate(kImmutableArrayCid));
+        __ CompareImmediate(value_cid_reg, Immediate(kImmutableArrayCid), PP);
         __ j(GREATER, &no_fixed_length, Assembler::kNearJump);
-        __ cmpq(value_cid_reg, Immediate(kArrayCid));
+        __ CompareImmediate(value_cid_reg, Immediate(kArrayCid), PP);
         __ j(LESS, &no_fixed_length, Assembler::kNearJump);
         // Destroy value_cid_reg (safe because we are finished with it).
         __ movq(value_cid_reg,
@@ -1665,14 +1610,14 @@
         // Updated field length from regular array.
         __ jmp(&length_set, Assembler::kNearJump);
         __ Bind(&no_fixed_length);
-        __ movq(field_length_operand,
-                Immediate(Smi::RawValue(Field::kNoFixedLength)));
+        __ LoadImmediate(field_length_operand,
+            Immediate(Smi::RawValue(Field::kNoFixedLength)), PP);
         __ Bind(&length_set);
       }
     } else {
       ASSERT(field_reg != kNoRegister);
-      __ movq(field_cid_operand, Immediate(value_cid));
-      __ movq(field_nullability_operand, Immediate(value_cid));
+      __ LoadImmediate(field_cid_operand, Immediate(value_cid), PP);
+      __ LoadImmediate(field_nullability_operand, Immediate(value_cid), PP);
       if (field_has_length) {
         ASSERT(value_cid_reg != kNoRegister);
         if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
@@ -1686,8 +1631,8 @@
                   FieldAddress(value_reg, TypedData::length_offset()));
           __ movq(field_length_operand, value_cid_reg);
         } else {
-          __ movq(field_length_operand,
-                  Immediate(Smi::RawValue(Field::kNoFixedLength)));
+          __ LoadImmediate(field_length_operand,
+                  Immediate(Smi::RawValue(Field::kNoFixedLength)), PP);
         }
       }
     }
@@ -1706,7 +1651,7 @@
       if (field_cid != kSmiCid) {
         __ j(ZERO, fail);
         __ LoadClassId(value_cid_reg, value_reg);
-        __ cmpq(value_cid_reg, Immediate(field_cid));
+        __ CompareImmediate(value_cid_reg, Immediate(field_cid), PP);
       }
 
       if (field_has_length) {
@@ -1732,7 +1677,7 @@
 
       if (field().is_nullable() && (field_cid != kNullCid)) {
         __ j(EQUAL, &ok);
-        __ CompareObject(value_reg, Object::null_object());
+        __ CompareObject(value_reg, Object::null_object(), PP);
       }
 
       if (ok_is_fall_through) {
@@ -1757,7 +1702,8 @@
           __ movq(value_cid_reg,
                   FieldAddress(value_reg, TypedData::length_offset()));
         }
-        __ cmpq(value_cid_reg, Immediate(Smi::RawValue(field_length)));
+        __ CompareImmediate(
+            value_cid_reg, Immediate(Smi::RawValue(field_length)), PP);
         if (ok_is_fall_through) {
           __ j(NOT_EQUAL, fail);
         }
@@ -1773,8 +1719,8 @@
     ASSERT(!compiler->is_optimizing());
     __ Bind(fail);
 
-    __ cmpq(FieldAddress(field_reg, Field::guarded_cid_offset()),
-            Immediate(kDynamicCid));
+    __ CompareImmediate(FieldAddress(field_reg, Field::guarded_cid_offset()),
+                        Immediate(kDynamicCid), PP);
     __ j(EQUAL, &ok);
 
     __ pushq(field_reg);
@@ -1811,7 +1757,7 @@
   } else {
     if (locs()->in(1).IsConstant()) {
       __ StoreObject(FieldAddress(instance_reg, field().Offset()),
-                     locs()->in(1).constant());
+                     locs()->in(1).constant(), PP);
     } else {
       Register value_reg = locs()->in(1).reg();
       __ StoreIntoObjectNoBarrier(instance_reg,
@@ -1909,7 +1855,7 @@
 void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   // Allocate the array.  R10 = length, RBX = element type.
   ASSERT(locs()->in(0).reg() == RBX);
-  __ movq(R10, Immediate(Smi::RawValue(num_elements())));
+  __ LoadImmediate(R10, Immediate(Smi::RawValue(num_elements())), PP);
   compiler->GenerateCall(token_pos(),
                          &StubCode::AllocateArrayLabel(),
                          PcDescriptors::kOther,
@@ -1970,8 +1916,8 @@
   // 'instantiator_reg' is the instantiator AbstractTypeArguments object
   // (or null).
   // A runtime call to instantiate the type is required.
-  __ PushObject(Object::ZoneHandle());  // Make room for the result.
-  __ PushObject(type());
+  __ PushObject(Object::ZoneHandle(), PP);  // Make room for the result.
+  __ PushObject(type(), PP);
   __ pushq(instantiator_reg);  // Push instantiator type arguments.
   compiler->GenerateCallRuntime(token_pos(),
                                 deopt_id(),
@@ -2011,13 +1957,13 @@
   Label type_arguments_instantiated;
   const intptr_t len = type_arguments().Length();
   if (type_arguments().IsRawInstantiatedRaw(len)) {
-    __ CompareObject(instantiator_reg, Object::null_object());
+    __ CompareObject(instantiator_reg, Object::null_object(), PP);
     __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
   }
   // Instantiate non-null type arguments.
   // A runtime call to instantiate the type arguments is required.
-  __ PushObject(Object::ZoneHandle());  // Make room for the result.
-  __ PushObject(type_arguments());
+  __ PushObject(Object::ZoneHandle(), PP);  // Make room for the result.
+  __ PushObject(type_arguments(), PP);
   __ pushq(instantiator_reg);  // Push instantiator type arguments.
   compiler->GenerateCallRuntime(token_pos(),
                                 deopt_id(),
@@ -2060,7 +2006,7 @@
   Label type_arguments_instantiated;
   ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
 
-  __ CompareObject(instantiator_reg, Object::null_object());
+  __ CompareObject(instantiator_reg, Object::null_object(), PP);
   __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
   // Instantiate non-null type arguments.
   // In the non-factory case, we rely on the allocation stub to
@@ -2102,12 +2048,12 @@
   ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length()));
 
   Label instantiator_not_null;
-  __ CompareObject(instantiator_reg, Object::null_object());
+  __ CompareObject(instantiator_reg, Object::null_object(), PP);
   __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
   // Null was used in VisitExtractConstructorTypeArguments as the
   // instantiated type arguments, no proper instantiator needed.
-  __ movq(instantiator_reg,
-          Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
+  __ LoadImmediate(instantiator_reg,
+          Immediate(Smi::RawValue(StubCode::kNoInstantiator)), PP);
   __ Bind(&instantiator_not_null);
   // instantiator_reg: instantiator or kNoInstantiator.
 }
@@ -2128,7 +2074,7 @@
   ASSERT(locs()->temp(0).reg() == R10);
   ASSERT(locs()->out().reg() == RAX);
 
-  __ movq(R10, Immediate(num_context_variables()));
+  __ LoadImmediate(R10, Immediate(num_context_variables()), PP);
   const ExternalLabel label("alloc_context",
                             StubCode::AllocateContextEntryPoint());
   compiler->GenerateCall(token_pos(),
@@ -2153,7 +2099,7 @@
   Register context_value = locs()->in(0).reg();
   Register result = locs()->out().reg();
 
-  __ PushObject(Object::ZoneHandle());  // Make room for the result.
+  __ PushObject(Object::ZoneHandle(), PP);  // Make room for the result.
   __ pushq(context_value);
   compiler->GenerateCallRuntime(token_pos(),
                                 deopt_id(),
@@ -2255,7 +2201,8 @@
 
   Register temp = locs()->temp(0).reg();
   // Generate stack overflow check.
-  __ movq(temp, Immediate(Isolate::Current()->stack_limit_address()));
+  __ LoadImmediate(
+      temp, Immediate(Isolate::Current()->stack_limit_address()), PP);
   __ cmpq(RSP, Address(temp, 0));
   __ j(BELOW_EQUAL, slow_path->entry_label());
   if (compiler->CanOSRFunction() && in_loop()) {
@@ -2265,8 +2212,8 @@
     __ LoadObject(temp, compiler->parsed_function().function(), PP);
     intptr_t threshold =
         FLAG_optimization_counter_threshold * (loop_depth() + 1);
-    __ cmpq(FieldAddress(temp, Function::usage_counter_offset()),
-            Immediate(threshold));
+    __ CompareImmediate(FieldAddress(temp, Function::usage_counter_offset()),
+                        Immediate(threshold), PP);
     __ j(GREATER_EQUAL, slow_path->entry_label());
   }
   __ Bind(slow_path->exit_label());
@@ -2279,9 +2226,9 @@
                                         Register result) {
   if (!range->IsWithin(-0x20000000000000LL, 0x20000000000000LL)) {
     ASSERT(overflow != NULL);
-    __ cmpq(result, Immediate(-0x20000000000000LL));
+    __ CompareImmediate(result, Immediate(-0x20000000000000LL), PP);
     __ j(LESS, overflow);
-    __ cmpq(result, Immediate(0x20000000000000LL));
+    __ CompareImmediate(result, Immediate(0x20000000000000LL), PP);
     __ j(GREATER, overflow);
   }
 }
@@ -2342,7 +2289,7 @@
     if (obj.IsSmi()) {
       const intptr_t left_int = Smi::Cast(obj).Value();
       if (left_int == 0) {
-        __ cmpq(right, Immediate(0));
+        __ CompareImmediate(right, Immediate(0), PP);
         __ j(NEGATIVE, deopt);
         return;
       }
@@ -2351,8 +2298,8 @@
           (right_range == NULL) ||
           !right_range->IsWithin(0, max_right - 1);
       if (right_needs_check) {
-        __ cmpq(right,
-          Immediate(reinterpret_cast<int64_t>(Smi::New(max_right))));
+        __ CompareImmediate(right,
+            Immediate(reinterpret_cast<int64_t>(Smi::New(max_right))), PP);
         __ j(ABOVE_EQUAL, deopt);
       }
       __ SmiUntag(right);
@@ -2374,12 +2321,12 @@
           !right_range->IsWithin(0, RangeBoundary::kPlusInfinity);
       if (right_may_be_negative) {
         ASSERT(shift_left->CanDeoptimize());
-        __ cmpq(right, Immediate(0));
+        __ CompareImmediate(right, Immediate(0), PP);
         __ j(NEGATIVE, deopt);
       }
       Label done, is_not_zero;
-      __ cmpq(right,
-          Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
+      __ CompareImmediate(right,
+          Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))), PP);
       __ j(BELOW, &is_not_zero, Assembler::kNearJump);
       __ xorq(left, left);
       __ jmp(&done, Assembler::kNearJump);
@@ -2394,8 +2341,8 @@
   } else {
     if (right_needs_check) {
       ASSERT(shift_left->CanDeoptimize());
-      __ cmpq(right,
-          Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
+      __ CompareImmediate(right,
+          Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))), PP);
       __ j(ABOVE_EQUAL, deopt);
     }
     // Left is not a constant.
@@ -2518,12 +2465,12 @@
         reinterpret_cast<int64_t>(constant.raw());
     switch (op_kind()) {
       case Token::kADD: {
-        __ addq(left, Immediate(imm));
+        __ AddImmediate(left, Immediate(imm), PP);
         if (deopt != NULL) __ j(OVERFLOW, deopt);
         break;
       }
       case Token::kSUB: {
-        __ subq(left, Immediate(imm));
+        __ AddImmediate(left, Immediate(-imm), PP);
         if (deopt != NULL) __ j(OVERFLOW, deopt);
         break;
       }
@@ -2533,7 +2480,7 @@
         if (value == 2) {
           __ shlq(left, Immediate(1));
         } else {
-          __ imulq(left, Immediate(value));
+          __ MulImmediate(left, Immediate(value), PP);
         }
         if (deopt != NULL) __ j(OVERFLOW, deopt);
         break;
@@ -2546,7 +2493,7 @@
         } else if (value == -1) {
           // Check the corner case of dividing the 'MIN_SMI' with -1, in which
           // case we cannot negate the result.
-          __ cmpq(left, Immediate(0x8000000000000000));
+          __ CompareImmediate(left, Immediate(0x8000000000000000), PP);
           __ j(EQUAL, deopt);
           __ negq(left);
           break;
@@ -2572,17 +2519,17 @@
       }
       case Token::kBIT_AND: {
         // No overflow check.
-        __ andq(left, Immediate(imm));
+        __ AndImmediate(left, Immediate(imm), PP);
         break;
       }
       case Token::kBIT_OR: {
         // No overflow check.
-        __ orq(left, Immediate(imm));
+        __ OrImmediate(left, Immediate(imm), PP);
         break;
       }
       case Token::kBIT_XOR: {
         // No overflow check.
-        __ xorq(left, Immediate(imm));
+        __ XorImmediate(left, Immediate(imm), PP);
         break;
       }
 
@@ -2738,7 +2685,7 @@
       __ idivq(right);  //  RAX: quotient, RDX: remainder.
       // Check the corner case of dividing the 'MIN_SMI' with -1, in which
       // case we cannot tag the result.
-      __ cmpq(result, Immediate(0x4000000000000000));
+      __ CompareImmediate(result, Immediate(0x4000000000000000), PP);
       __ j(EQUAL, deopt);
       __ Bind(&done);
       __ SmiTag(result);
@@ -2746,7 +2693,7 @@
     }
     case Token::kSHR: {
       if (CanDeoptimize()) {
-        __ cmpq(right, Immediate(0));
+        __ CompareImmediate(right, Immediate(0), PP);
         __ j(LESS, deopt);
       }
       __ SmiUntag(right);
@@ -2755,10 +2702,10 @@
       Range* right_range = this->right()->definition()->range();
       if ((right_range == NULL) ||
           !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
-        __ cmpq(right, Immediate(kCountLimit));
+        __ CompareImmediate(right, Immediate(kCountLimit), PP);
         Label count_ok;
         __ j(LESS, &count_ok, Assembler::kNearJump);
-        __ movq(right, Immediate(kCountLimit));
+        __ LoadImmediate(right, Immediate(kCountLimit), PP);
         __ Bind(&count_ok);
       }
       ASSERT(right == RCX);  // Count must be in RCX
@@ -2886,7 +2833,8 @@
   __ TryAllocate(compiler->double_class(),
                  slow_path->entry_label(),
                  Assembler::kFarJump,
-                 out_reg);
+                 out_reg,
+                 PP);
   __ Bind(slow_path->exit_label());
   __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
 }
@@ -2988,7 +2936,8 @@
   __ TryAllocate(compiler->float32x4_class(),
                  slow_path->entry_label(),
                  Assembler::kFarJump,
-                 out_reg);
+                 out_reg,
+                 PP);
   __ Bind(slow_path->exit_label());
   __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value);
 }
@@ -3073,7 +3022,8 @@
   __ TryAllocate(compiler->uint32x4_class(),
                  slow_path->entry_label(),
                  Assembler::kFarJump,
-                 out_reg);
+                 out_reg,
+                 PP);
   __ Bind(slow_path->exit_label());
   __ movups(FieldAddress(out_reg, Uint32x4::value_offset()), value);
 }
@@ -3243,7 +3193,7 @@
   XmmRegister v2 = locs()->in(2).fpu_reg();
   XmmRegister v3 = locs()->in(3).fpu_reg();
   ASSERT(v0 == locs()->out().fpu_reg());
-  __ subq(RSP, Immediate(16));
+  __ AddImmediate(RSP, Immediate(-16), PP);
   __ cvtsd2ss(v0, v0);
   __ movss(Address(RSP, 0), v0);
   __ movsd(v0, v1);
@@ -3256,7 +3206,7 @@
   __ cvtsd2ss(v0, v0);
   __ movss(Address(RSP, 12), v0);
   __ movups(v0, Address(RSP, 0));
-  __ addq(RSP, Immediate(16));
+  __ AddImmediate(RSP, Immediate(16), PP);
 }
 
 
@@ -3501,47 +3451,47 @@
   switch (op_kind()) {
     case MethodRecognizer::kFloat32x4WithX:
       __ cvtsd2ss(replacement, replacement);
-      __ subq(RSP, Immediate(16));
+      __ AddImmediate(RSP, Immediate(-16), PP);
       // Move value to stack.
       __ movups(Address(RSP, 0), value);
       // Write over X value.
       __ movss(Address(RSP, 0), replacement);
       // Move updated value into output register.
       __ movups(replacement, Address(RSP, 0));
-      __ addq(RSP, Immediate(16));
+      __ AddImmediate(RSP, Immediate(16), PP);
       break;
     case MethodRecognizer::kFloat32x4WithY:
       __ cvtsd2ss(replacement, replacement);
-      __ subq(RSP, Immediate(16));
+      __ AddImmediate(RSP, Immediate(-16), PP);
       // Move value to stack.
       __ movups(Address(RSP, 0), value);
       // Write over Y value.
       __ movss(Address(RSP, 4), replacement);
       // Move updated value into output register.
       __ movups(replacement, Address(RSP, 0));
-      __ addq(RSP, Immediate(16));
+      __ AddImmediate(RSP, Immediate(16), PP);
       break;
     case MethodRecognizer::kFloat32x4WithZ:
       __ cvtsd2ss(replacement, replacement);
-      __ subq(RSP, Immediate(16));
+      __ AddImmediate(RSP, Immediate(-16), PP);
       // Move value to stack.
       __ movups(Address(RSP, 0), value);
       // Write over Z value.
       __ movss(Address(RSP, 8), replacement);
       // Move updated value into output register.
       __ movups(replacement, Address(RSP, 0));
-      __ addq(RSP, Immediate(16));
+      __ AddImmediate(RSP, Immediate(16), PP);
       break;
     case MethodRecognizer::kFloat32x4WithW:
       __ cvtsd2ss(replacement, replacement);
-      __ subq(RSP, Immediate(16));
+      __ AddImmediate(RSP, Immediate(-16), PP);
       // Move value to stack.
       __ movups(Address(RSP, 0), value);
       // Write over W value.
       __ movss(Address(RSP, 12), replacement);
       // Move updated value into output register.
       __ movups(replacement, Address(RSP, 0));
-      __ addq(RSP, Immediate(16));
+      __ AddImmediate(RSP, Immediate(16), PP);
       break;
     default: UNREACHABLE();
   }
@@ -3629,46 +3579,46 @@
   Label y_false, y_done;
   Label z_false, z_done;
   Label w_false, w_done;
-  __ subq(RSP, Immediate(16));
+  __ AddImmediate(RSP, Immediate(-16), PP);
 
-  __ CompareObject(v0, Bool::True());
+  __ CompareObject(v0, Bool::True(), PP);
   __ j(NOT_EQUAL, &x_false);
-  __ movq(temp, Immediate(0xFFFFFFFF));
+  __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
   __ jmp(&x_done);
   __ Bind(&x_false);
-  __ movq(temp, Immediate(0x0));
+  __ LoadImmediate(temp, Immediate(0x0), PP);
   __ Bind(&x_done);
   __ movl(Address(RSP, 0), temp);
 
-  __ CompareObject(v1, Bool::True());
+  __ CompareObject(v1, Bool::True(), PP);
   __ j(NOT_EQUAL, &y_false);
-  __ movq(temp, Immediate(0xFFFFFFFF));
+  __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
   __ jmp(&y_done);
   __ Bind(&y_false);
-  __ movq(temp, Immediate(0x0));
+  __ LoadImmediate(temp, Immediate(0x0), PP);
   __ Bind(&y_done);
   __ movl(Address(RSP, 4), temp);
 
-  __ CompareObject(v2, Bool::True());
+  __ CompareObject(v2, Bool::True(), PP);
   __ j(NOT_EQUAL, &z_false);
-  __ movq(temp, Immediate(0xFFFFFFFF));
+  __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
   __ jmp(&z_done);
   __ Bind(&z_false);
-  __ movq(temp, Immediate(0x0));
+  __ LoadImmediate(temp, Immediate(0x0), PP);
   __ Bind(&z_done);
   __ movl(Address(RSP, 8), temp);
 
-  __ CompareObject(v3, Bool::True());
+  __ CompareObject(v3, Bool::True(), PP);
   __ j(NOT_EQUAL, &w_false);
-  __ movq(temp, Immediate(0xFFFFFFFF));
+  __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
   __ jmp(&w_done);
   __ Bind(&w_false);
-  __ movq(temp, Immediate(0x0));
+  __ LoadImmediate(temp, Immediate(0x0), PP);
   __ Bind(&w_done);
   __ movl(Address(RSP, 12), temp);
 
   __ movups(result, Address(RSP, 0));
-  __ addq(RSP, Immediate(16));
+  __ AddImmediate(RSP, Immediate(16), PP);
 }
 
 
@@ -3688,7 +3638,7 @@
   Register result = locs()->out().reg();
   Label done;
   Label non_zero;
-  __ subq(RSP, Immediate(16));
+  __ AddImmediate(RSP, Immediate(-16), PP);
   // Move value to stack.
   __ movups(Address(RSP, 0), value);
   switch (op_kind()) {
@@ -3706,7 +3656,7 @@
       break;
     default: UNREACHABLE();
   }
-  __ addq(RSP, Immediate(16));
+  __ AddImmediate(RSP, Immediate(16), PP);
   __ testl(result, result);
   __ j(NOT_ZERO, &non_zero, Assembler::kNearJump);
   __ LoadObject(result, Bool::False(), PP);
@@ -3769,43 +3719,43 @@
   Register flag = locs()->in(1).reg();
   Register temp = locs()->temp(0).reg();
   ASSERT(mask == locs()->out().fpu_reg());
-  __ subq(RSP, Immediate(16));
+  __ AddImmediate(RSP, Immediate(-16), PP);
   // Copy mask to stack.
   __ movups(Address(RSP, 0), mask);
   Label falsePath, exitPath;
-  __ CompareObject(flag, Bool::True());
+  __ CompareObject(flag, Bool::True(), PP);
   __ j(NOT_EQUAL, &falsePath);
   switch (op_kind()) {
     case MethodRecognizer::kUint32x4WithFlagX:
-      __ movq(temp, Immediate(0xFFFFFFFF));
+      __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
       __ movl(Address(RSP, 0), temp);
       __ jmp(&exitPath);
       __ Bind(&falsePath);
-      __ movq(temp, Immediate(0x0));
+      __ LoadImmediate(temp, Immediate(0x0), PP);
       __ movl(Address(RSP, 0), temp);
     break;
     case MethodRecognizer::kUint32x4WithFlagY:
-      __ movq(temp, Immediate(0xFFFFFFFF));
+      __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
       __ movl(Address(RSP, 4), temp);
       __ jmp(&exitPath);
       __ Bind(&falsePath);
-      __ movq(temp, Immediate(0x0));
+      __ LoadImmediate(temp, Immediate(0x0), PP);
       __ movl(Address(RSP, 4), temp);
     break;
     case MethodRecognizer::kUint32x4WithFlagZ:
-      __ movq(temp, Immediate(0xFFFFFFFF));
+      __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
       __ movl(Address(RSP, 8), temp);
       __ jmp(&exitPath);
       __ Bind(&falsePath);
-      __ movq(temp, Immediate(0x0));
+      __ LoadImmediate(temp, Immediate(0x0), PP);
       __ movl(Address(RSP, 8), temp);
     break;
     case MethodRecognizer::kUint32x4WithFlagW:
-      __ movq(temp, Immediate(0xFFFFFFFF));
+      __ LoadImmediate(temp, Immediate(0xFFFFFFFF), PP);
       __ movl(Address(RSP, 12), temp);
       __ jmp(&exitPath);
       __ Bind(&falsePath);
-      __ movq(temp, Immediate(0x0));
+      __ LoadImmediate(temp, Immediate(0x0), PP);
       __ movl(Address(RSP, 12), temp);
     break;
     default: UNREACHABLE();
@@ -3813,7 +3763,7 @@
   __ Bind(&exitPath);
   // Copy mask back to register.
   __ movups(mask, Address(RSP, 0));
-  __ addq(RSP, Immediate(16));
+  __ AddImmediate(RSP, Immediate(16), PP);
 }
 
 
@@ -3936,7 +3886,8 @@
     }
     case Token::kBIT_NOT:
       __ notq(value);
-      __ andq(value, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
+      // Remove inverted smi-tag.
+      __ AndImmediate(value, Immediate(~kSmiTagMask), PP);
       break;
     default:
       UNREACHABLE();
@@ -4011,7 +3962,7 @@
 
     __ Bind(&returns_nan);
     static double kNaN = NAN;
-    __ movq(temp, Immediate(reinterpret_cast<intptr_t>(&kNaN)));
+    __ LoadImmediate(temp, Immediate(reinterpret_cast<intptr_t>(&kNaN)), PP);
     __ movsd(result, Address(temp, 0));
     __ jmp(&done, Assembler::kNearJump);
 
@@ -4337,7 +4288,7 @@
     Label* deopt = compiler->AddDeoptStub(deopt_id(),
                                           kDeoptCheckClass);
     __ CompareObject(locs()->in(0).reg(),
-                     Object::null_object());
+                     Object::null_object(), PP);
     __ j(EQUAL, deopt);
     return;
   }
@@ -4434,12 +4385,14 @@
   if (index_loc.IsConstant()) {
     Register length = length_loc.reg();
     const Smi& index = Smi::Cast(index_loc.constant());
-    __ cmpq(length, Immediate(reinterpret_cast<int64_t>(index.raw())));
+    __ CompareImmediate(
+        length, Immediate(reinterpret_cast<int64_t>(index.raw())), PP);
     __ j(BELOW_EQUAL, deopt);
   } else if (length_loc.IsConstant()) {
     const Smi& length = Smi::Cast(length_loc.constant());
     Register index = index_loc.reg();
-    __ cmpq(index, Immediate(reinterpret_cast<int64_t>(length.raw())));
+    __ CompareImmediate(
+        index, Immediate(reinterpret_cast<int64_t>(length.raw())), PP);
     __ j(ABOVE_EQUAL, deopt);
   } else {
     Register length = length_loc.reg();
@@ -4546,21 +4499,13 @@
 void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   __ Bind(compiler->GetJumpLabel(this));
   if (!compiler->is_optimizing()) {
+    compiler->EmitEdgeCounter();
+    // The deoptimization descriptor points after the edge counter code for
+    // uniformity with ARM and MIPS, where we can reuse pattern matching
+    // code that matches backwards from the end of the pattern.
     compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
                                    deopt_id_,
                                    Scanner::kDummyTokenIndex);
-    // Add an edge counter.
-    const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
-    counter.SetAt(0, Smi::Handle(Smi::New(0)));
-    Label done;
-    __ Comment("Edge counter");
-    __ LoadObject(RAX, counter, PP);
-    __ addq(FieldAddress(RAX, Array::element_offset(0)),
-            Immediate(Smi::RawValue(1)));
-    __ j(NO_OVERFLOW, &done);
-    __ movq(FieldAddress(RAX, Array::element_offset(0)),
-            Immediate(Smi::RawValue(Smi::kMaxValue)));
-    __ Bind(&done);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -4575,23 +4520,15 @@
 
 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   if (!compiler->is_optimizing()) {
-    // Add deoptimization descriptor for deoptimizing instructions that may
-    // be inserted before this instruction.
+    compiler->EmitEdgeCounter();
+    // Add a deoptimization descriptor for deoptimizing instructions that
+    // may be inserted before this instruction.  This descriptor points
+    // after the edge counter for uniformity with ARM and MIPS, where we can
+    // reuse pattern matching that matches backwards from the end of the
+    // pattern.
     compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   0);  // No token position.
-    // Add an edge counter.
-    const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
-    counter.SetAt(0, Smi::Handle(Smi::New(0)));
-    Label done;
-    __ Comment("Edge counter");
-    __ LoadObject(RAX, counter, PP);
-    __ addq(FieldAddress(RAX, Array::element_offset(0)),
-            Immediate(Smi::RawValue(1)));
-    __ j(NO_OVERFLOW, &done);
-    __ movq(FieldAddress(RAX, Array::element_offset(0)),
-            Immediate(Smi::RawValue(Smi::kMaxValue)));
-    __ Bind(&done);
+                                   Scanner::kDummyTokenIndex);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index e7edd62..fa3992b 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -69,7 +69,7 @@
   // the class matches and the rest of the method name starting with
   // the dot matches, we have found a match.
   // We do not store the entire factory constructor name with the class
-  // (e.g: _GrowableObjectArray.withData) because the actual function name
+  // (e.g: _GrowableList.withData) because the actual function name
   //  that we see here includes the private key.
   if (test_function_name[0] == '.') {
     function_name = strstr(function_name, ".");
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index de6d92e..e5d4dd2 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -31,20 +31,20 @@
   V(_Double, get:isNegative, Double_getIsNegative, 1711391869)                 \
   V(_Double, _mulFromInteger, Double_mulFromInteger, 1238321808)               \
   V(_Double, .fromInteger, Double_fromInteger, 82414734)                       \
-  V(_ObjectArray, ., ObjectArray_Allocate, 1558200848)                         \
-  V(_ObjectArray, get:length, Array_getLength, 259382695)                      \
-  V(_ObjectArray, [], Array_getIndexed, 544020319)                             \
-  V(_ObjectArray, []=, Array_setIndexed, 304306010)                            \
-  V(_GrowableObjectArray, .withData, GrowableArray_Allocate, 619965861)        \
-  V(_GrowableObjectArray, get:length, GrowableArray_getLength, 1160417196)     \
-  V(_GrowableObjectArray, get:_capacity, GrowableArray_getCapacity, 1509841570)\
-  V(_GrowableObjectArray, [], GrowableArray_getIndexed, 951312767)             \
-  V(_GrowableObjectArray, []=, GrowableArray_setIndexed, 1366856519)           \
-  V(_GrowableObjectArray, _setLength, GrowableArray_setLength, 1112774552)     \
-  V(_GrowableObjectArray, _setData, GrowableArray_setData, 1574432374)         \
-  V(_GrowableObjectArray, add, GrowableArray_add, 635801182)                   \
-  V(_ImmutableArray, [], ImmutableArray_getIndexed, 1345387065)                \
-  V(_ImmutableArray, get:length, ImmutableArray_getLength, 1342001998)         \
+  V(_List, ., List_Allocate, 1436567945)                                       \
+  V(_List, get:length, Array_getLength, 215153395)                             \
+  V(_List, [], Array_getIndexed, 1079829188)                                   \
+  V(_List, []=, Array_setIndexed, 748954698)                                   \
+  V(_GrowableList, .withData, GrowableList_Allocate, 461305701)                \
+  V(_GrowableList, get:length, GrowableList_getLength, 1654225242)             \
+  V(_GrowableList, get:_capacity, GrowableList_getCapacity, 817090003)         \
+  V(_GrowableList, [], GrowableList_getIndexed, 1686777561)                    \
+  V(_GrowableList, []=, GrowableList_setIndexed, 327404102)                    \
+  V(_GrowableList, _setLength, GrowableList_setLength, 1227678442)             \
+  V(_GrowableList, _setData, GrowableList_setData, 1375509957)                 \
+  V(_GrowableList, add, GrowableList_add, 996912766)                           \
+  V(_ImmutableList, [], ImmutableList_getIndexed, 25983597)                    \
+  V(_ImmutableList, get:length, ImmutableList_getLength, 578733070)            \
   V(Object, ==, Object_equal, 936042315)                                       \
   V(_StringBase, get:hashCode, String_getHashCode, 654543028)                  \
   V(_StringBase, get:isEmpty, String_getIsEmpty, 879849436)                    \
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 734b889..8770677 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -20,7 +20,7 @@
 
 #define __ assembler->
 
-void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
+void Intrinsifier::List_Allocate(Assembler* assembler) {
   const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
   const intptr_t kArrayLengthOffset = 0 * kWordSize;
   Label fall_through;
@@ -133,7 +133,7 @@
 }
 
 
-void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getLength(Assembler* assembler) {
   return Array_getLength(assembler);
 }
 
@@ -160,7 +160,7 @@
 }
 
 
-void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) {
   return Array_getIndexed(assembler);
 }
 
@@ -168,7 +168,7 @@
 static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
   const Library& core_lib = Library::Handle(Library::CoreLibrary());
   const Class& cls = Class::Handle(
-      core_lib.LookupClassAllowPrivate(Symbols::ObjectArray()));
+      core_lib.LookupClassAllowPrivate(Symbols::_List()));
   ASSERT(!cls.IsNull());
   ASSERT(cls.HasTypeArguments());
   ASSERT(cls.NumTypeArguments() == 1);
@@ -247,7 +247,7 @@
 
 // Allocate a GrowableObjectArray using the backing array specified.
 // On stack: type argument (+1), data (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableList_Allocate(Assembler* assembler) {
   // The newly allocated object is returned in R0.
   const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
   const intptr_t kArrayOffset = 0 * kWordSize;
@@ -313,14 +313,14 @@
 }
 
 
-void Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, GrowableObjectArray::length_offset()));
   __ Ret();
 }
 
 
-void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
+void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) {
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ ldr(R0, FieldAddress(R0, GrowableObjectArray::data_offset()));
   __ ldr(R0, FieldAddress(R0, Array::length_offset()));
@@ -328,7 +328,7 @@
 }
 
 
-void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) {
   Label fall_through;
 
   __ ldr(R0, Address(SP, + 0 * kWordSize));  // Index
@@ -353,7 +353,7 @@
 
 // Set value into growable object array at specified index.
 // On stack: growable array (+2), index (+1), value (+0).
-void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
     return;
   }
@@ -383,7 +383,7 @@
 // Set length of growable object array. The length cannot
 // be greater than the length of the data container.
 // On stack: growable array (+1), length (+0).
-void Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_setLength(Assembler* assembler) {
   __ ldr(R0, Address(SP, 1 * kWordSize));  // Growable array.
   __ ldr(R1, Address(SP, 0 * kWordSize));  // Length value.
   __ tst(R1, ShifterOperand(kSmiTagMask));  // Check for Smi.
@@ -395,7 +395,7 @@
 
 // Set data of growable object array.
 // On stack: growable array (+1), data (+0).
-void Intrinsifier::GrowableArray_setData(Assembler* assembler) {
+void Intrinsifier::GrowableList_setData(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
     return;
   }
@@ -418,7 +418,7 @@
 // Add an element to growable array if it doesn't need to grow, otherwise
 // call into regular code.
 // On stack: growable array (+1), value (+0).
-void Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableList_add(Assembler* assembler) {
   // In checked mode we need to type-check the incoming argument.
   if (FLAG_enable_type_checks) return;
   Label fall_through;
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 64758e6..f9634c8 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -28,7 +28,7 @@
 
 #define __ assembler->
 
-void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
+void Intrinsifier::List_Allocate(Assembler* assembler) {
   // This snippet of inlined code uses the following registers:
   // EAX, EBX, EDI
   // and the newly allocated object is returned in EAX.
@@ -142,7 +142,7 @@
 }
 
 
-void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getLength(Assembler* assembler) {
   return Array_getLength(assembler);
 }
 
@@ -165,7 +165,7 @@
 }
 
 
-void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) {
   return Array_getIndexed(assembler);
 }
 
@@ -173,7 +173,7 @@
 static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
   const Library& core_lib = Library::Handle(Library::CoreLibrary());
   const Class& cls = Class::Handle(
-      core_lib.LookupClassAllowPrivate(Symbols::ObjectArray()));
+      core_lib.LookupClassAllowPrivate(Symbols::_List()));
   ASSERT(!cls.IsNull());
   ASSERT(cls.HasTypeArguments());
   ASSERT(cls.NumTypeArguments() == 1);
@@ -245,7 +245,7 @@
 
 // Allocate a GrowableObjectArray using the backing array specified.
 // On stack: type argument (+2), data (+1), return-address (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableList_Allocate(Assembler* assembler) {
   // This snippet of inlined code uses the following registers:
   // EAX, EBX
   // and the newly allocated object is returned in EAX.
@@ -312,7 +312,7 @@
 
 // Get length of growable object array.
 // On stack: growable array (+1), return-address (+0).
-void Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
   __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::length_offset()));
   __ ret();
@@ -321,7 +321,7 @@
 
 // Get capacity of growable object array.
 // On stack: growable array (+1), return-address (+0).
-void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
+void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) {
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
   __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset()));
   __ movl(EAX, FieldAddress(EAX, Array::length_offset()));
@@ -331,7 +331,7 @@
 
 // Access growable object array at specified index.
 // On stack: growable array (+2), index (+1), return-address (+0).
-void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) {
   Label fall_through;
   __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Index.
   __ movl(EAX, Address(ESP, + 2 * kWordSize));  // GrowableArray.
@@ -353,7 +353,7 @@
 
 // Set value into growable object array at specified index.
 // On stack: growable array (+3), index (+2), value (+1), return-address (+0).
-void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
     return;
   }
@@ -381,7 +381,7 @@
 // Set length of growable object array. The length cannot
 // be greater than the length of the data container.
 // On stack: growable array (+2), length (+1), return-address (+0).
-void Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_setLength(Assembler* assembler) {
   Label fall_through;
   __ movl(EAX, Address(ESP, + 2 * kWordSize));  // Growable array.
   __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Length value.
@@ -395,7 +395,7 @@
 
 // Set data of growable object array.
 // On stack: growable array (+2), data (+1), return-address (+0).
-void Intrinsifier::GrowableArray_setData(Assembler* assembler) {
+void Intrinsifier::GrowableList_setData(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
     return;
   }
@@ -418,7 +418,7 @@
 // Add an element to growable array if it doesn't need to grow, otherwise
 // call into regular code.
 // On stack: growable array (+2), value (+1), return-address (+0).
-void Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableList_add(Assembler* assembler) {
   // In checked mode we need to type-check the incoming argument.
   if (FLAG_enable_type_checks) return;
 
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index de39ced8..3a12f24 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -20,7 +20,7 @@
 
 #define __ assembler->
 
-void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
+void Intrinsifier::List_Allocate(Assembler* assembler) {
   const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
   const intptr_t kArrayLengthOffset = 0 * kWordSize;
   Label fall_through;
@@ -140,7 +140,7 @@
 }
 
 
-void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getLength(Assembler* assembler) {
   return Array_getLength(assembler);
 }
 
@@ -168,7 +168,7 @@
 }
 
 
-void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) {
   return Array_getIndexed(assembler);
 }
 
@@ -176,7 +176,7 @@
 static intptr_t ComputeObjectArrayTypeArgumentsOffset() {
   const Library& core_lib = Library::Handle(Library::CoreLibrary());
   const Class& cls = Class::Handle(
-      core_lib.LookupClassAllowPrivate(Symbols::ObjectArray()));
+      core_lib.LookupClassAllowPrivate(Symbols::_List()));
   ASSERT(!cls.IsNull());
   ASSERT(cls.HasTypeArguments());
   ASSERT(cls.NumTypeArguments() == 1);
@@ -252,7 +252,7 @@
 
 // Allocate a GrowableObjectArray using the backing array specified.
 // On stack: type argument (+1), data (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableList_Allocate(Assembler* assembler) {
   // The newly allocated object is returned in V0.
   const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
   const intptr_t kArrayOffset = 0 * kWordSize;
@@ -317,7 +317,7 @@
 }
 
 
-void Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
   __ lw(V0, Address(SP, 0 * kWordSize));
   __ Ret();
   __ delay_slot()->lw(V0,
@@ -325,7 +325,7 @@
 }
 
 
-void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
+void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) {
   __ lw(V0, Address(SP, 0 * kWordSize));
   __ lw(V0, FieldAddress(V0, GrowableObjectArray::data_offset()));
   __ Ret();
@@ -333,7 +333,7 @@
 }
 
 
-void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) {
   Label fall_through;
 
   __ lw(T0, Address(SP, 0 * kWordSize));  // Index
@@ -360,7 +360,7 @@
 
 // Set value into growable object array at specified index.
 // On stack: growable array (+2), index (+1), value (+0).
-void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
     return;
   }
@@ -390,7 +390,7 @@
 // Set length of growable object array. The length cannot
 // be greater than the length of the data container.
 // On stack: growable array (+1), length (+0).
-void Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_setLength(Assembler* assembler) {
   Label fall_through;
   __ lw(T1, Address(SP, 0 * kWordSize));  // Length value.
   __ andi(CMPRES, T1, Immediate(kSmiTagMask));
@@ -405,7 +405,7 @@
 
 // Set data of growable object array.
 // On stack: growable array (+1), data (+0).
-void Intrinsifier::GrowableArray_setData(Assembler* assembler) {
+void Intrinsifier::GrowableList_setData(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
     return;
   }
@@ -428,7 +428,7 @@
 // Add an element to growable array if it doesn't need to grow, otherwise
 // call into regular code.
 // On stack: growable array (+1), value (+0).
-void Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableList_add(Assembler* assembler) {
   // In checked mode we need to type-check the incoming argument.
   if (FLAG_enable_type_checks) return;
   Label fall_through;
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index 83180be..e976fd5 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -27,7 +27,7 @@
 #define __ assembler->
 
 
-void Intrinsifier::ObjectArray_Allocate(Assembler* assembler) {
+void Intrinsifier::List_Allocate(Assembler* assembler) {
   // This snippet of inlined code uses the following registers:
   // RAX, RCX, RDI, R13
   // and the newly allocated object is returned in RAX.
@@ -141,7 +141,7 @@
 }
 
 
-void Intrinsifier::ImmutableArray_getLength(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getLength(Assembler* assembler) {
   return Array_getLength(assembler);
 }
 
@@ -164,7 +164,7 @@
 }
 
 
-void Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::ImmutableList_getIndexed(Assembler* assembler) {
   return Array_getIndexed(assembler);
 }
 
@@ -197,7 +197,7 @@
 
 // Allocate a GrowableObjectArray using the backing array specified.
 // On stack: type argument (+2), data (+1), return-address (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
+void Intrinsifier::GrowableList_Allocate(Assembler* assembler) {
   // This snippet of inlined code uses the following registers:
   // RAX, RCX, R13
   // and the newly allocated object is returned in RAX.
@@ -267,14 +267,14 @@
 
 // Get length of growable object array.
 // On stack: growable array (+1), return-address (+0).
-void Intrinsifier::GrowableArray_getLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
   __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::length_offset()));
   __ ret();
 }
 
 
-void Intrinsifier::GrowableArray_getCapacity(Assembler* assembler) {
+void Intrinsifier::GrowableList_getCapacity(Assembler* assembler) {
   __ movq(RAX, Address(RSP, + 1 * kWordSize));
   __ movq(RAX, FieldAddress(RAX, GrowableObjectArray::data_offset()));
   __ movq(RAX, FieldAddress(RAX, Array::length_offset()));
@@ -284,7 +284,7 @@
 
 // Access growable object array at specified index.
 // On stack: growable array (+2), index (+1), return-address (+0).
-void Intrinsifier::GrowableArray_getIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_getIndexed(Assembler* assembler) {
   Label fall_through;
   __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Index.
   __ movq(RAX, Address(RSP, + 2 * kWordSize));  // GrowableArray.
@@ -306,7 +306,7 @@
 
 // Set value into growable object array at specified index.
 // On stack: growable array (+3), index (+2), value (+1), return-address (+0).
-void Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) {
+void Intrinsifier::GrowableList_setIndexed(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
     return;
   }
@@ -334,7 +334,7 @@
 // Set length of growable object array. The length cannot
 // be greater than the length of the data container.
 // On stack: growable array (+2), length (+1), return-address (+0).
-void Intrinsifier::GrowableArray_setLength(Assembler* assembler) {
+void Intrinsifier::GrowableList_setLength(Assembler* assembler) {
   Label fall_through;
   __ movq(RAX, Address(RSP, + 2 * kWordSize));  // Growable array.
   __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Length value.
@@ -348,7 +348,7 @@
 
 // Set data of growable object array.
 // On stack: growable array (+2), data (+1), return-address (+0).
-void Intrinsifier::GrowableArray_setData(Assembler* assembler) {
+void Intrinsifier::GrowableList_setData(Assembler* assembler) {
   if (FLAG_enable_type_checks) {
     return;
   }
@@ -370,7 +370,7 @@
 // Add an element to growable array if it doesn't need to grow, otherwise
 // call into regular code.
 // On stack: growable array (+2), value (+1), return-address (+0).
-void Intrinsifier::GrowableArray_add(Assembler* assembler) {
+void Intrinsifier::GrowableList_add(Assembler* assembler) {
   // In checked mode we need to check the incoming argument.
   if (FLAG_enable_type_checks) return;
   Label fall_through;
@@ -1101,7 +1101,8 @@
   __ TryAllocate(double_class,
                  &fall_through,
                  Assembler::kNearJump,
-                 RAX);  // Result register.
+                 RAX,  // Result register.
+                 kNoRegister);  // Pool pointer might not be loaded.
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
@@ -1145,7 +1146,8 @@
   __ TryAllocate(double_class,
                  &fall_through,
                  Assembler::kNearJump,
-                 RAX);  // Result register.
+                 RAX,  // Result register.
+                 kNoRegister);  // Pool pointer might not be loaded.
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
@@ -1166,7 +1168,8 @@
   __ TryAllocate(double_class,
                  &fall_through,
                  Assembler::kNearJump,
-                 RAX);  // Result register.
+                 RAX,  // Result register.
+                 kNoRegister);  // Pool pointer might not be loaded.
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&fall_through);
@@ -1236,7 +1239,8 @@
   __ TryAllocate(double_class,
                  &alloc_failed,
                  Assembler::kNearJump,
-                 RAX);  // Result register.
+                 RAX,  // Result register.
+                 kNoRegister);  // Pool pointer might not be loaded.
   __ fstpl(FieldAddress(RAX, Double::value_offset()));
   __ ret();
 
@@ -1283,7 +1287,8 @@
   __ TryAllocate(double_class,
                  &fall_through,
                  Assembler::kNearJump,
-                 RAX);  // Result register.
+                 RAX,  // Result register.
+                 kNoRegister);  // Pool pointer might not be loaded.
   __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
   __ ret();
   __ Bind(&is_smi);
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 5d12dc6..0e6ad03 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -14,6 +14,7 @@
 #include "vm/dart_api_state.h"
 #include "vm/dart_entry.h"
 #include "vm/debugger.h"
+#include "vm/deopt_instructions.h"
 #include "vm/heap.h"
 #include "vm/heap_histogram.h"
 #include "vm/message_handler.h"
@@ -38,7 +39,6 @@
             "Track function usage and report.");
 DEFINE_FLAG(bool, trace_isolates, false,
             "Trace isolate creation and shut down.");
-DECLARE_FLAG(bool, trace_deoptimization_verbose);
 
 
 void Isolate::RegisterClass(const Class& cls) {
@@ -270,113 +270,6 @@
 #endif
 
 
-void DeferredDouble::Materialize() {
-  RawDouble** double_slot = reinterpret_cast<RawDouble**>(slot());
-  *double_slot = Double::New(value());
-
-  if (FLAG_trace_deoptimization_verbose) {
-    OS::PrintErr("materializing double at %" Px ": %g\n",
-                 reinterpret_cast<uword>(slot()), value());
-  }
-}
-
-
-void DeferredMint::Materialize() {
-  RawMint** mint_slot = reinterpret_cast<RawMint**>(slot());
-  ASSERT(!Smi::IsValid64(value()));
-  Mint& mint = Mint::Handle();
-  mint ^= Integer::New(value());
-  *mint_slot = mint.raw();
-
-  if (FLAG_trace_deoptimization_verbose) {
-    OS::PrintErr("materializing mint at %" Px ": %" Pd64 "\n",
-                 reinterpret_cast<uword>(slot()), value());
-  }
-}
-
-
-void DeferredFloat32x4::Materialize() {
-  RawFloat32x4** float32x4_slot = reinterpret_cast<RawFloat32x4**>(slot());
-  RawFloat32x4* raw_float32x4 = Float32x4::New(value());
-  *float32x4_slot = raw_float32x4;
-
-  if (FLAG_trace_deoptimization_verbose) {
-    float x = raw_float32x4->x();
-    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",
-                 reinterpret_cast<uword>(slot()), x, y, z, w);
-  }
-}
-
-
-void DeferredUint32x4::Materialize() {
-  RawUint32x4** uint32x4_slot = reinterpret_cast<RawUint32x4**>(slot());
-  RawUint32x4* raw_uint32x4 = Uint32x4::New(value());
-  *uint32x4_slot = raw_uint32x4;
-
-  if (FLAG_trace_deoptimization_verbose) {
-    uint32_t x = raw_uint32x4->x();
-    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",
-                 reinterpret_cast<uword>(slot()), x, y, z, w);
-  }
-}
-
-
-void DeferredObjectRef::Materialize() {
-  DeferredObject* obj = Isolate::Current()->GetDeferredObject(index());
-  *slot() = obj->object();
-  if (FLAG_trace_deoptimization_verbose) {
-    OS::PrintErr("writing instance ref at %" Px ": %s\n",
-                 reinterpret_cast<uword>(slot()),
-                 Instance::Handle(obj->object()).ToCString());
-  }
-}
-
-
-RawInstance* DeferredObject::object() {
-  if (object_ == NULL) {
-    Materialize();
-  }
-  return object_->raw();
-}
-
-
-void DeferredObject::Materialize() {
-  Class& cls = Class::Handle();
-  cls ^= GetClass();
-
-  if (FLAG_trace_deoptimization_verbose) {
-    OS::PrintErr("materializing instance of %s (%" Px ", %" Pd " fields)\n",
-                 cls.ToCString(),
-                 reinterpret_cast<uword>(args_),
-                 field_count_);
-  }
-
-  const Instance& obj = Instance::ZoneHandle(Instance::New(cls));
-
-  Field& field = Field::Handle();
-  Object& value = Object::Handle();
-  for (intptr_t i = 0; i < field_count_; i++) {
-    field ^= GetField(i);
-    value = GetValue(i);
-    obj.SetField(field, value);
-
-    if (FLAG_trace_deoptimization_verbose) {
-      OS::PrintErr("    %s <- %s\n",
-                   String::Handle(field.name()).ToCString(),
-                   value.ToCString());
-    }
-  }
-
-  object_ = &obj;
-}
-
-
 #define REUSABLE_HANDLE_INITIALIZERS(object)                                   \
   object##_handle_(NULL),
 
@@ -409,14 +302,7 @@
       gc_prologue_callbacks_(),
       gc_epilogue_callbacks_(),
       defer_finalization_count_(0),
-      deopt_cpu_registers_copy_(NULL),
-      deopt_fpu_registers_copy_(NULL),
-      deopt_frame_copy_(NULL),
-      deopt_frame_copy_size_(0),
-      deferred_boxes_(NULL),
-      deferred_object_refs_(NULL),
-      deferred_objects_count_(0),
-      deferred_objects_(NULL),
+      deopt_context_(NULL),
       stacktrace_(NULL),
       stack_frame_index_(-1),
       object_histogram_(NULL),
@@ -444,6 +330,7 @@
   mutex_ = NULL;  // Fail fast if interrupts are scheduled on a dead isolate.
   delete message_handler_;
   message_handler_ = NULL;  // Fail fast if we send messages to a dead isolate.
+  ASSERT(deopt_context_ == NULL);  // No deopt in progress when isolate deleted.
   delete object_histogram_;
 }
 
@@ -864,6 +751,11 @@
 
   // Visit objects in the debugger.
   debugger()->VisitObjectPointers(visitor);
+
+  // Visit objects that are being used for deoptimization.
+  if (deopt_context() != NULL) {
+    deopt_context()->VisitObjectPointers(visitor);
+  }
 }
 
 
@@ -1079,31 +971,6 @@
 }
 
 
-static void FillDeferredSlots(DeferredSlot** slot_list) {
-  DeferredSlot* slot = *slot_list;
-  *slot_list = NULL;
-
-  while (slot != NULL) {
-    DeferredSlot* current = slot;
-    slot = slot->next();
-
-    current->Materialize();
-
-    delete current;
-  }
-}
-
-
-void Isolate::MaterializeDeferredBoxes() {
-  FillDeferredSlots(&deferred_boxes_);
-}
-
-
-void Isolate::MaterializeDeferredObjects() {
-  FillDeferredSlots(&deferred_object_refs_);
-}
-
-
 static char* GetRootScriptUri(Isolate* isolate) {
   const Library& library =
       Library::Handle(isolate->object_store()->root_library());
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 7a71eb4..128f7e2 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -25,6 +25,7 @@
 class Class;
 class CodeIndexTable;
 class Debugger;
+class DeoptContext;
 class Field;
 class Function;
 class HandleScope;
@@ -58,174 +59,6 @@
 class ObjectIdRing;
 
 
-// Used by the deoptimization infrastructure to defer allocation of unboxed
-// objects until frame is fully rewritten and GC is safe.
-// Describes a stack slot that should be populated with a reference to the
-// materialized object.
-class DeferredSlot {
- public:
-  DeferredSlot(RawInstance** slot, DeferredSlot* next)
-      : slot_(slot), next_(next) { }
-  virtual ~DeferredSlot() { }
-
-  RawInstance** slot() const { return slot_; }
-  DeferredSlot* next() const { return next_; }
-
-  virtual void Materialize() = 0;
-
- private:
-  RawInstance** const slot_;
-  DeferredSlot* const next_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeferredSlot);
-};
-
-
-class DeferredDouble : public DeferredSlot {
- public:
-  DeferredDouble(double value, RawInstance** slot, DeferredSlot* next)
-      : DeferredSlot(slot, next), value_(value) { }
-
-  virtual void Materialize();
-
-  double value() const { return value_; }
-
- private:
-  const double value_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeferredDouble);
-};
-
-
-class DeferredMint : public DeferredSlot {
- public:
-  DeferredMint(int64_t value, RawInstance** slot, DeferredSlot* next)
-      : DeferredSlot(slot, next), value_(value) { }
-
-  virtual void Materialize();
-
-  int64_t value() const { return value_; }
-
- private:
-  const int64_t value_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeferredMint);
-};
-
-
-class DeferredFloat32x4 : public DeferredSlot {
- public:
-  DeferredFloat32x4(simd128_value_t value, RawInstance** slot,
-                    DeferredSlot* next)
-      : DeferredSlot(slot, next), value_(value) { }
-
-  virtual void Materialize();
-
-  simd128_value_t value() const { return value_; }
-
- private:
-  const simd128_value_t value_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeferredFloat32x4);
-};
-
-
-class DeferredUint32x4 : public DeferredSlot {
- public:
-  DeferredUint32x4(simd128_value_t value, RawInstance** slot,
-                   DeferredSlot* next)
-      : DeferredSlot(slot, next), value_(value) { }
-
-  virtual void Materialize();
-
-  simd128_value_t value() const { return value_; }
-
- private:
-  const simd128_value_t value_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeferredUint32x4);
-};
-
-
-// Describes a slot that contains a reference to an object that had its
-// allocation removed by AllocationSinking pass.
-// Object itself is described and materialized by DeferredObject.
-class DeferredObjectRef : public DeferredSlot {
- public:
-  DeferredObjectRef(intptr_t index, RawInstance** slot, DeferredSlot* next)
-      : DeferredSlot(slot, next), index_(index) { }
-
-  virtual void Materialize();
-
-  intptr_t index() const { return index_; }
-
- private:
-  const intptr_t index_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeferredObjectRef);
-};
-
-
-// Describes an object which allocation was removed by AllocationSinking pass.
-// Arguments for materialization are stored as a part of expression stack
-// for the bottommost deoptimized frame so that GC could discover them.
-// They will be removed from the stack at the very end of deoptimization.
-class DeferredObject {
- public:
-  DeferredObject(intptr_t field_count, intptr_t* args)
-      : field_count_(field_count),
-        args_(reinterpret_cast<RawObject**>(args)),
-        object_(NULL) { }
-
-  intptr_t ArgumentCount() const {
-    return kFieldsStartIndex + kFieldEntrySize * field_count_;
-  }
-
-  RawInstance* object();
-
- private:
-  enum {
-    kClassIndex = 0,
-    kFieldsStartIndex = kClassIndex + 1
-  };
-
-  enum {
-    kFieldIndex = 0,
-    kValueIndex,
-    kFieldEntrySize,
-  };
-
-  // Materializes the object. Returns amount of values that were consumed
-  // and should be removed from the expression stack at the very end of
-  // deoptimization.
-  void Materialize();
-
-  RawObject* GetClass() const {
-    return args_[kClassIndex];
-  }
-
-  RawObject* GetField(intptr_t index) const {
-    return args_[kFieldsStartIndex + kFieldEntrySize * index + kFieldIndex];
-  }
-
-  RawObject* GetValue(intptr_t index) const {
-    return args_[kFieldsStartIndex + kFieldEntrySize * index + kValueIndex];
-  }
-
-  // Amount of fields that have to be initialized.
-  const intptr_t field_count_;
-
-  // Pointer to the first materialization argument on the stack.
-  // The first argument is Class of the instance to materialize followed by
-  // Field, value pairs.
-  RawObject** args_;
-
-  // Object materialized from this description.
-  const Instance* object_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeferredObject);
-};
-
 #define REUSABLE_HANDLE_LIST(V)                                                \
   V(Object)                                                                    \
   V(Array)                                                                     \
@@ -503,29 +336,6 @@
     return file_close_callback_;
   }
 
-  intptr_t* deopt_cpu_registers_copy() const {
-    return deopt_cpu_registers_copy_;
-  }
-  void set_deopt_cpu_registers_copy(intptr_t* value) {
-    ASSERT((value == NULL) || (deopt_cpu_registers_copy_ == NULL));
-    deopt_cpu_registers_copy_ = value;
-  }
-  fpu_register_t* deopt_fpu_registers_copy() const {
-    return deopt_fpu_registers_copy_;
-  }
-  void set_deopt_fpu_registers_copy(fpu_register_t* value) {
-    ASSERT((value == NULL) || (deopt_fpu_registers_copy_ == NULL));
-    deopt_fpu_registers_copy_ = value;
-  }
-  intptr_t* deopt_frame_copy() const { return deopt_frame_copy_; }
-  void SetDeoptFrameCopy(intptr_t* value, intptr_t size) {
-    ASSERT((value == NULL) || (size > 0));
-    ASSERT((value == NULL) || (deopt_frame_copy_ == NULL));
-    deopt_frame_copy_ = value;
-    deopt_frame_copy_size_ = size;
-  }
-  intptr_t deopt_frame_copy_size() const { return deopt_frame_copy_size_; }
-
   void set_object_id_ring(ObjectIdRing* ring) {
     object_id_ring_ = ring;
   }
@@ -533,79 +343,12 @@
     return object_id_ring_;
   }
 
-  void PrepareForDeferredMaterialization(intptr_t count) {
-    if (count > 0) {
-      deferred_objects_ = new DeferredObject*[count];
-      deferred_objects_count_ = count;
-    }
+  DeoptContext* deopt_context() const { return deopt_context_; }
+  void set_deopt_context(DeoptContext* value) {
+    ASSERT(value == NULL || deopt_context_ == NULL);
+    deopt_context_ = value;
   }
 
-  void DeleteDeferredObjects() {
-    for (intptr_t i = 0; i < deferred_objects_count_; i++) {
-      delete deferred_objects_[i];
-    }
-    delete[] deferred_objects_;
-    deferred_objects_ = NULL;
-    deferred_objects_count_ = 0;
-  }
-
-  DeferredObject* GetDeferredObject(intptr_t idx) const {
-    return deferred_objects_[idx];
-  }
-
-  void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) {
-    deferred_objects_[idx] = object;
-  }
-
-  intptr_t DeferredObjectsCount() const {
-    return deferred_objects_count_;
-  }
-
-  void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) {
-    deferred_object_refs_ = new DeferredObjectRef(
-        idx,
-        reinterpret_cast<RawInstance**>(slot),
-        deferred_object_refs_);
-  }
-
-  void DeferDoubleMaterialization(double value, RawDouble** slot) {
-    deferred_boxes_ = new DeferredDouble(
-        value,
-        reinterpret_cast<RawInstance**>(slot),
-        deferred_boxes_);
-  }
-
-  void DeferMintMaterialization(int64_t value, RawMint** slot) {
-    deferred_boxes_ = new DeferredMint(
-        value,
-        reinterpret_cast<RawInstance**>(slot),
-        deferred_boxes_);
-  }
-
-  void DeferFloat32x4Materialization(simd128_value_t value,
-                                     RawFloat32x4** slot) {
-    deferred_boxes_ = new DeferredFloat32x4(
-        value,
-        reinterpret_cast<RawInstance**>(slot),
-        deferred_boxes_);
-  }
-
-  void DeferUint32x4Materialization(simd128_value_t value,
-                                    RawUint32x4** slot) {
-    deferred_boxes_ = new DeferredUint32x4(
-        value,
-        reinterpret_cast<RawInstance**>(slot),
-        deferred_boxes_);
-  }
-
-  // Populate all deferred slots that contain boxes for double, mint, simd
-  // values.
-  void MaterializeDeferredBoxes();
-
-  // Populate all slots containing references to objects which allocations
-  // were eliminated by AllocationSinking pass.
-  void MaterializeDeferredObjects();
-
   static char* GetStatus(const char* request);
 
   intptr_t BlockClassFinalization() {
@@ -668,17 +411,7 @@
   GcPrologueCallbacks gc_prologue_callbacks_;
   GcEpilogueCallbacks gc_epilogue_callbacks_;
   intptr_t defer_finalization_count_;
-
-  // Deoptimization support.
-  intptr_t* deopt_cpu_registers_copy_;
-  fpu_register_t* deopt_fpu_registers_copy_;
-  intptr_t* deopt_frame_copy_;
-  intptr_t deopt_frame_copy_size_;
-  DeferredSlot* deferred_boxes_;
-  DeferredSlot* deferred_object_refs_;
-
-  intptr_t deferred_objects_count_;
-  DeferredObject** deferred_objects_;
+  DeoptContext* deopt_context_;
 
   // Status support.
   char* stacktrace_;
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 20335cc..72a4833 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -87,46 +87,34 @@
   Isolate* isolate() const { return isolate_; }
   int ArgCount() const { return ArgcBits::decode(argc_tag_); }
 
-  // Returns true if the arguments are those of an instance function call.
-  bool ToInstanceFunction() const {
-    return InstanceFunctionBit::decode(argc_tag_);
-  }
-
-  // Returns true if the arguments are those of a closure function call.
-  bool ToClosureFunction() const {
-    return ClosureFunctionBit::decode(argc_tag_);
-  }
-
   RawObject* ArgAt(int index) const {
     ASSERT((index >= 0) && (index < ArgCount()));
     return (*argv_)[-index];
   }
 
-  int NumHiddenArgs() const {
-    // For static closure functions, the closure at index 0 is hidden.
-    // In the instance closure function case, the receiver is accessed from
-    // the context and the closure at index 0 is hidden, so the apparent
-    // argument count remains unchanged.
-    if (ToClosureFunction() && !ToInstanceFunction()) {
-      return 1;
-    }
-    return 0;
+  int NativeArgCount() const {
+    int function_bits = FunctionBits::decode(argc_tag_);
+    return ArgCount() - NumHiddenArgs(function_bits);
   }
 
-  int NativeArgCount() const {
-    return ArgCount() - NumHiddenArgs();
+  RawObject* NativeArg0() const {
+    int function_bits = FunctionBits::decode(argc_tag_);
+    if (function_bits == (kClosureFunctionBit | kInstanceFunctionBit)) {
+      // Retrieve the receiver from the context.
+      const Context& context = Context::Handle(isolate_->top_context());
+      return context.At(0);
+    }
+    return ArgAt(NumHiddenArgs(function_bits));
   }
 
   RawObject* NativeArgAt(int index) const {
     ASSERT((index >= 0) && (index < NativeArgCount()));
-    if ((index == 0) && ToClosureFunction() && ToInstanceFunction()) {
-      // Retrieve the receiver from the context.
-      const Context& context = Context::Handle(isolate_->top_context());
-      return context.At(0);
-    } else {
-      const int actual_index = index + NumHiddenArgs();
-      return ArgAt(actual_index);
+    if (index == 0) {
+      return NativeArg0();
     }
+    int function_bits = FunctionBits::decode(argc_tag_);
+    const int actual_index = index + NumHiddenArgs(function_bits);
+    return ArgAt(actual_index);
   }
 
   void SetReturn(const Object& value) const {
@@ -162,21 +150,29 @@
     ASSERT(function.is_native());
     ASSERT(!function.IsConstructor());  // Not supported.
     int tag = ArgcBits::encode(function.NumParameters());
-    tag = InstanceFunctionBit::update(!function.is_static(), tag);
-    tag = ClosureFunctionBit::update(function.IsClosureFunction(), tag);
-    return tag;
+    int function_bits = 0;
+    if (!function.is_static()) {
+      function_bits |= kInstanceFunctionBit;
+    }
+    if (function.IsClosureFunction()) {
+      function_bits |= kClosureFunctionBit;
+    }
+    return FunctionBits::update(function_bits, tag);
   }
 
  private:
+  enum {
+    kInstanceFunctionBit = 1,
+    kClosureFunctionBit = 2,
+  };
   enum ArgcTagBits {
     kArgcBit = 0,
     kArgcSize = 24,
-    kInstanceFunctionBit = 24,
-    kClosureFunctionBit = 25,
+    kFunctionBit = 24,
+    kFunctionSize = 2,
   };
   class ArgcBits : public BitField<int, kArgcBit, kArgcSize> {};
-  class InstanceFunctionBit : public BitField<bool, kInstanceFunctionBit, 1> {};
-  class ClosureFunctionBit : public BitField<bool, kClosureFunctionBit, 1> {};
+  class FunctionBits : public BitField<int, kFunctionBit, kFunctionSize> {};
   friend class Api;
   friend class BootstrapNatives;
   friend class Simulator;
@@ -189,6 +185,27 @@
     *retval_ = value;
   }
 
+  // Returns true if the arguments are those of an instance function call.
+  bool ToInstanceFunction() const {
+    return (FunctionBits::decode(argc_tag_) & kInstanceFunctionBit);
+  }
+
+  // Returns true if the arguments are those of a closure function call.
+  bool ToClosureFunction() const {
+    return (FunctionBits::decode(argc_tag_) & kClosureFunctionBit);
+  }
+
+  int NumHiddenArgs(int function_bits) const {
+    // For static closure functions, the closure at index 0 is hidden.
+    // In the instance closure function case, the receiver is accessed from
+    // the context and the closure at index 0 is hidden, so the apparent
+    // argument count remains unchanged.
+    if (function_bits == kClosureFunctionBit) {
+      return 1;
+    }
+    return 0;
+  }
+
   Isolate* isolate_;  // Current isolate pointer.
   int argc_tag_;  // Encodes argument count and invoked native call type.
   RawObject*(*argv_)[];  // Pointer to an array of arguments to runtime call.
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 421ff4a..e25cbe9 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -154,7 +154,7 @@
   V(CoreLibrary, Object, _noSuchMethod)                                        \
   V(CoreLibrary, Object, _as)                                                  \
   V(CoreLibrary, Object, _instanceOf)                                          \
-  V(CoreLibrary, _ObjectArray, _ObjectArray.)                                  \
+  V(CoreLibrary, _List, _List.)                                                \
   V(CoreLibrary, AssertionError, _throwNew)                                    \
   V(CoreLibrary, TypeError, _throwNew)                                         \
   V(CoreLibrary, FallThroughError, _throwNew)                                  \
@@ -696,7 +696,7 @@
   // Set up names for object array and one byte string class which are
   // pre-allocated in the vm isolate also.
   cls = Dart::vm_isolate()->object_store()->array_class();
-  cls.set_name(Symbols::ObjectArray());
+  cls.set_name(Symbols::_List());
   cls = Dart::vm_isolate()->object_store()->one_byte_string_class();
   cls.set_name(Symbols::OneByteString());
 }
@@ -876,7 +876,7 @@
   // remaining classes and register them by name in the dictionaries.
   String& name = String::Handle();
   cls = object_store->array_class();  // Was allocated above.
-  RegisterPrivateClass(cls, Symbols::ObjectArray(), core_lib);
+  RegisterPrivateClass(cls, Symbols::_List(), core_lib);
   pending_classes.Add(cls);
   // We cannot use NewNonParameterizedType(cls), because Array is parameterized.
   type ^= Type::New(Object::Handle(cls.raw()),
@@ -887,7 +887,7 @@
   object_store->set_array_type(type);
 
   cls = object_store->growable_object_array_class();  // Was allocated above.
-  RegisterPrivateClass(cls, Symbols::GrowableObjectArray(), core_lib);
+  RegisterPrivateClass(cls, Symbols::_GrowableList(), core_lib);
   pending_classes.Add(cls);
 
   cls = Class::New<Array>(kImmutableArrayCid);
@@ -895,7 +895,7 @@
   cls.set_type_arguments_field_offset(Array::type_arguments_offset());
   ASSERT(object_store->immutable_array_class() != object_store->array_class());
   cls.set_is_prefinalized();
-  RegisterPrivateClass(cls, Symbols::ImmutableArray(), core_lib);
+  RegisterPrivateClass(cls, Symbols::_ImmutableList(), core_lib);
   pending_classes.Add(cls);
 
   cls = object_store->one_byte_string_class();  // Was allocated above.
@@ -1175,9 +1175,12 @@
   ClassFinalizer::VerifyBootstrapClasses();
   MarkInvisibleFunctions();
 
-  // Set up the intrinsic state of all functions (core, math and scalar list).
+  // Set up the intrinsic state of all functions (core, math and typed data).
   Intrinsifier::InitializeState();
 
+  // Set up recognized state of all functions (core, math and typed data).
+  MethodRecognizer::InitializeState();
+
   return Error::null();
 }
 
@@ -4165,6 +4168,11 @@
 }
 
 
+void Function::set_is_recognized(bool value) const {
+  set_kind_tag(RecognizedBit::update(value, raw_ptr()->kind_tag_));
+}
+
+
 void Function::set_is_static(bool value) const {
   set_kind_tag(StaticBit::update(value, raw_ptr()->kind_tag_));
 }
@@ -4738,6 +4746,7 @@
   result.set_is_external(is_external);
   result.set_is_visible(true);  // Will be computed later.
   result.set_is_intrinsic(false);
+  result.set_is_recognized(false);
   result.set_owner(owner);
   result.set_token_pos(token_pos);
   result.set_end_token_pos(token_pos);
@@ -6173,7 +6182,7 @@
   }
 
   static const int kInitialTokenCount = 32;
-  static const intptr_t kTableSize = 128;
+  static const intptr_t kTableSize = 1024;
 
   uint8_t* buffer_;
   WriteStream stream_;
@@ -8027,10 +8036,10 @@
 
 
 
-// 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) {
+// Return Function::null() if function does not exist in libs.
+RawFunction* Library::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();
@@ -9833,7 +9842,6 @@
       Array::Handle(arguments_descriptor()),
       deopt_id(),
       kNumArgsTested));
-  result.set_deopt_reason(deopt_reason());
   const intptr_t len = NumberOfChecks();
   for (intptr_t i = 0; i < len; i++) {
     const intptr_t class_id = GetClassIdAt(i, arg_nr);
@@ -9859,7 +9867,7 @@
     }
   }
   // Copy deoptimization reason.
-  result.set_deopt_reason(this->deopt_reason());
+  result.set_deopt_reason(deopt_reason());
 
   return result.raw();
 }
@@ -13315,8 +13323,18 @@
   if (str.IsOneByteString()) {
     return OneByteString::EscapeSpecialCharacters(str);
   }
-  ASSERT(str.IsTwoByteString());
-  return TwoByteString::EscapeSpecialCharacters(str);
+  if (str.IsTwoByteString()) {
+    return TwoByteString::EscapeSpecialCharacters(str);
+  }
+  if (str.IsExternalOneByteString()) {
+    return ExternalOneByteString::EscapeSpecialCharacters(str);
+  }
+  ASSERT(str.IsExternalTwoByteString());
+  // If EscapeSpecialCharacters is frequently called on external two byte
+  // strings, we should implement it directly on ExternalTwoByteString rather
+  // than first converting to a TwoByteString.
+  return TwoByteString::EscapeSpecialCharacters(
+      String::Handle(TwoByteString::New(str, Heap::kNew)));
 }
 
 
@@ -13358,14 +13376,24 @@
 
 RawString* String::ConcatAll(const Array& strings,
                              Heap::Space space) {
+  return ConcatAllRange(strings, 0, strings.Length(), space);
+}
+
+
+RawString* String::ConcatAllRange(const Array& strings,
+                                  intptr_t start,
+                                  intptr_t end,
+                                  Heap::Space space) {
   ASSERT(!strings.IsNull());
+  ASSERT(start >= 0);
+  ASSERT(end <= strings.Length());
   intptr_t result_len = 0;
-  intptr_t strings_len = strings.Length();
   String& str = String::Handle();
   intptr_t char_size = kOneByteChar;
-  for (intptr_t i = 0; i < strings_len; i++) {
+  // Compute 'char_size' and 'result_len'.
+  for (intptr_t i = start; i < end; i++) {
     str ^= strings.At(i);
-    intptr_t str_len = str.Length();
+    const intptr_t str_len = str.Length();
     if ((kMaxElements - result_len) < str_len) {
       Isolate* isolate = Isolate::Current();
       const Instance& exception =
@@ -13377,10 +13405,10 @@
     char_size = Utils::Maximum(char_size, str.CharSize());
   }
   if (char_size == kOneByteChar) {
-    return OneByteString::ConcatAll(strings, result_len, space);
+    return OneByteString::ConcatAll(strings, start, end, result_len, space);
   }
   ASSERT(char_size == kTwoByteChar);
-  return TwoByteString::ConcatAll(strings, result_len, space);
+  return TwoByteString::ConcatAll(strings, start, end, result_len, space);
 }
 
 
@@ -13721,7 +13749,6 @@
   intptr_t len = str.Length();
   if (len > 0) {
     intptr_t num_escapes = 0;
-    intptr_t index = 0;
     for (intptr_t i = 0; i < len; i++) {
       if (IsSpecialCharacter(*CharAddr(str, i))) {
         num_escapes += 1;
@@ -13729,6 +13756,7 @@
     }
     const String& dststr = String::Handle(
         OneByteString::New(len + num_escapes, Heap::kNew));
+    intptr_t index = 0;
     for (intptr_t i = 0; i < len; i++) {
       if (IsSpecialCharacter(*CharAddr(str, i))) {
         *(CharAddr(dststr, index)) = '\\';
@@ -13741,7 +13769,36 @@
     }
     return OneByteString::raw(dststr);
   }
-  return OneByteString::null();
+  return OneByteString::raw(Symbols::Empty());
+}
+
+RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters(
+    const String& str) {
+  intptr_t len = str.Length();
+  if (len > 0) {
+    intptr_t num_escapes = 0;
+    for (intptr_t i = 0; i < len; i++) {
+      if (IsSpecialCharacter(*CharAddr(str, i))) {
+        num_escapes += 1;
+      }
+    }
+    const String& dststr = String::Handle(
+        OneByteString::New(len + num_escapes, Heap::kNew));
+    intptr_t index = 0;
+    for (intptr_t i = 0; i < len; i++) {
+      if (IsSpecialCharacter(*CharAddr(str, i))) {
+        *(OneByteString::CharAddr(dststr, index)) = '\\';
+        *(OneByteString::CharAddr(dststr, index + 1)) =
+        SpecialCharacter(*CharAddr(str, i));
+        index += 2;
+      } else {
+        *(OneByteString::CharAddr(dststr, index)) = *CharAddr(str, i);
+        index += 1;
+      }
+    }
+    return OneByteString::raw(dststr);
+  }
+  return OneByteString::raw(Symbols::Empty());
 }
 
 
@@ -13842,15 +13899,19 @@
 
 
 RawOneByteString* OneByteString::ConcatAll(const Array& strings,
+                                           intptr_t start,
+                                           intptr_t end,
                                            intptr_t len,
                                            Heap::Space space) {
+  ASSERT(!strings.IsNull());
+  ASSERT(start >= 0);
+  ASSERT(end <= strings.Length());
   const String& result = String::Handle(OneByteString::New(len, space));
   String& str = String::Handle();
-  intptr_t strings_len = strings.Length();
   intptr_t pos = 0;
-  for (intptr_t i = 0; i < strings_len; i++) {
+  for (intptr_t i = start; i < end; i++) {
     str ^= strings.At(i);
-    intptr_t str_len = str.Length();
+    const intptr_t str_len = str.Length();
     String::Copy(result, pos, str, 0, str_len);
     ASSERT((kMaxElements - pos) >= str_len);
     pos += str_len;
@@ -13918,7 +13979,6 @@
   intptr_t len = str.Length();
   if (len > 0) {
     intptr_t num_escapes = 0;
-    intptr_t index = 0;
     for (intptr_t i = 0; i < len; i++) {
       if (IsSpecialCharacter(*CharAddr(str, i))) {
         num_escapes += 1;
@@ -13926,6 +13986,7 @@
     }
     const String& dststr = String::Handle(
         TwoByteString::New(len + num_escapes, Heap::kNew));
+    intptr_t index = 0;
     for (intptr_t i = 0; i < len; i++) {
       if (IsSpecialCharacter(*CharAddr(str, i))) {
         *(CharAddr(dststr, index)) = '\\';
@@ -13938,7 +13999,7 @@
     }
     return TwoByteString::raw(dststr);
   }
-  return TwoByteString::null();
+  return TwoByteString::New(0, Heap::kNew);
 }
 
 
@@ -14024,15 +14085,19 @@
 
 
 RawTwoByteString* TwoByteString::ConcatAll(const Array& strings,
+                                           intptr_t start,
+                                           intptr_t end,
                                            intptr_t len,
                                            Heap::Space space) {
+  ASSERT(!strings.IsNull());
+  ASSERT(start >= 0);
+  ASSERT(end <= strings.Length());
   const String& result = String::Handle(TwoByteString::New(len, space));
   String& str = String::Handle();
-  intptr_t strings_len = strings.Length();
   intptr_t pos = 0;
-  for (intptr_t i = 0; i < strings_len; i++) {
+  for (intptr_t i = start; i < end; i++) {
     str ^= strings.At(i);
-    intptr_t str_len = str.Length();
+    const intptr_t str_len = str.Length();
     String::Copy(result, pos, str, 0, str_len);
     ASSERT((kMaxElements - pos) >= str_len);
     pos += str_len;
@@ -14255,10 +14320,10 @@
 
 const char* Array::ToCString() const {
   if (IsNull()) {
-    return IsImmutable() ? "ImmutableArray NULL" : "Array NULL";
+    return IsImmutable() ? "_ImmutableList NULL" : "_List NULL";
   }
-  const char* format = !IsImmutable() ? "Array len:%" Pd "" :
-      "Immutable Array len:%" Pd "";
+  const char* format = IsImmutable() ?
+      "_ImmutableList len:%" Pd : "_List 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());
@@ -14466,9 +14531,9 @@
 
 const char* GrowableObjectArray::ToCString() const {
   if (IsNull()) {
-    return "GrowableObjectArray NULL";
+    return "_GrowableList NULL";
   }
-  const char* format = "GrowableObjectArray len:%" Pd "";
+  const char* format = "_GrowableList 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());
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 2caf67d..30ce9f7 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -858,6 +858,9 @@
   void SetFunctions(const Array& value) const;
   void AddFunction(const Function& function) const;
 
+  RawGrowableObjectArray* closures() const {
+    return raw_ptr()->closure_functions_;
+  }
   void AddClosureFunction(const Function& function) const;
   RawFunction* LookupClosureFunction(intptr_t token_pos) const;
 
@@ -1691,6 +1694,11 @@
   }
   void set_is_intrinsic(bool value) const;
 
+  bool is_recognized() const {
+    return RecognizedBit::decode(raw_ptr()->kind_tag_);
+  }
+  void set_is_recognized(bool value) const;
+
   bool HasOptimizedCode() const;
 
   // Returns true if the argument counts are valid for calling this function.
@@ -1849,7 +1857,8 @@
     kExternalBit = 7,
     kVisibleBit = 8,
     kIntrinsicBit = 9,
-    kKindTagBit = 10,
+    kRecognizedBit = 10,
+    kKindTagBit = 11,
     kKindTagSize = 4,
   };
   class StaticBit : public BitField<bool, kStaticBit, 1> {};
@@ -1862,6 +1871,7 @@
   class ExternalBit : public BitField<bool, kExternalBit, 1> {};
   class VisibleBit : public BitField<bool, kVisibleBit, 1> {};
   class IntrinsicBit : public BitField<bool, kIntrinsicBit, 1> {};
+  class RecognizedBit : public BitField<bool, kRecognizedBit, 1> {};
   class KindBits :
     public BitField<RawFunction::Kind, kKindTagBit, kKindTagSize> {};  // NOLINT
 
@@ -2510,6 +2520,11 @@
 
   static bool IsPrivate(const String& name);
 
+  // Return Function::null() if function does not exist in libs.
+  static RawFunction* GetFunction(const GrowableArray<Library*>& libs,
+                                  const char* class_name,
+                                  const char* function_name);
+
  private:
   static const int kInitialImportsCapacity = 4;
   static const int kImportsCapacityIncrement = 8;
@@ -4778,6 +4793,11 @@
                            Heap::Space space = Heap::kNew);
   static RawString* ConcatAll(const Array& strings,
                               Heap::Space space = Heap::kNew);
+  // Concat all strings in 'strings' from 'start' to 'end' (excluding).
+  static RawString* ConcatAllRange(const Array& strings,
+                                   intptr_t start,
+                                   intptr_t end,
+                                   Heap::Space space = Heap::kNew);
 
   static RawString* SubString(const String& str,
                               intptr_t begin_index,
@@ -4898,6 +4918,8 @@
                                   const String& str2,
                                   Heap::Space space);
   static RawOneByteString* ConcatAll(const Array& strings,
+                                     intptr_t start,
+                                     intptr_t end,
                                      intptr_t len,
                                      Heap::Space space);
 
@@ -4947,6 +4969,7 @@
 
   friend class Class;
   friend class String;
+  friend class ExternalOneByteString;
   friend class SnapshotReader;
 };
 
@@ -4993,6 +5016,8 @@
                                   const String& str2,
                                   Heap::Space space);
   static RawTwoByteString* ConcatAll(const Array& strings,
+                                     intptr_t start,
+                                     intptr_t end,
                                      intptr_t len,
                                      Heap::Space space);
 
@@ -5068,6 +5093,8 @@
     return reinterpret_cast<RawExternalOneByteString*>(Object::null());
   }
 
+  static RawOneByteString* EscapeSpecialCharacters(const String& str);
+
   static const ClassId kClassId = kExternalOneByteStringCid;
 
  private:
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 78a3d0c..cba6d44 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -1529,6 +1529,100 @@
 }
 
 
+TEST_CASE(EscapeSpecialCharactersOneByteString) {
+  uint8_t characters[] =
+      { 'a', '\n', '\f', '\b', '\t', '\v', '\r', '\\', '$', 'z' };
+  intptr_t len = ARRAY_SIZE(characters);
+
+  const String& str =
+      String::Handle(
+          OneByteString::New(characters, len, Heap::kNew));
+  EXPECT(str.IsOneByteString());
+  EXPECT_EQ(str.Length(), len);
+  EXPECT(str.Equals("a\n\f\b\t\v\r\\$z"));
+  const String& escaped_str =
+      String::Handle(String::EscapeSpecialCharacters(str));
+  EXPECT(escaped_str.Equals("a\\n\\f\\b\\t\\v\\r\\\\\\$z"));
+
+  const String& escaped_empty_str =
+      String::Handle(String::EscapeSpecialCharacters(Symbols::Empty()));
+  EXPECT_EQ(escaped_empty_str.Length(), 0);
+}
+
+
+TEST_CASE(EscapeSpecialCharactersExternalOneByteString) {
+  uint8_t characters[] =
+      { 'a', '\n', '\f', '\b', '\t', '\v', '\r', '\\', '$', 'z' };
+  intptr_t len = ARRAY_SIZE(characters);
+
+  const String& str =
+      String::Handle(
+          ExternalOneByteString::New(characters, len, NULL, NULL, Heap::kNew));
+  EXPECT(!str.IsOneByteString());
+  EXPECT(str.IsExternalOneByteString());
+  EXPECT_EQ(str.Length(), len);
+  EXPECT(str.Equals("a\n\f\b\t\v\r\\$z"));
+  const String& escaped_str =
+      String::Handle(String::EscapeSpecialCharacters(str));
+  EXPECT(escaped_str.Equals("a\\n\\f\\b\\t\\v\\r\\\\\\$z"));
+
+  const String& empty_str =
+      String::Handle(
+          ExternalOneByteString::New(characters, 0, NULL, NULL, Heap::kNew));
+  const String& escaped_empty_str =
+      String::Handle(String::EscapeSpecialCharacters(empty_str));
+  EXPECT_EQ(empty_str.Length(), 0);
+  EXPECT_EQ(escaped_empty_str.Length(), 0);
+}
+
+TEST_CASE(EscapeSpecialCharactersTwoByteString) {
+  uint16_t characters[] =
+      { 'a', '\n', '\f', '\b', '\t', '\v', '\r', '\\', '$', 'z' };
+  intptr_t len = ARRAY_SIZE(characters);
+
+  const String& str =
+      String::Handle(TwoByteString::New(characters, len, Heap::kNew));
+  EXPECT(str.IsTwoByteString());
+  EXPECT_EQ(str.Length(), len);
+  EXPECT(str.Equals("a\n\f\b\t\v\r\\$z"));
+  const String& escaped_str =
+      String::Handle(String::EscapeSpecialCharacters(str));
+  EXPECT(escaped_str.Equals("a\\n\\f\\b\\t\\v\\r\\\\\\$z"));
+
+  const String& empty_str =
+      String::Handle(TwoByteString::New(static_cast<intptr_t>(0), Heap::kNew));
+  const String& escaped_empty_str =
+      String::Handle(String::EscapeSpecialCharacters(empty_str));
+  EXPECT_EQ(empty_str.Length(), 0);
+  EXPECT_EQ(escaped_empty_str.Length(), 0);
+}
+
+
+TEST_CASE(EscapeSpecialCharactersExternalTwoByteString) {
+  uint16_t characters[] =
+      { 'a', '\n', '\f', '\b', '\t', '\v', '\r', '\\', '$', 'z' };
+  intptr_t len = ARRAY_SIZE(characters);
+
+  const String& str =
+      String::Handle(
+          ExternalTwoByteString::New(characters, len, NULL, NULL, Heap::kNew));
+  EXPECT(str.IsExternalTwoByteString());
+  EXPECT_EQ(str.Length(), len);
+  EXPECT(str.Equals("a\n\f\b\t\v\r\\$z"));
+  const String& escaped_str =
+      String::Handle(String::EscapeSpecialCharacters(str));
+  EXPECT(escaped_str.Equals("a\\n\\f\\b\\t\\v\\r\\\\\\$z"));
+
+  const String& empty_str =
+      String::Handle(
+          ExternalTwoByteString::New(characters, 0, NULL, NULL, Heap::kNew));
+  const String& escaped_empty_str =
+      String::Handle(String::EscapeSpecialCharacters(empty_str));
+  EXPECT_EQ(empty_str.Length(), 0);
+  EXPECT_EQ(escaped_empty_str.Length(), 0);
+}
+
+
 TEST_CASE(ExternalTwoByteString) {
   uint16_t characters[] = { 0x1E6B, 0x1E85, 0x1E53 };
   intptr_t len = ARRAY_SIZE(characters);
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 11ce280..22ec97e 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -308,7 +308,7 @@
 }
 
 
-void Parser::SetScript(const Script & script, intptr_t token_pos) {
+void Parser::SetScript(const Script& script, intptr_t token_pos) {
   script_ = script.raw();
   tokens_iterator_.SetStream(TokenStream::Handle(script.tokens()), token_pos);
   token_kind_ = Token::kILLEGAL;
@@ -1019,7 +1019,7 @@
   if (field.is_const()) {
     // This getter will only be called once at compile time.
     if (expr->EvalConstExpr() == NULL) {
-      ErrorMsg(expr_pos, "initializer must be a compile-time constant");
+      ErrorMsg(expr_pos, "initializer is not a valid compile-time constant");
     }
     ReturnNode* return_node = new ReturnNode(ident_pos, expr);
     current_block_->statements->Add(return_node);
@@ -1923,55 +1923,7 @@
       op_arguments = BuildNoSuchMethodArguments(
           operator_pos, operator_function_name, *op_arguments);
     }
-    if (super_operator.name() == Symbols::EqualOperator().raw()) {
-      // Expand super.== call to match correct == semantics into:
-      // Let t1 = left, t2 = right {
-      //   (t1 === null  || t2 === null) ? t1 === t2
-      //                                 : static_call(super.==, t1, t2)
-      // }
-      // Normal == calls are not expanded at the AST level to produce
-      // more compact code and enable more optimization opportunities.
-      ASSERT(!is_no_such_method);  // == is always found.
-      EnsureExpressionTemp();  // Needed for ConditionalExprNode.
-      LetNode* result = new LetNode(operator_pos);
-      AstNode* left =
-          new LoadLocalNode(operator_pos,
-                            result->AddInitializer(op_arguments->NodeAt(0)));
-      AstNode* right =
-          new LoadLocalNode(operator_pos,
-                            result->AddInitializer(op_arguments->NodeAt(1)));
-      LiteralNode* null_operand =
-          new LiteralNode(operator_pos, Instance::ZoneHandle());
-      ComparisonNode* is_left_null = new ComparisonNode(operator_pos,
-                                                        Token::kEQ_STRICT,
-                                                        left,
-                                                        null_operand);
-      ComparisonNode* is_right_null = new ComparisonNode(operator_pos,
-                                                         Token::kEQ_STRICT,
-                                                         right,
-                                                         null_operand);
-      BinaryOpNode* null_check = new BinaryOpNode(operator_pos,
-                                                  Token::kOR,
-                                                  is_left_null,
-                                                  is_right_null);
-      ArgumentListNode* new_arguments = new ArgumentListNode(operator_pos);
-      new_arguments->Add(left);
-      new_arguments->Add(right);
-      StaticCallNode* call = new StaticCallNode(operator_pos,
-                                                super_operator,
-                                                new_arguments);
-      ComparisonNode* strict_eq = new ComparisonNode(operator_pos,
-                                                     Token::kEQ_STRICT,
-                                                     left,
-                                                     right);
-      result->AddNode(new ConditionalExprNode(operator_pos,
-                                              null_check,
-                                              strict_eq,
-                                              call));
-      super_op = result;
-    } else {
-      super_op = new StaticCallNode(operator_pos, super_operator, op_arguments);
-    }
+    super_op = new StaticCallNode(operator_pos, super_operator, op_arguments);
     if (negate_result) {
       super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op);
     }
@@ -2879,17 +2831,35 @@
   intptr_t end_token_pos = 0;
   if (CurrentToken() == Token::kLBRACE) {
     ConsumeToken();
+    if (String::Handle(func.name()).Equals(Symbols::EqualOperator())) {
+      const Class& owner = Class::Handle(func.Owner());
+      if (!owner.IsObjectClass()) {
+        AddEqualityNullCheck();
+      }
+    }
     ParseStatementSequence();
     end_token_pos = TokenPos();
     ExpectToken(Token::kRBRACE);
   } else if (CurrentToken() == Token::kARROW) {
     ConsumeToken();
+    if (String::Handle(func.name()).Equals(Symbols::EqualOperator())) {
+      const Class& owner = Class::Handle(func.Owner());
+      if (!owner.IsObjectClass()) {
+        AddEqualityNullCheck();
+      }
+    }
     const intptr_t expr_pos = TokenPos();
     AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
     ASSERT(expr != NULL);
     current_block_->statements->Add(new ReturnNode(expr_pos, expr));
     end_token_pos = TokenPos();
   } else if (IsLiteral("native")) {
+    if (String::Handle(func.name()).Equals(Symbols::EqualOperator())) {
+      const Class& owner = Class::Handle(func.Owner());
+      if (!owner.IsObjectClass()) {
+        AddEqualityNullCheck();
+      }
+    }
     ParseNativeFunctionBlock(&params, func);
     end_token_pos = TokenPos();
     ExpectSemicolon();
@@ -2924,6 +2894,31 @@
 }
 
 
+void Parser::AddEqualityNullCheck() {
+  const intptr_t token_pos = Scanner::kDummyTokenIndex;
+  AstNode* argument =
+      new LoadLocalNode(token_pos,
+                        current_block_->scope->parent()->VariableAt(1));
+  LiteralNode* null_operand =
+      new LiteralNode(token_pos, Instance::ZoneHandle());
+  ComparisonNode* check_arg = new ComparisonNode(token_pos,
+                                                 Token::kEQ_STRICT,
+                                                 argument,
+                                                 null_operand);
+  ComparisonNode* result = new ComparisonNode(token_pos,
+                                              Token::kEQ_STRICT,
+                                              LoadReceiver(token_pos),
+                                              null_operand);
+  SequenceNode* arg_is_null = new SequenceNode(token_pos, NULL);
+  arg_is_null->Add(new ReturnNode(token_pos, result));
+  IfNode* if_arg_null = new IfNode(token_pos,
+                                   check_arg,
+                                   arg_is_null,
+                                   NULL);
+  current_block_->statements->Add(if_arg_null);
+}
+
+
 void Parser::SkipIf(Token::Kind token) {
   if (CurrentToken() == token) {
     ConsumeToken();
@@ -3123,7 +3118,7 @@
       // Replace the type with a malformed type and compile a throw when called.
       redirection_type = ClassFinalizer::NewFinalizedMalformedType(
           Error::Handle(),  // No previous error.
-          current_class(),
+          script_,
           type_pos,
           "factory '%s' may not redirect to type parameter '%s'",
           method->name->ToCString(),
@@ -6047,8 +6042,20 @@
 }
 
 
+// Return true if the type class of the given value implements the
+// == operator.
+static bool ImplementsEqualOperator(const Instance& value) {
+  Class& cls = Class::Handle(value.clazz());
+  const Function& equal_op = Function::Handle(
+      Resolver::ResolveDynamicAnyArgs(cls, Symbols::EqualOperator()));
+  ASSERT(!equal_op.IsNull());
+  cls = equal_op.Owner();
+  return !cls.IsObjectClass();
+}
+
+
 // Check that all case expressions are of the same type, either int, String,
-// double or any other class that does not override the == operator.
+// or any other class that does not override the == operator.
 // The expressions are compile-time constants and are thus in the form
 // of a LiteralNode.
 void Parser::CheckCaseExpressions(const GrowableArray<LiteralNode*>& values) {
@@ -6072,23 +6079,21 @@
       }
       continue;
     }
-    if (first_value.IsDouble()) {
-      if (!val.IsDouble()) {
-        ErrorMsg(val_pos, "expected case expression of type double");
-      }
-      continue;
+    if (val.IsDouble()) {
+      ErrorMsg(val_pos, "case expression may not be of type double");
     }
     if (val.clazz() != first_value.clazz()) {
       ErrorMsg(val_pos, "all case expressions must be of same type");
     }
-    Class& cls = Class::Handle(val.clazz());
-    const Function& equal_op = Function::Handle(
-        Resolver::ResolveDynamicAnyArgs(cls, Symbols::EqualOperator()));
-    ASSERT(!equal_op.IsNull());
-    cls = equal_op.Owner();
-    if (!cls.IsObjectClass()) {
-      ErrorMsg(val_pos,
-               "type class of case expression must not implement operator ==");
+    if (i == 0) {
+      // The value is of some type other than int, String or double.
+      // Check that the type class does not override the == operator.
+      // Check this only in the first loop iteration since all values
+      // are of the same type, which we check above.
+      if (ImplementsEqualOperator(val)) {
+        ErrorMsg(val_pos,
+            "type class of case expression must not implement operator ==");
+      }
     }
   }
 }
@@ -7652,7 +7657,7 @@
     return expr;
   }
   if (expr->EvalConstExpr() == NULL) {
-    ErrorMsg(expr_pos, "expression must be a compile-time constant");
+    ErrorMsg(expr_pos, "expression is not a valid compile-time constant");
   }
   return new LiteralNode(expr_pos, EvaluateConstExpr(expr));
 }
@@ -7822,7 +7827,7 @@
   ConsumeToken();
   const intptr_t right_expr_pos = TokenPos();
   if (require_compiletime_const && (assignment_op != Token::kASSIGN)) {
-    ErrorMsg(right_expr_pos, "expression must be a compile-time constant");
+    ErrorMsg(right_expr_pos, "expression is not a valid compile-time constant");
   }
   AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades);
   if (assignment_op != Token::kASSIGN) {
@@ -8530,7 +8535,7 @@
                 FLAG_error_on_bad_type) {
               *type = ClassFinalizer::NewFinalizedMalformedType(
                   Error::Handle(),  // No previous error.
-                  scope_class,
+                  script_,
                   type->token_pos(),
                   "type parameter '%s' cannot be referenced "
                   "from static member",
@@ -8548,7 +8553,7 @@
                 FLAG_error_on_bad_type) {
               *type = ClassFinalizer::NewFinalizedMalformedType(
                   Error::Handle(),  // No previous error.
-                  scope_class,
+                  script_,
                   type_parameter.token_pos(),
                   "type parameter '%s' cannot be parameterized",
                   String::Handle(type_parameter.name()).ToCString());
@@ -8586,7 +8591,7 @@
           FLAG_error_on_bad_type) {
         ClassFinalizer::FinalizeMalformedType(
             Error::Handle(),  // No previous error.
-            scope_class,
+            script_,
             parameterized_type,
             "type '%s' is not loaded",
             String::Handle(parameterized_type.UserVisibleName()).ToCString());
@@ -9181,7 +9186,7 @@
       if (finalization == ClassFinalizer::kCanonicalizeWellFormed) {
         return ClassFinalizer::NewFinalizedMalformedType(
             Error::Handle(),  // No previous error.
-            current_class(),
+            script_,
             type_name.ident_pos,
             "using '%s' in this context is invalid",
             type_name.ident->ToCString());
@@ -9502,6 +9507,18 @@
                                key_type,
                                Symbols::ListLiteralElement());
     }
+    if (is_const) {
+      ASSERT(key->IsLiteralNode());
+      const Instance& key_value = key->AsLiteralNode()->literal();
+      if (key_value.IsDouble()) {
+        ErrorMsg(key_pos, "key value must not be of type double");
+      }
+      if (!key_value.IsInteger() &&
+          !key_value.IsString() &&
+          ImplementsEqualOperator(key_value)) {
+        ErrorMsg(key_pos, "key value must not implement operator ==");
+      }
+    }
     ExpectToken(Token::kCOLON);
     const intptr_t value_pos = TokenPos();
     AstNode* value = ParseExpr(is_const, kConsumeCascades);
@@ -9744,7 +9761,7 @@
       // Replace the type with a malformed type.
       type = ClassFinalizer::NewFinalizedMalformedType(
           Error::Handle(),  // No previous error.
-          current_class(),
+          script_,
           type_pos,
           "%s'%s' cannot be instantiated",
           type.IsTypeParameter() ? "type parameter " : "",
@@ -9756,7 +9773,7 @@
         // Replace the type with a malformed type.
         type = ClassFinalizer::NewFinalizedMalformedType(
             bound_error,
-            current_class(),
+            script_,
             type_pos,
             "malbounded type '%s' cannot be instantiated",
             String::Handle(type.UserVisibleName()).ToCString());
@@ -9821,7 +9838,7 @@
       if (is_const) {
         type = ClassFinalizer::NewFinalizedMalformedType(
             Error::Handle(),  // No previous error.
-            current_class(),
+            script_,
             call_pos,
             "class '%s' has no constructor or factory named '%s'",
             String::Handle(type_class.Name()).ToCString(),
@@ -9947,7 +9964,7 @@
                                          &malformed_error)) {
           type_bound = ClassFinalizer::NewFinalizedMalformedType(
               malformed_error,
-              current_class(),
+              script_,
               new_pos,
               "const factory result is not an instance of '%s'",
               String::Handle(type_bound.UserVisibleName()).ToCString());
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 4abfda0..16b9322 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -662,6 +662,8 @@
       const Function& constructor,
       ArgumentListNode* arguments);
 
+  void AddEqualityNullCheck();
+
   RawInstance* TryCanonicalize(const Instance& instance, intptr_t token_pos);
 
   Isolate* isolate() const { return isolate_; }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 32f5d83..3ccbe98 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -628,7 +628,7 @@
   int16_t num_fixed_parameters_;
   int16_t num_optional_parameters_;  // > 0: positional; < 0: named.
   int16_t deoptimization_counter_;
-  uint16_t kind_tag_;
+  uint16_t kind_tag_;  // See Function::KindTagBits.
   uint16_t optimized_instruction_count_;
   uint16_t optimized_call_site_count_;
 };
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index 3e185ee..a8351cd 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -67,7 +67,6 @@
   V(TwoArgsUnoptimizedStaticCall)                                              \
   V(OptimizeFunction)                                                          \
   V(BreakpointDynamic)                                                         \
-  V(EqualityWithNullArg)                                                       \
 
 // class StubEntry is used to describe stub methods generated in dart to
 // abstract out common code executed from generated dart code.
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 596af42..0c35d5b 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1758,7 +1758,15 @@
 
 
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
-  __ Unimplemented("BreakpointRuntime stub");
+  __ Comment("BreakpointRuntime stub");
+  __ EnterStubFrame();
+  __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
+  // Preserve arguments descriptor and make room for result.
+  __ PushList((1 << R0) | (1 << R4) | (1 << R5));
+  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
+  __ PopList((1 << R0) | (1 << R4) | (1 << R5));
+  __ LeaveStubFrame();
+  __ bx(R0);
 }
 
 
@@ -1958,92 +1966,6 @@
 }
 
 
-// Implements equality operator when one of the arguments is null
-// (identity check) and updates ICData if necessary.
-// LR: return address.
-// R1: left argument.
-// R0: right argument.
-// R5: ICData.
-// R0: result.
-// TODO(srdjan): Move to VM stubs once Boolean objects become VM objects.
-void StubCode::GenerateEqualityWithNullArgStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  static const intptr_t kNumArgsTested = 2;
-#if defined(DEBUG)
-  { Label ok;
-    __ ldr(IP, FieldAddress(R5, ICData::num_args_tested_offset()));
-    __ cmp(IP, ShifterOperand(kNumArgsTested));
-    __ b(&ok, EQ);
-    __ Stop("Incorrect ICData for equality");
-    __ Bind(&ok);
-  }
-#endif  // DEBUG
-  // Check IC data, update if needed.
-  // R5: IC data object (preserved).
-  __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
-  // R6: ic_data_array with check entries: classes and target functions.
-  __ AddImmediate(R6, Array::data_offset() - kHeapObjectTag);
-  // R6: points directly to the first ic data array element.
-
-  Label get_class_id_as_smi, no_match, loop, found;
-  __ Bind(&loop);
-  // Check left.
-  __ mov(R2, ShifterOperand(R1));
-  __ bl(&get_class_id_as_smi);
-  __ ldr(R3, Address(R6, 0 * kWordSize));
-  __ cmp(R2, ShifterOperand(R3));  // Class id match?
-  __ b(&no_match, NE);
-  // Check right.
-  __ mov(R2, ShifterOperand(R0));
-  __ bl(&get_class_id_as_smi);
-  __ ldr(R3, Address(R6, 1 * kWordSize));
-  __ cmp(R2, ShifterOperand(R3));  // Class id match?
-  __ b(&found, EQ);
-  __ Bind(&no_match);
-  // Next check group.
-  __ AddImmediate(R6, kWordSize * ICData::TestEntryLengthFor(kNumArgsTested));
-  __ CompareImmediate(R3, Smi::RawValue(kIllegalCid));  // Done?
-  __ b(&loop, NE);
-  Label update_ic_data;
-  __ b(&update_ic_data);
-
-  __ Bind(&found);
-  const intptr_t count_offset =
-      ICData::CountIndexFor(kNumArgsTested) * kWordSize;
-  __ ldr(IP, Address(R6, count_offset));
-  __ adds(IP, IP, ShifterOperand(Smi::RawValue(1)));
-  __ LoadImmediate(IP, Smi::RawValue(Smi::kMaxValue), VS);  // If overflow.
-  __ str(IP, Address(R6, count_offset));
-
-  Label compute_result;
-  __ Bind(&compute_result);
-  __ cmp(R0, ShifterOperand(R1));
-  __ LoadObject(R0, Bool::False(), NE);
-  __ LoadObject(R0, Bool::True(), EQ);
-  __ LeaveStubFrame();
-  __ Ret();
-
-  __ Bind(&get_class_id_as_smi);
-  // Test if Smi -> load Smi class for comparison.
-  __ tst(R2, ShifterOperand(kSmiTagMask));
-  __ mov(R2, ShifterOperand(Smi::RawValue(kSmiCid)), EQ);
-  __ bx(LR, EQ);
-  __ LoadClassId(R2, R2);
-  __ SmiTag(R2);
-  __ bx(LR);
-
-  __ Bind(&update_ic_data);
-  // R5: ICData
-  __ PushList((1 << R0) | (1 << R1));
-  __ PushObject(Symbols::EqualOperator());  // Target's name.
-  __ Push(R5);  // ICData
-  __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4);  // Clobbers R4, R5.
-  __ Drop(2);
-  __ PopList((1 << R0) | (1 << R1));
-  __ b(&compute_result);
-}
-
-
 // Calls to the runtime to optimize the given function.
 // R6: function to be reoptimized.
 // R4: argument descriptor (preserved).
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index f2ba2ea..4df92d7 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1796,7 +1796,7 @@
 }
 
 
-// EDX, EXC: May contain arguments to runtime stub.
+// EDX, ECX: May contain arguments to runtime stub.
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
   __ EnterStubFrame();
   // Save runtime args.
@@ -2032,105 +2032,6 @@
 }
 
 
-// Implements equality operator when one of the arguments is null
-// (identity check) and updates ICData if necessary.
-// TOS + 0: return address
-// TOS + 1: right argument
-// TOS + 2: left argument
-// ECX: ICData.
-// EAX: result.
-// TODO(srdjan): Move to VM stubs once Boolean objects become VM objects.
-void StubCode::GenerateEqualityWithNullArgStub(Assembler* assembler) {
-  static const intptr_t kNumArgsTested = 2;
-#if defined(DEBUG)
-  { Label ok;
-    __ movl(EAX, FieldAddress(ECX, ICData::num_args_tested_offset()));
-    __ cmpl(EAX, Immediate(kNumArgsTested));
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Incorrect ICData for equality");
-    __ Bind(&ok);
-  }
-#endif  // DEBUG
-  // Check IC data, update if needed.
-  // ECX: IC data object (preserved).
-  __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
-  // EBX: ic_data_array with check entries: classes and target functions.
-  __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
-  // EBX: points directly to the first ic data array element.
-
-  Label get_class_id_as_smi, no_match, loop, compute_result, found;
-  __ Bind(&loop);
-  // Check left.
-  __ movl(EAX, Address(ESP, 2 * kWordSize));
-  __ call(&get_class_id_as_smi);
-  __ movl(EDI, Address(EBX, 0 * kWordSize));
-  __ cmpl(EAX, EDI);  // Class id match?
-  __ j(NOT_EQUAL, &no_match, Assembler::kNearJump);
-  // Check right.
-  __ movl(EAX, Address(ESP, 1 * kWordSize));
-  __ call(&get_class_id_as_smi);
-  __ movl(EDI, Address(EBX, 1 * kWordSize));
-  __ cmpl(EAX, EDI);  // Class id match?
-  __ j(EQUAL, &found, Assembler::kNearJump);
-  __ Bind(&no_match);
-  // Next check group.
-  __ addl(EBX, Immediate(
-      kWordSize * ICData::TestEntryLengthFor(kNumArgsTested)));
-  __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid)));  // Done?
-  __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
-  Label update_ic_data;
-  __ jmp(&update_ic_data);
-
-  __ Bind(&found);
-  const intptr_t count_offset =
-      ICData::CountIndexFor(kNumArgsTested) * kWordSize;
-  __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1)));
-  __ j(NO_OVERFLOW, &compute_result);
-  __ movl(Address(EBX, count_offset),
-          Immediate(Smi::RawValue(Smi::kMaxValue)));
-
-  __ Bind(&compute_result);
-  Label true_label;
-  __ movl(EAX, Address(ESP, 1 * kWordSize));
-  __ cmpl(EAX, Address(ESP, 2 * kWordSize));
-  __ j(EQUAL, &true_label, Assembler::kNearJump);
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-  __ Bind(&true_label);
-  __ LoadObject(EAX, Bool::True());
-  __ ret();
-
-  __ Bind(&get_class_id_as_smi);
-  Label not_smi;
-  // Test if Smi -> load Smi class for comparison.
-  __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
-  __ movl(EAX, Immediate(Smi::RawValue(kSmiCid)));
-  __ ret();
-
-  __ Bind(&not_smi);
-  __ LoadClassId(EAX, EAX);
-  __ SmiTag(EAX);
-  __ ret();
-
-  __ Bind(&update_ic_data);
-
-  // ECX: ICData
-  __ movl(EAX, Address(ESP, 1 * kWordSize));
-  __ movl(EDI, Address(ESP, 2 * kWordSize));
-  __ EnterStubFrame();
-  __ pushl(EDI);  // arg 0
-  __ pushl(EAX);  // arg 1
-  __ PushObject(Symbols::EqualOperator());  // Target's name.
-  __ pushl(ECX);  // ICData
-  __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4);
-  __ Drop(4);
-  __ LeaveFrame();
-
-  __ jmp(&compute_result, Assembler::kNearJump);
-}
-
-
 // Calls to the runtime to optimize the given function.
 // EDI: function to be reoptimized.
 // EDX: argument descriptor (preserved).
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 83990b8..0928f0a 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -2000,7 +2000,22 @@
 
 
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
-  __ Unimplemented("BreakpointRuntime stub");
+  __ Comment("BreakpointRuntime stub");
+  __ EnterStubFrame();
+  __ addiu(SP, SP, Immediate(-3 * kWordSize));
+  __ sw(S5, Address(SP, 2 * kWordSize));
+  __ sw(S4, Address(SP, 1 * kWordSize));
+  __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
+  __ sw(TMP, Address(SP, 0 * kWordSize));
+
+  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
+
+  __ lw(S5, Address(SP, 2 * kWordSize));
+  __ lw(S4, Address(SP, 1 * kWordSize));
+  __ lw(T0, Address(SP, 0 * kWordSize));
+  __ addiu(SP, SP, Immediate(3 * kWordSize));
+  __ LeaveStubFrame();
+  __ jr(T0);
 }
 
 
@@ -2217,110 +2232,6 @@
 }
 
 
-// Implements equality operator when one of the arguments is null
-// (identity check) and updates ICData if necessary.
-// RA: return address.
-// A1: left argument.
-// A0: right argument.
-// T0: ICData.
-// V0: result.
-// TODO(srdjan): Move to VM stubs once Boolean objects become VM objects.
-void StubCode::GenerateEqualityWithNullArgStub(Assembler* assembler) {
-  __ TraceSimMsg("EqualityWithNullArgStub");
-  __ Comment("EqualityWithNullArgStub");
-  __ EnterStubFrame();
-  static const intptr_t kNumArgsTested = 2;
-#if defined(DEBUG)
-  { Label ok;
-    __ lw(CMPRES1, FieldAddress(T0, ICData::num_args_tested_offset()));
-    __ BranchEqual(CMPRES1, kNumArgsTested, &ok);
-    __ Stop("Incorrect ICData for equality");
-    __ Bind(&ok);
-  }
-#endif  // DEBUG
-  // Check IC data, update if needed.
-  // T0: IC data object (preserved).
-  __ lw(T6, FieldAddress(T0, ICData::ic_data_offset()));
-  // T6: ic_data_array with check entries: classes and target functions.
-  __ AddImmediate(T6, Array::data_offset() - kHeapObjectTag);
-  // T6: points directly to the first ic data array element.
-
-  Label get_class_id_as_smi, no_match, loop, found;
-  __ Bind(&loop);
-  // Check left.
-  __ bal(&get_class_id_as_smi);
-  __ delay_slot()->mov(T2, A1);
-  __ lw(T3, Address(T6, 0 * kWordSize));
-  __ bne(T2, T3, &no_match);  // Class id match?
-
-  // Check right.
-  __ bal(&get_class_id_as_smi);
-  __ delay_slot()->mov(T2, A0);
-  __ lw(T3, Address(T6, 1 * kWordSize));
-  __ beq(T2, T3, &found);  // Class id match?
-  __ Bind(&no_match);
-  // Next check group.
-  intptr_t entry_bytes = kWordSize * ICData::TestEntryLengthFor(kNumArgsTested);
-  if (Utils::IsInt(kImmBits, entry_bytes)) {
-    __ BranchNotEqual(T3, Smi::RawValue(kIllegalCid), &loop);  // Done?
-    __ delay_slot()->addiu(T6, T6, Immediate(entry_bytes));
-  } else {
-    __ AddImmediate(T6, entry_bytes);
-    __ BranchNotEqual(T3, Smi::RawValue(kIllegalCid), &loop);  // Done?
-  }
-
-  Label update_ic_data;
-  __ b(&update_ic_data);
-
-  __ Bind(&found);
-  const intptr_t count_offset =
-      ICData::CountIndexFor(kNumArgsTested) * kWordSize;
-  Label no_overflow;
-  __ lw(T1, Address(T6, count_offset));
-  __ AddImmediateDetectOverflow(T1, T1, Smi::RawValue(1), CMPRES, T5);
-  __ bgez(CMPRES, &no_overflow);
-  __ delay_slot()->sw(T1, Address(T6, count_offset));
-  __ LoadImmediate(TMP1, Smi::RawValue(Smi::kMaxValue));
-  __ sw(TMP1, Address(T6, count_offset));  // If overflow.
-  __ Bind(&no_overflow);
-
-  Label compute_result;
-  __ Bind(&compute_result);
-  __ LoadObject(T4, Bool::True());
-  __ LoadObject(T5, Bool::False());
-  __ subu(CMPRES, A0, A1);
-  __ movz(V0, T4, CMPRES);
-  __ movn(V0, T5, CMPRES);
-  __ LeaveStubFrameAndReturn();
-
-  __ Bind(&get_class_id_as_smi);
-  // Test if Smi -> load Smi class for comparison.
-  Label not_smi;
-  __ andi(CMPRES, T2, Immediate(kSmiTagMask));
-  __ bne(CMPRES, ZR, &not_smi);
-  __ jr(RA);
-  __ delay_slot()->addiu(T2, ZR, Immediate(Smi::RawValue(kSmiCid)));
-  __ Bind(&not_smi);
-  __ LoadClassId(T2, T2);
-  __ jr(RA);
-  __ delay_slot()->SmiTag(T2);
-
-  __ Bind(&update_ic_data);
-  // T0: ICData
-  __ addiu(SP, SP, Immediate(-4 * kWordSize));
-  __ sw(A1, Address(SP, 3 * kWordSize));
-  __ sw(A0, Address(SP, 2 * kWordSize));
-  __ LoadObject(TMP1, Symbols::EqualOperator());  // Target's name.
-  __ sw(TMP1, Address(SP, 1 * kWordSize));
-  __ sw(T0, Address(SP, 0 * kWordSize));  // ICData.
-  __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4);
-  __ lw(A0, Address(SP, 2 * kWordSize));
-  __ lw(A1, Address(SP, 3 * kWordSize));
-  __ b(&compute_result);
-  __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize));
-}
-
-
 // Calls to the runtime to optimize the given function.
 // T0: function to be reoptimized.
 // S4: argument descriptor (preserved).
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 7d47618..d2d304f 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -60,7 +60,7 @@
   __ movq(CTX, RAX);
 
   // Reserve space for arguments and align frame before entering C++ world.
-  __ AddImmediate(RSP, Immediate(-sizeof(NativeArguments)));
+  __ subq(RSP, Immediate(sizeof(NativeArguments)));
   if (OS::ActivationFrameAlignment() > 1) {
     __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
   }
@@ -149,7 +149,7 @@
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
   // RDI) and align frame before entering the C++ world.
-  __ AddImmediate(RSP, Immediate(-sizeof(NativeArguments)));
+  __ subq(RSP, Immediate(sizeof(NativeArguments)));
   if (OS::ActivationFrameAlignment() > 1) {
     __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
   }
@@ -217,7 +217,7 @@
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
   // RDI) and align frame before entering the C++ world.
-  __ AddImmediate(RSP, Immediate(-sizeof(NativeArguments)));
+  __ subq(RSP, Immediate(sizeof(NativeArguments)));
   if (OS::ActivationFrameAlignment() > 1) {
     __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
   }
@@ -255,7 +255,7 @@
   __ EnterStubFrame();
   __ pushq(R10);  // Preserve arguments descriptor array.
   // Setup space on stack for return value.
-  __ PushObject(Object::null_object());
+  __ PushObject(Object::null_object(), PP);
   __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
   __ popq(RAX);  // Get Code object result.
   __ popq(R10);  // Restore arguments descriptor array.
@@ -275,7 +275,7 @@
   __ EnterStubFrame();
   __ pushq(R10);  // Preserve arguments descriptor array.
   // Setup space on stack for return value.
-  __ PushObject(Object::null_object());
+  __ PushObject(Object::null_object(), PP);
   __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
   __ popq(RAX);  // Get Code object.
   __ popq(R10);  // Restore arguments descriptor array.
@@ -308,8 +308,8 @@
   __ Bind(&loop);
   __ movq(RAX, Address(R12, 0));
   __ movq(Address(RBX, 0), RAX);
-  __ AddImmediate(RBX, Immediate(kWordSize));
-  __ AddImmediate(R12, Immediate(-kWordSize));
+  __ addq(RBX, Immediate(kWordSize));
+  __ subq(R12, Immediate(kWordSize));
   __ Bind(&loop_condition);
   __ decq(R10);
   __ j(POSITIVE, &loop, Assembler::kNearJump);
@@ -324,7 +324,7 @@
 //       when trying to resolve the call.
 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
   __ EnterStubFrameWithPP();
-  __ PushObject(Object::null_object());  // Space for the return value.
+  __ PushObject(Object::null_object(), PP);  // Space for the return value.
 
   // Push the receiver as an argument.  Load the smi-tagged argument
   // count into R13 to index the receiver in the stack.  There are
@@ -504,7 +504,7 @@
   __ pushq(R10);
 
   // Space for the result of the runtime call.
-  __ PushObject(Object::null_object());
+  __ PushObject(Object::null_object(), PP);
   __ pushq(RAX);  // Receiver.
   __ pushq(RBX);  // IC data.
   __ pushq(R10);  // Arguments descriptor.
@@ -519,7 +519,7 @@
   __ LeaveFrameWithPP();
 
   Label lookup;
-  __ CompareObject(RAX, Object::null_object());
+  __ CompareObject(RAX, Object::null_object(), PP);
   __ j(EQUAL, &lookup, Assembler::kNearJump);
   __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
   __ jmp(RAX);
@@ -650,7 +650,7 @@
   // calling into the runtime.
   __ EnterStubFrame();
   // Setup space on stack for return value.
-  __ PushObject(Object::null_object());
+  __ PushObject(Object::null_object(), PP);
   __ pushq(R10);  // Array length as Smi.
   __ pushq(RBX);  // Element type.
   __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
@@ -1228,7 +1228,7 @@
   // Create a stub frame.
   __ EnterStubFrameWithPP();
   __ pushq(R12);  // Setup space on stack for return value.
-  __ PushObject(cls);  // Push class of object to be allocated.
+  __ PushObject(cls, PP);  // Push class of object to be allocated.
   if (is_cls_parameterized) {
     __ pushq(RAX);  // Push type arguments of object to be allocated.
     __ pushq(RDX);  // Push type arguments of instantiator.
@@ -1364,7 +1364,7 @@
   }
 
   __ pushq(R12);  // Setup space on stack for the return value.
-  __ PushObject(func);
+  __ PushObject(func, PP);
   if (is_implicit_instance_closure) {
     __ pushq(RAX);  // Receiver.
   }
@@ -2003,104 +2003,6 @@
 }
 
 
-// Implements equality operator when one of the arguments is null
-// (identity check) and updates ICData if necessary.
-// TOS + 0: return address
-// TOS + 1: right argument
-// TOS + 2: left argument
-// RBX: ICData.
-// RAX: result.
-// TODO(srdjan): Move to VM stubs once Boolean objects become VM objects.
-void StubCode::GenerateEqualityWithNullArgStub(Assembler* assembler) {
-  static const intptr_t kNumArgsTested = 2;
-#if defined(DEBUG)
-  { Label ok;
-    __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset()));
-    __ cmpq(RCX, Immediate(kNumArgsTested));
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Incorrect ICData for equality");
-    __ Bind(&ok);
-  }
-#endif  // DEBUG
-  // Check IC data, update if needed.
-  // RBX: IC data object (preserved).
-  __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
-  // R12: ic_data_array with check entries: classes and target functions.
-  __ leaq(R12, FieldAddress(R12, Array::data_offset()));
-  // R12: points directly to the first ic data array element.
-
-  Label get_class_id_as_smi, no_match, loop, compute_result, found;
-  __ Bind(&loop);
-  // Check left.
-  __ movq(RAX, Address(RSP, 2 * kWordSize));
-  __ call(&get_class_id_as_smi);
-  __ movq(R13, Address(R12, 0 * kWordSize));
-  __ cmpq(RAX, R13);  // Class id match?
-  __ j(NOT_EQUAL, &no_match, Assembler::kNearJump);
-  // Check right.
-  __ movq(RAX, Address(RSP, 1 * kWordSize));
-  __ call(&get_class_id_as_smi);
-  __ movq(R13, Address(R12, 1 * kWordSize));
-  __ cmpq(RAX, R13);  // Class id match?
-  __ j(EQUAL, &found, Assembler::kNearJump);
-  __ Bind(&no_match);
-  // Next check group.
-  __ addq(R12, Immediate(
-      kWordSize * ICData::TestEntryLengthFor(kNumArgsTested)));
-  __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid)));  // Done?
-  __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
-  Label update_ic_data;
-  __ jmp(&update_ic_data);
-
-  __ Bind(&found);
-  const intptr_t count_offset =
-      ICData::CountIndexFor(kNumArgsTested) * kWordSize;
-  __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1)));
-  __ j(NO_OVERFLOW, &compute_result);
-  __ movq(Address(R12, count_offset),
-          Immediate(Smi::RawValue(Smi::kMaxValue)));
-
-  __ Bind(&compute_result);
-  Label true_label;
-  __ movq(RAX, Address(RSP, 1 * kWordSize));
-  __ cmpq(RAX, Address(RSP, 2 * kWordSize));
-  __ j(EQUAL, &true_label, Assembler::kNearJump);
-  __ LoadObject(RAX, Bool::False(), PP);
-  __ ret();
-  __ Bind(&true_label);
-  __ LoadObject(RAX, Bool::True(), PP);
-  __ ret();
-
-  __ Bind(&get_class_id_as_smi);
-  Label not_smi;
-  // Test if Smi -> load Smi class for comparison.
-  __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
-  __ movq(RAX, Immediate(Smi::RawValue(kSmiCid)));
-  __ ret();
-
-  __ Bind(&not_smi);
-  __ LoadClassId(RAX, RAX);
-  __ SmiTag(RAX);
-  __ ret();
-
-  __ Bind(&update_ic_data);
-
-  // RBX: ICData
-  __ movq(RAX, Address(RSP, 1 * kWordSize));
-  __ movq(R13, Address(RSP, 2 * kWordSize));
-  __ EnterStubFrame();
-  __ pushq(R13);  // arg 0
-  __ pushq(RAX);  // arg 1
-  __ PushObject(Symbols::EqualOperator());  // Target's name.
-  __ pushq(RBX);  // ICData
-  __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4);
-  __ Drop(4);
-  __ LeaveFrame();
-
-  __ jmp(&compute_result, Assembler::kNearJump);
-}
-
 // Calls to the runtime to optimize the given function.
 // RDI: function to be reoptimized.
 // R10: argument descriptor (preserved).
diff --git a/runtime/vm/stub_code_x64_test.cc b/runtime/vm/stub_code_x64_test.cc
index 3efc152..cc0e3fb 100644
--- a/runtime/vm/stub_code_x64_test.cc
+++ b/runtime/vm/stub_code_x64_test.cc
@@ -47,12 +47,12 @@
   ASSERT(context.isolate() == Isolate::Current());
   __ EnterStubFrameWithPP();
   __ LoadObject(CTX, context, PP);
-  __ PushObject(result);  // Push Null object for return value.
-  __ PushObject(smi1);  // Push argument 1 smi1.
-  __ PushObject(smi2);  // Push argument 2 smi2.
+  __ PushObject(result, PP);  // Push Null object for return value.
+  __ PushObject(smi1, PP);  // Push argument 1 smi1.
+  __ PushObject(smi2, PP);  // Push argument 2 smi2.
   ASSERT(kTestSmiSubRuntimeEntry.argument_count() == argc);
   __ CallRuntime(kTestSmiSubRuntimeEntry, argc);  // Call SmiSub runtime func.
-  __ AddImmediate(RSP, Immediate(argc * kWordSize));
+  __ AddImmediate(RSP, Immediate(argc * kWordSize), PP);
   __ popq(RAX);  // Pop return value from return slot.
   __ LeaveFrameWithPP();
   __ ret();
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 987eb45..723263c 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -116,12 +116,12 @@
   V(_Bigint, "_Bigint")                                                        \
   V(_Double, "_Double")                                                        \
   V(Bool, "bool")                                                              \
-  V(ObjectArray, "_ObjectArray")                                               \
-  V(ObjectArrayFactory, "_ObjectArray.")                                       \
-  V(GrowableObjectArray, "_GrowableObjectArray")                               \
-  V(GrowableObjectArrayFactory, "_GrowableObjectArray.")                       \
-  V(GrowableObjectArrayWithData, "_GrowableObjectArray.withData")              \
-  V(ImmutableArray, "_ImmutableArray")                                         \
+  V(_List, "_List")                                                            \
+  V(_ListFactory, "_List.")                                                    \
+  V(_GrowableList, "_GrowableList")                                            \
+  V(_GrowableListFactory, "_GrowableList.")                                    \
+  V(_GrowableListWithData, "_GrowableList.withData")                           \
+  V(_ImmutableList, "_ImmutableList")                                          \
   V(OneByteString, "_OneByteString")                                           \
   V(TwoByteString, "_TwoByteString")                                           \
   V(ExternalOneByteString, "_ExternalOneByteString")                           \
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index edcd75d..921078b 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -116,6 +116,8 @@
     'debuginfo.h',
     'debuginfo_android.cc',
     'debuginfo_linux.cc',
+    'deferred_objects.cc',
+    'deferred_objects.h',
     'deopt_instructions.cc',
     'deopt_instructions.h',
     'disassembler.cc',
diff --git a/sdk/lib/_internal/compiler/implementation/common.dart b/sdk/lib/_internal/compiler/implementation/common.dart
new file mode 100644
index 0000000..3c069ca
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/common.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart2js.common;
+
+export 'dart2jslib.dart' show
+    CompilerTask,
+    Compiler,
+    Constant,
+    ConstantHandler,
+    InterceptorConstant,
+    MessageKind,
+    NullConstant,
+    Selector,
+    SourceString,
+    TreeElements,
+    TypeConstant,
+    invariant;
+
+export 'dart_types.dart' show
+    DartType,
+    FunctionType,
+    InterfaceType,
+    TypeVariableType,
+    Types;
+
+export 'elements/elements.dart' show
+    ClassElement,
+    ClosureFieldElement,
+    Element,
+    Elements,
+    FunctionElement,
+    FunctionSignature,
+    LibraryElement,
+    MetadataAnnotation,
+    MixinApplicationElement,
+    TypedefElement,
+    VariableElement;
+
+export 'tree/tree.dart' show
+    Node;
+
+export 'types/types.dart' show
+    TypeMask;
+
+export 'universe/universe.dart' show
+    SelectorKind;
+
+export 'util/util.dart' show
+    Link,
+    SpannableAssertionFailure;
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index 48bc9f4..8ae51fa 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -29,12 +29,6 @@
   /** Caches the statics where the initial value cannot be eagerly compiled. */
   final Set<VariableElement> lazyStatics;
 
-  /** Caches the createRuntimeType function if registered. */
-  Element createRuntimeTypeFunction = null;
-
-  /** Caches the setRuntimeTypeInfo function if registered. */
-  Element setRuntimeTypeInfoFunction = null;
-
   ConstantHandler(Compiler compiler, this.constantSystem,
                   { bool this.isMetadata: false })
       : initialVariableValues = new Map<VariableElement, dynamic>(),
@@ -45,90 +39,12 @@
 
   String get name => 'ConstantHandler';
 
-  void registerCompileTimeConstant(Constant constant, TreeElements elements) {
-    registerInstantiatedType(constant.computeType(compiler), elements);
-    if (constant.isFunction()) {
-      FunctionConstant function = constant;
-      registerGetOfStaticFunction(function.element);
-    } else if (constant.isInterceptor()) {
-      // An interceptor constant references the class's prototype chain.
-      InterceptorConstant interceptor = constant;
-      registerInstantiatedType(interceptor.dispatchedType, elements);
-    }
+  void addCompileTimeConstantForEmission(Constant constant) {
     compiledConstants.add(constant);
   }
 
-  void registerInstantiatedType(DartType type, TreeElements elements) {
-    if (isMetadata) {
-      compiler.backend.registerMetadataInstantiatedType(type, elements);
-      return;
-    }
-    compiler.enqueuer.codegen.registerInstantiatedType(type, elements);
-    if (type is InterfaceType &&
-        !type.isRaw &&
-        compiler.backend.classNeedsRti(type.element)) {
-      registerSetRuntimeTypeInfoFunction();
-    }
-  }
-
-  void registerStaticUse(Element element) {
-    if (isMetadata) {
-      compiler.backend.registerMetadataStaticUse(element);
-      return;
-    }
-    compiler.analyzeElement(element.declaration);
-    compiler.enqueuer.codegen.registerStaticUse(element);
-  }
-
-  void registerGetOfStaticFunction(FunctionElement element) {
-    if (isMetadata) {
-      compiler.backend.registerMetadataGetOfStaticFunction(element);
-      return;
-    }
-    compiler.analyzeElement(element.declaration);
-    compiler.enqueuer.codegen.registerGetOfStaticFunction(element);
-  }
-
-  void registerStringInstance(TreeElements elements) {
-    registerInstantiatedType(compiler.stringClass.rawType, elements);
-  }
-
-  void registerSetRuntimeTypeInfoFunction() {
-    if (setRuntimeTypeInfoFunction != null) return;
-    SourceString helperName = const SourceString('setRuntimeTypeInfo');
-    setRuntimeTypeInfoFunction = compiler.findHelper(helperName);
-    registerStaticUse(setRuntimeTypeInfoFunction);
-  }
-
-  void registerCreateRuntimeTypeFunction() {
-    if (createRuntimeTypeFunction != null) return;
-    SourceString helperName = const SourceString('createRuntimeType');
-    createRuntimeTypeFunction = compiler.findHelper(helperName);
-    registerStaticUse(createRuntimeTypeFunction);
-  }
-
-  /**
-   * Compiles the initial value of the given field and stores it in an internal
-   * map. Returns the initial value (a constant) if it can be computed
-   * statically. Returns [:null:] if the variable must be initialized lazily.
-   *
-   * [work] must contain a [VariableElement] refering to a global or
-   * static field.
-   */
-  Constant compileWorkItem(CodegenWorkItem work) {
-    return measure(() {
-      assert(work.element.kind == ElementKind.FIELD
-             || work.element.kind == ElementKind.PARAMETER
-             || work.element.kind == ElementKind.FIELD_PARAMETER);
-      VariableElement element = work.element;
-      // Shortcut if it has already been compiled.
-      Constant result = initialVariableValues[element];
-      if (result != null) return result;
-      if (lazyStatics.contains(element)) return null;
-      result = compileVariableWithDefinitions(element, work.resolutionTree);
-      assert(pendingVariables.isEmpty);
-      return result;
-    });
+  Constant getConstantForVariable(VariableElement element) {
+    return initialVariableValues[element];
   }
 
   /**
@@ -175,9 +91,6 @@
                                           TreeElements definitions,
                                           {bool isConst: false}) {
     return measure(() {
-      // Initializers for parameters must be const.
-      isConst = isConst || element.modifiers.isConst()
-          || !Elements.isStaticOrTopLevel(element);
       if (!isConst && lazyStatics.contains(element)) return null;
 
       Node node = element.parseNode(compiler);
@@ -235,23 +148,17 @@
                                       {bool isConst: false}) {
     return measure(() {
       assert(node != null);
+      Constant constant = definitions.getConstant(node);
+      if (constant != null) {
+        return constant;
+      }
       CompileTimeConstantEvaluator evaluator = new CompileTimeConstantEvaluator(
           this, definitions, compiler, isConst: isConst);
-      return evaluator.evaluate(node);
-    });
-  }
-
-  /** Attempts to compile a constant expression. Returns null if not possible */
-  Constant tryCompileNodeWithDefinitions(Node node, TreeElements definitions) {
-    return measure(() {
-      assert(node != null);
-      try {
-        TryCompileTimeConstantEvaluator evaluator =
-            new TryCompileTimeConstantEvaluator(this, definitions, compiler);
-        return evaluator.evaluate(node);
-      } on CompileTimeConstantError catch (exn) {
-        return null;
+      constant = evaluator.evaluate(node);
+      if (constant != null) {
+        definitions.setConstant(node, constant);
       }
+      return constant;
     });
   }
 
@@ -358,17 +265,14 @@
   }
 
   Constant visitLiteralBool(LiteralBool node) {
-    handler.registerInstantiatedType(compiler.boolClass.rawType, elements);
     return constantSystem.createBool(node.value);
   }
 
   Constant visitLiteralDouble(LiteralDouble node) {
-    handler.registerInstantiatedType(compiler.doubleClass.rawType, elements);
     return constantSystem.createDouble(node.value);
   }
 
   Constant visitLiteralInt(LiteralInt node) {
-    handler.registerInstantiatedType(compiler.intClass.rawType, elements);
     return constantSystem.createInt(node.value);
   }
 
@@ -383,10 +287,7 @@
       arguments.add(evaluateConstant(link.head));
     }
     DartType type = elements.getType(node);
-    handler.registerInstantiatedType(type, elements);
-    Constant constant = new ListConstant(type, arguments);
-    handler.registerCompileTimeConstant(constant, elements);
-    return constant;
+    return new ListConstant(type, arguments);
   }
 
   Constant visitLiteralMap(LiteralMap node) {
@@ -422,13 +323,15 @@
     bool hasProtoKey = (protoValue != null);
     List<Constant> values = map.values.toList();
     InterfaceType sourceType = elements.getType(node);
-    Link<DartType> arguments =
-        new Link<DartType>.fromList([compiler.stringClass.rawType]);
-    DartType keysType = new InterfaceType(compiler.listClass, arguments);
-    ListConstant keysList = new ListConstant(keysType, keys);
-    if (onlyStringKeys) {
-      handler.registerCompileTimeConstant(keysList, elements);
+    DartType keysType;
+    if (sourceType.treatAsRaw) {
+      keysType = compiler.listClass.rawType;
+    } else {
+      Link<DartType> arguments =
+          new Link<DartType>.fromList([sourceType.typeArguments.head]);
+      keysType = new InterfaceType(compiler.listClass, arguments);
     }
+    ListConstant keysList = new ListConstant(keysType, keys);
     SourceString className = onlyStringKeys
         ? (hasProtoKey ? MapConstant.DART_PROTO_CLASS
                        : MapConstant.DART_STRING_CLASS)
@@ -436,12 +339,13 @@
     ClassElement classElement = compiler.jsHelperLibrary.find(className);
     classElement.ensureResolved(compiler);
     Link<DartType> typeArgument = sourceType.typeArguments;
-    InterfaceType type = new InterfaceType(classElement, typeArgument);
-    handler.registerInstantiatedType(type, elements);
-    Constant constant =
-        new MapConstant(type, keysList, values, protoValue, onlyStringKeys);
-    handler.registerCompileTimeConstant(constant, elements);
-    return constant;
+    InterfaceType type;
+    if (sourceType.treatAsRaw) {
+      type = classElement.rawType;
+    } else {
+      type = new InterfaceType(classElement, typeArgument);
+    }
+    return new MapConstant(type, keysList, values, protoValue, onlyStringKeys);
   }
 
   Constant visitLiteralNull(LiteralNull node) {
@@ -449,7 +353,6 @@
   }
 
   Constant visitLiteralString(LiteralString node) {
-    handler.registerStringInstance(elements);
     return constantSystem.createString(node.dartString, node);
   }
 
@@ -457,7 +360,6 @@
     StringConstant left = evaluate(node.first);
     StringConstant right = evaluate(node.second);
     if (left == null || right == null) return null;
-    handler.registerStringInstance(elements);
     return constantSystem.createString(
         new DartString.concat(left.value, right.value), node);
   }
@@ -485,12 +387,10 @@
       if (partString == null) return null;
       accumulator = new DartString.concat(accumulator, partString.value);
     };
-    handler.registerStringInstance(elements);
     return constantSystem.createString(accumulator, node);
   }
 
   Constant visitLiteralSymbol(LiteralSymbol node) {
-    handler.registerStringInstance(elements);
     InterfaceType type = compiler.symbolClass.computeType(compiler);
     List<Constant> createArguments(_) {
       return [constantSystem.createString(
@@ -502,17 +402,9 @@
 
   Constant makeTypeConstant(Element element) {
     DartType elementType = element.computeType(compiler).asRaw();
-    compiler.backend.registerTypeLiteral(
-        element, compiler.enqueuer.codegen, elements);
     DartType constantType =
         compiler.backend.typeImplementation.computeType(compiler);
-    Constant constant = new TypeConstant(elementType, constantType);
-    // If we use a type literal in a constant, the compile time
-    // constant emitter will generate a call to the createRuntimeType
-    // helper so we register a use of that.
-    handler.registerCreateRuntimeTypeFunction();
-    handler.registerCompileTimeConstant(constant, elements);
-    return constant;
+    return new TypeConstant(elementType, constantType);
   }
 
   // TODO(floitsch): provide better error-messages.
@@ -520,9 +412,7 @@
     Element element = elements[send];
     if (send.isPropertyAccess) {
       if (Elements.isStaticOrTopLevelFunction(element)) {
-        Constant constant = new FunctionConstant(element);
-        handler.registerCompileTimeConstant(constant, elements);
-        return constant;
+        return new FunctionConstant(element);
       } else if (Elements.isStaticOrTopLevelField(element)) {
         Constant result;
         if (element.modifiers.isConst()) {
@@ -532,6 +422,7 @@
         }
         if (result != null) return result;
       } else if (Elements.isClass(element) || Elements.isTypedef(element)) {
+        assert(elements.isTypeLiteral(send));
         return makeTypeConstant(element);
       } else if (send.receiver != null) {
         // Fall through to error handling.
@@ -550,7 +441,10 @@
         Constant result = constantSystem.identity.fold(left, right);
         if (result != null) return result;
       } else if (Elements.isClass(element) || Elements.isTypedef(element)) {
-        return makeTypeConstant(element);
+        // The node itself is not a constant but we register the selector (the
+        // identifier that refers to the class/typedef) as a constant.
+        Constant typeConstant = makeTypeConstant(element);
+        elements.setConstant(send.selector, typeConstant);
       }
       return signalNotCompileTimeConstant(send);
     } else if (send.isPrefix) {
@@ -668,6 +562,25 @@
     return signalNotCompileTimeConstant(send);
   }
 
+  Constant visitConditional(Conditional node) {
+    Constant condition = evaluate(node.condition);
+    if (condition == null) {
+      return null;
+    } else if (!condition.isBool()) {
+      DartType conditionType = condition.computeType(compiler);
+      if (isEvaluatingConstant) {
+        compiler.reportFatalError(
+            node.condition, MessageKind.NOT_ASSIGNABLE.error,
+            {'fromType': conditionType, 'toType': compiler.boolClass.rawType});
+      }
+      return null;
+    }
+    Constant thenExpression = evaluate(node.thenExpression);
+    Constant elseExpression = evaluate(node.elseExpression);
+    BoolConstant boolCondition = condition;
+    return boolCondition.value ? thenExpression : elseExpression;
+  }
+
   Constant visitSendSet(SendSet node) {
     return signalNotCompileTimeConstant(node);
   }
@@ -744,10 +657,7 @@
     evaluator.evaluateConstructorFieldValues(arguments);
     List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
 
-    handler.registerInstantiatedType(type, elements);
-    Constant constant = new ConstructedConstant(type, jsNewArguments);
-    handler.registerCompileTimeConstant(constant, elements);
-    return constant;
+    return new ConstructedConstant(type, jsNewArguments);
   }
 
   Constant visitParenthesizedExpression(ParenthesizedExpression node) {
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 04c0df0..6f673a3 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -123,6 +123,13 @@
   bool classNeedsRti(ClassElement cls);
   bool methodNeedsRti(FunctionElement function);
 
+
+  /// Called during codegen when [constant] has been used.
+  void registerCompileTimeConstant(Constant constant, TreeElements elements) {}
+
+  /// Called during post-processing when [constant] has been evaluated.
+  void registerMetadataConstant(Constant constant, TreeElements elements) {}
+
   /// Called during resolution to notify to the backend that a class is
   /// being instantiated.
   void registerInstantiatedClass(ClassElement cls,
@@ -257,10 +264,6 @@
     return new Future.value();
   }
 
-  void registerMetadataInstantiatedType(DartType type, TreeElements elements) {}
-  void registerMetadataStaticUse(Element element) {}
-  void registerMetadataGetOfStaticFunction(FunctionElement element) {}
-
   /// Called by [MirrorUsageAnalyzerTask] after it has merged all @MirrorsUsed
   /// annotations. The arguments corresponds to the unions of the corresponding
   /// fields of the annotations.
@@ -529,11 +532,9 @@
   ti.TypesTask typesTask;
   Backend backend;
   ConstantHandler constantHandler;
-  ConstantHandler metadataHandler;
   EnqueueTask enqueuer;
   DeferredLoadTask deferredLoadTask;
   MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask;
-  ContainerTracer containerTracer;
   String buildId;
 
   static const SourceString MAIN = const SourceString('main');
@@ -639,15 +640,12 @@
       closureToClassMapper = new closureMapping.ClosureTask(this, closureNamer),
       checker = new TypeCheckerTask(this),
       typesTask = new ti.TypesTask(this),
-      containerTracer = new ContainerTracer(this),
       constantHandler = new ConstantHandler(this, backend.constantSystem),
       deferredLoadTask = new DeferredLoadTask(this),
       mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this),
       enqueuer = new EnqueueTask(this)];
 
     tasks.addAll(backend.tasks);
-    metadataHandler = new ConstantHandler(
-        this, backend.constantSystem, isMetadata: true);
   }
 
   Universe get resolverWorld => enqueuer.resolution.universe;
diff --git a/sdk/lib/_internal/compiler/implementation/constants.dart b/sdk/lib/_internal/compiler/implementation/constants.dart
index bca6524..a8ac524 100644
--- a/sdk/lib/_internal/compiler/implementation/constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/constants.dart
@@ -45,6 +45,7 @@
   bool isNaN() => false;
   bool isMinusZero() => false;
 
+  // TODO(johnniwinther): Replace with a 'type' getter.
   DartType computeType(Compiler compiler);
 
   List<Constant> getDependencies();
@@ -295,6 +296,10 @@
   int get length => value.length;
 
   accept(ConstantVisitor visitor) => visitor.visitString(this);
+
+  String toString() {
+    return 'StringConstant(${Error.safeToString(value.slowToString())})';
+  }
 }
 
 abstract class ObjectConstant extends Constant {
@@ -323,6 +328,8 @@
   List<Constant> getDependencies() => const <Constant>[];
 
   accept(ConstantVisitor visitor) => visitor.visitType(this);
+
+  String toString() => 'TypeConstant(${Error.safeToString(representedType)})';
 }
 
 class ListConstant extends ObjectConstant {
@@ -362,6 +369,17 @@
   int get length => entries.length;
 
   accept(ConstantVisitor visitor) => visitor.visitList(this);
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('ListConstant([');
+    for (int i = 0 ; i < entries.length ; i++) {
+      if (i > 0) sb.write(',');
+      sb.write(Error.safeToString(entries[i]));
+    }
+    sb.write('])');
+    return sb.toString();
+  }
 }
 
 class MapConstant extends ObjectConstant {
@@ -437,6 +455,19 @@
   int get length => keys.length;
 
   accept(ConstantVisitor visitor) => visitor.visitMap(this);
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('MapConstant({');
+    for (int i = 0 ; i < keys.entries.length ; i++) {
+      if (i > 0) sb.write(',');
+      sb.write(Error.safeToString(keys.entries[i]));
+      sb.write(':');
+      sb.write(Error.safeToString(values[i]));
+    }
+    sb.write('})');
+    return sb.toString();
+  }
 }
 
 class InterceptorConstant extends Constant {
@@ -460,6 +491,10 @@
   accept(ConstantVisitor visitor) => visitor.visitInterceptor(this);
 
   DartType computeType(Compiler compiler) => compiler.types.dynamicType;
+
+  String toString() {
+    return 'InterceptorConstant(${Error.safeToString(dispatchedType)})';
+  }
 }
 
 class ConstructedConstant extends ObjectConstant {
@@ -510,4 +545,21 @@
     }, includeSuperAndInjectedMembers: true);
     return result;
   }
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('ConstructedConstant(');
+    sb.write(type);
+    sb.write('(');
+    int i = 0;
+    fieldElements.forEach((Element field, Constant value) {
+      if (i > 0) sb.write(',');
+      sb.write(Error.safeToString(field.name.slowToString()));
+      sb.write('=');
+      sb.write(Error.safeToString(value));
+      i++;
+    });
+    sb.write('))');
+    return sb.toString();
+  }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
index 47febfa..7d825c0 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
@@ -32,7 +32,6 @@
 import 'source_file.dart' show SourceFile;
 import 'js/js.dart' as js;
 import 'deferred_load.dart' show DeferredLoadTask;
-import 'inferrer/container_tracer.dart' show ContainerTracer;
 import 'mirrors_used.dart' show MirrorUsageAnalyzerTask;
 
 export 'resolution/resolution.dart' show TreeElements, TreeElementMapping;
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
index 6dea904..bbf3c20 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -619,7 +619,7 @@
   }
 }
 
-compareBy(f) => (x, y) => f(x).compareTo(f(y));
+Comparator compareBy(f) => (x, y) => f(x).compareTo(f(y));
 
 List sorted(Iterable l, comparison) {
   final result = new List.from(l);
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
index f842ac3..bcaa080 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
@@ -4,7 +4,7 @@
 
 part of dart_backend;
 
-Function get _compareNodes =>
+Comparator get _compareNodes =>
     compareBy((n) => n.getBeginToken().charOffset);
 
 typedef String _Renamer(Renamable renamable);
@@ -90,7 +90,7 @@
     StringBuffer result = new StringBuffer(renameElement(type.element));
     if (type is InterfaceType) {
       InterfaceType interfaceType = type;
-      if (!interfaceType.isRaw) {
+      if (!interfaceType.treatAsRaw) {
         result.write('<');
         Link<DartType> argumentsLink = interfaceType.typeArguments;
         result.write(renameType(argumentsLink.head, renameElement));
@@ -306,53 +306,54 @@
   }
 }
 
-/** Always tries to return original identifier name unless it is forbidden. */
-String conservativeGenerator(
-    String originalName, bool isForbidden(String name)) {
-  String newName = originalName;
-  while (isForbidden(newName)) {
-    newName = 'p_$newName';
+/**
+ * Generates mini ID based on index.
+ * In other words, it converts index to visual representation
+ * as if digits are given characters.
+ */
+String generateMiniId(int index) {
+  const String firstCharAlphabet =
+      r'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+  const String otherCharsAlphabet =
+      r'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$';
+  // It's like converting index in decimal to [chars] radix.
+  if (index < firstCharAlphabet.length) return firstCharAlphabet[index];
+  StringBuffer resultBuilder = new StringBuffer();
+  resultBuilder.writeCharCode(
+     firstCharAlphabet.codeUnitAt(index % firstCharAlphabet.length));
+  index ~/= firstCharAlphabet.length;
+  int length = otherCharsAlphabet.length;
+  while (index >= length) {
+    resultBuilder.writeCharCode(otherCharsAlphabet.codeUnitAt(index % length));
+    index ~/= length;
   }
-  return newName;
+  resultBuilder.write(otherCharsAlphabet[index]);
+  return resultBuilder.toString();
 }
 
+
+/** Always tries to return original identifier name unless it is forbidden. */
+String conservativeGenerator(String name, bool isForbidden(String name)) {
+  String result = name;
+  int index = 0;
+  while (isForbidden(result)) {
+    result = '${generateMiniId(index++)}_$name';
+  }
+  return result;
+}
+
+
 /** Always tries to generate the most compact identifier. */
 class MinifyingGenerator {
-  static const String firstCharAlphabet =
-      r'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
-  static const String otherCharsAlphabet =
-      r'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$';
-  int nextIdIndex;
+  int index = 0;
 
-  MinifyingGenerator() : nextIdIndex = 0;
+  MinifyingGenerator();
 
   String generate(bool isForbidden(String name)) {
-    String newName;
+    String result;
     do {
-      newName = getNextId();
-    } while(isForbidden(newName));
-    return newName;
+      result = generateMiniId(index++);
+    } while (isForbidden(result));
+    return result;
   }
-
-  /**
-   * Generates next mini ID with current index and alphabet.
-   * Advances current index.
-   * In other words, it converts index to visual representation
-   * as if digits are given characters.
-   */
-  String getNextId() {
-    // It's like converting index in decimal to [chars] radix.
-    int index = nextIdIndex++;
-    StringBuffer resultBuilder = new StringBuffer();
-    if (index < firstCharAlphabet.length) return firstCharAlphabet[index];
-    resultBuilder.write(firstCharAlphabet[index % firstCharAlphabet.length]);
-    index ~/= firstCharAlphabet.length;
-    int length = otherCharsAlphabet.length;
-    while (index >= length) {
-      resultBuilder.write(otherCharsAlphabet[index % length]);
-      index ~/= length;
-    }
-    resultBuilder.write(otherCharsAlphabet[index]);
-    return resultBuilder.toString();
-  }
-}
+}
\ No newline at end of file
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index f301f9b..f70517e 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -93,6 +93,9 @@
   /// Returns the raw version of this type.
   DartType asRaw() => this;
 
+  /// Is [: true :] if this type has no non-dynamic type arguments.
+  bool get treatAsRaw => isRaw;
+
   /// Is [: true :] if this type should be treated as the dynamic type.
   bool get treatAsDynamic => false;
 
@@ -424,6 +427,14 @@
   bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
 
   GenericType asRaw() => element.rawType;
+
+  bool get treatAsRaw {
+    if (isRaw) return true;
+    for (Link<DartType> link = typeArguments; !link.isEmpty; link = link.tail) {
+      if (!link.head.treatAsDynamic) return false;
+    }
+    return true;
+  }
 }
 
 class InterfaceType extends GenericType {
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 42ef97c..394d4e4 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -1574,6 +1574,7 @@
 
   bool get isUnnamedMixinApplication => false;
 
+  // TODO(johnniwinther): Add [thisType] getter similar to [rawType].
   InterfaceType computeType(Compiler compiler) {
     if (thisType == null) {
       if (origin == null) {
diff --git a/sdk/lib/_internal/compiler/implementation/enqueue.dart b/sdk/lib/_internal/compiler/implementation/enqueue.dart
index d1ee2cc..e489fb1 100644
--- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
+++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
@@ -4,6 +4,8 @@
 
 part of dart2js;
 
+typedef ItemCompilationContext ItemCompilationContextCreator();
+
 class EnqueueTask extends CompilerTask {
   final ResolutionEnqueuer resolution;
   final CodegenEnqueuer codegen;
@@ -71,7 +73,7 @@
 abstract class Enqueuer {
   final String name;
   final Compiler compiler; // TODO(ahe): Remove this dependency.
-  final Function itemCompilationContextCreator;
+  final ItemCompilationContextCreator itemCompilationContextCreator;
   final Map<String, Link<Element>> instanceMembersByName
       = new Map<String, Link<Element>>();
   final Map<String, Link<Element>> instanceFunctionsByName
@@ -85,9 +87,7 @@
 
   bool hasEnqueuedEverything = false;
 
-  Enqueuer(this.name, this.compiler,
-           ItemCompilationContext itemCompilationContextCreator())
-    : this.itemCompilationContextCreator = itemCompilationContextCreator;
+  Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator);
 
   Queue<WorkItem> get queue;
 
@@ -104,7 +104,6 @@
    */
   void addToWorkList(Element element) {
     assert(invariant(element, element.isDeclaration));
-    if (element.isForeign(compiler)) return;
     internalAddToWorkList(element);
   }
 
@@ -614,7 +613,7 @@
     if (getCachedElements(element) != null) return;
     if (queueIsClosed) {
       throw new SpannableAssertionFailure(element,
-                                          "Resolution work list is closed.");
+          "Resolution work list is closed. Trying to add $element.");
     }
     compiler.world.registerUsedElement(element);
 
@@ -681,11 +680,14 @@
    * The action is performed as part of the post-processing immediately after
    * the resolution queue has been closed. As a consequence, [action] must not
    * add elements to the resolution queue.
+   *
+   * The queue is processed in FIFO order.
    */
   void addPostProcessAction(Element element, PostProcessAction action) {
     if (queueIsClosed) {
       throw new SpannableAssertionFailure(element,
-                                          "Resolution work list is closed.");
+          "Resolution work list is closed. "
+          "Trying to add post process action for $element");
     }
     postQueue.add(new PostProcessTask(element, action));
   }
@@ -720,13 +722,16 @@
       member.isAbstract(compiler) || generatedCode.containsKey(member);
 
   void internalAddToWorkList(Element element) {
+    // Don't generate code for foreign elements.
+    if (element.isForeign(compiler)) return;
+
     // Codegen inlines field initializers, so it does not need to add
     // individual fields in the work list.
     if (element.isField() && element.isInstanceMember()) return;
 
     if (queueIsClosed) {
       throw new SpannableAssertionFailure(element,
-                                          "Codegen work list is closed.");
+          "Codegen work list is closed. Trying to add $element");
     }
     CodegenWorkItem workItem = new CodegenWorkItem(
         element, itemCompilationContextCreator());
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart
index d491aa4..2325cd9 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart
@@ -2,17 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library container_tracer;
-
-import '../dart2jslib.dart' hide Selector, TypedSelector;
-import '../elements/elements.dart';
-import '../tree/tree.dart';
-import '../universe/universe.dart';
-import '../util/util.dart' show Link;
-import 'simple_types_inferrer.dart'
-    show InferrerEngine, InferrerVisitor, LocalsHandler, TypeMaskSystem;
-import '../types/types.dart';
-import 'inferrer_visitor.dart';
+part of type_graph_inferrer;
 
 /**
  * A set of selector names that [List] implements, that we know do not
@@ -136,672 +126,154 @@
 
 bool _VERBOSE = false;
 
-class InferrerEngineForContainerTracer
-    implements MinimalInferrerEngine<TypeMask> {
+class ContainerTracerVisitor implements TypeInformationVisitor {
+  final ContainerTypeInformation container;
+  final TypeGraphInferrerEngine inferrer;
   final Compiler compiler;
 
-  InferrerEngineForContainerTracer(this.compiler);
+  // The set of [TypeInformation] where the traced container could
+  // flow in, and operations done on them.
+  final Set<TypeInformation> allUsers = new Set<TypeInformation>();
 
-  TypeMask typeOfElement(Element element) {
-    return compiler.typesTask.getGuaranteedTypeOfElement(element);
-  }
+  // The list of found assignments to the container.
+  final List<TypeInformation> assignments = <TypeInformation>[];
 
-  TypeMask returnTypeOfElement(Element element) {
-    return compiler.typesTask.getGuaranteedReturnTypeOfElement(element);
-  }
-
-  TypeMask returnTypeOfSelector(Selector selector) {
-    return compiler.typesTask.getGuaranteedTypeOfSelector(selector);
-  }
-
-  TypeMask typeOfNode(Node node) {
-    return compiler.typesTask.getGuaranteedTypeOfNode(null, node);
-  }
-
-  Iterable<Element> getCallersOf(Element element) {
-    return compiler.typesTask.typesInferrer.getCallersOf(element);
-  }
-
-  void recordTypeOfNonFinalField(Node node,
-                                 Element field,
-                                 TypeMask type) {}
-}
-
-/**
- * Global analysis phase that traces container instantiations in order to
- * find their element type.
- */
-class ContainerTracer extends CompilerTask {
-  ContainerTracer(Compiler compiler) : super(compiler);
-
-  String get name => 'List tracer';
-
-  bool analyze() {
-    measure(() {
-      if (compiler.disableTypeInference) return;
-      TypesInferrer inferrer = compiler.typesTask.typesInferrer;
-      InferrerEngineForContainerTracer engine =
-          new InferrerEngineForContainerTracer(compiler);
-
-      // Walk over all created [ContainerTypeMask].
-      inferrer.containerTypes.forEach((ContainerTypeMask mask) {
-        // The element type has already been set for const containers.
-        if (mask.elementType != null) return;
-        new TracerForConcreteContainer(mask, this, compiler, engine).run();
-      });
-    });
-  }
-}
-
-/**
- * A tracer for a specific container.
- */
-class TracerForConcreteContainer {
-  final Compiler compiler;
-  final ContainerTracer tracer;
-  final InferrerEngineForContainerTracer inferrer;
-  final ContainerTypeMask mask;
-
-  final Node analyzedNode;
-  final Element startElement;
-
-  final List<Element> workList = <Element>[];
-
-  /**
-   * A set of elements where this list might escape.
-   */
-  final Set<Element> escapingElements = new Set<Element>();
-
-  /**
-   * A set of selectors that both use and update the list, for example
-   * [: list[0]++; :] or [: list[0] |= 42; :].
-   */
-  final Set<Selector> constraints = new Set<Selector>();
-
-  /**
-   * A cache of setters that were already seen. Caching these
-   * selectors avoid the filtering done in [addSettersToAnalysis].
-   */
-  final Set<Selector> seenSetterSelectors = new Set<Selector>();
-
-  static const int MAX_ANALYSIS_COUNT = 11;
-
-  TypeMask potentialType;
-  int potentialLength;
-  bool isLengthTrackingDisabled = false;
+  bool enableLengthTracking = true;
   bool continueAnalyzing = true;
 
-  TracerForConcreteContainer(ContainerTypeMask mask,
-                             this.tracer,
-                             this.compiler,
-                             this.inferrer)
-      : analyzedNode = mask.allocationNode,
-        startElement = mask.allocationElement,
-        this.mask = mask;
+  static const int MAX_ANALYSIS_COUNT = 11;
+  final Set<Element> analyzedElements = new Set<Element>();
+
+  ContainerTracerVisitor(this.container, inferrer)
+      : this.inferrer = inferrer, this.compiler = inferrer.compiler;
 
   void run() {
-    int analysisCount = 0;
-    workList.add(startElement);
+    // Add the assignments found at allocation site.
+    assignments.addAll(container.elementType.assignments);
+
+    // Collect the [TypeInformation] where the container can flow in,
+    // as well as the operations done on all these [TypeInformation]s.
+    List<TypeInformation> workList = <TypeInformation>[];
+    allUsers.add(container);
+    workList.add(container);
     while (!workList.isEmpty) {
-      if (workList.length + analysisCount > MAX_ANALYSIS_COUNT) {
+      TypeInformation user = workList.removeLast();
+      user.users.forEach((TypeInformation info) {
+        if (allUsers.contains(info)) return;
+        allUsers.add(info);
+        analyzedElements.add(info.owner);
+        if (info.reachedBy(user, inferrer)) {
+          workList.add(info);
+        }
+      });
+      if (analyzedElements.length > MAX_ANALYSIS_COUNT) {
         bailout('Too many users');
         break;
       }
-      Element currentElement = workList.removeLast().implementation;
-      new ContainerTracerVisitor(currentElement, this).run();
-      if (!continueAnalyzing) break;
-      analysisCount++;
     }
 
-    if (!continueAnalyzing) {
-      if (mask.forwardTo == compiler.typesTask.fixedListType) {
-        mask.length = potentialLength;
+    if (continueAnalyzing) {
+      for (TypeInformation info in allUsers) {
+        info.accept(this);
+        if (!continueAnalyzing) break;
       }
-      mask.elementType = compiler.typesTask.dynamicType;
-      return;
     }
 
-    // [potentialType] can be null if we did not find any instruction
-    // that adds elements to the list.
-    if (potentialType == null) {
-      if (_VERBOSE) {
-        print('Found empty type for $analyzedNode $startElement');
-      }
-      mask.elementType = new TypeMask.nonNullEmpty();
-      return;
+    ContainerTypeMask mask = container.type;
+    if (!enableLengthTracking
+        && (mask.forwardTo != compiler.typesTask.fixedListType)) {
+      mask.length = null;
     }
 
-    // Walk over the found constraints and update the type according
-    // to the selectors of these constraints.
-    for (Selector constraint in constraints) {
-      assert(constraint.isOperator());
-      constraint = new TypedSelector(potentialType, constraint);
-      potentialType = potentialType.union(
-          inferrer.returnTypeOfSelector(constraint), compiler);
-    }
+    TypeMask result = continueAnalyzing
+      ? inferrer.types.computeTypeMask(assignments)
+      : inferrer.types.dynamicType.type;
+
+    mask.elementType = result;
     if (_VERBOSE) {
-      print('$potentialType and $potentialLength '
-            'for $analyzedNode $startElement');
-    }
-    mask.elementType = potentialType;
-    mask.length = potentialLength;
-  }
-
-  void disableLengthTracking() {
-    if (mask.forwardTo == compiler.typesTask.fixedListType) {
-      // Bogus update to a fixed list.
-      return;
-    }
-    isLengthTrackingDisabled = true;
-    potentialLength = null;
-  }
-
-  void setPotentialLength(int value) {
-    if (isLengthTrackingDisabled) return;
-    potentialLength = value;
-  }
-
-  void unionPotentialTypeWith(TypeMask newType) {
-    assert(newType != null);
-    potentialType = potentialType == null
-        ? newType
-        : newType.union(potentialType, compiler);
-    if (potentialType == compiler.typesTask.dynamicType) {
-      bailout('Moved to dynamic');
+      print('$result and ${mask.length} '
+            'for ${mask.allocationNode} ${mask.allocationElement}');
     }
   }
 
-  void addEscapingElement(element) {
-    element = element.implementation;
-    if (escapingElements.contains(element)) return;
-    escapingElements.add(element);
-    if (element.isField() || element.isGetter() || element.isFunction()) {
-      for (Element e in inferrer.getCallersOf(element)) {
-        addElementToAnalysis(e);
-      }
-    } else if (element.isParameter()) {
-      addElementToAnalysis(element.enclosingElement);
-    } else if (element.isFieldParameter()) {
-      addEscapingElement(element.fieldElement);
-    }
-  }
-
-  void addSettersToAnalysis(Selector selector) {
-    assert(selector.isSetter());
-    if (seenSetterSelectors.contains(selector)) return;
-    seenSetterSelectors.add(selector);
-    for (var e in compiler.world.allFunctions.filter(selector)) {
-      e = e.implementation;
-      if (e.isField()) {
-        addEscapingElement(e);
-      } else {
-        FunctionSignature signature = e.computeSignature(compiler);
-        signature.forEachRequiredParameter((Element e) {
-          addEscapingElement(e);
-        });
-      }
-    }
-  }
-
-  void addElementToAnalysis(Element element) {
-    workList.add(element);
-  }
-
-  TypeMask bailout(String reason) {
+  void bailout(String reason) {
     if (_VERBOSE) {
-      print('Bailout on $analyzedNode $startElement because of $reason');
+      ContainerTypeMask mask = container.type;
+      print('Bailing out on ${mask.allocationNode} ${mask.allocationElement} '
+            'because: $reason');
     }
     continueAnalyzing = false;
-    return compiler.typesTask.dynamicType;
+    enableLengthTracking = false;
   }
 
-  bool couldBeTheList(resolved) {
-    if (resolved is Selector) {
-      return escapingElements.any((e) {
-        return e.isInstanceMember() && resolved.applies(e, compiler);
-      });
-    } else if (resolved is Node) {
-      return analyzedNode == resolved;
-    } else {
-      assert(resolved is Element);
-      return escapingElements.contains(resolved);
+  visitNarrowTypeInformation(NarrowTypeInformation info) {}
+  visitPhiElementTypeInformation(PhiElementTypeInformation info) {}
+  visitElementInContainerTypeInformation(
+      ElementInContainerTypeInformation info) {}
+  visitContainerTypeInformation(ContainerTypeInformation info) {}
+  visitConcreteTypeInformation(ConcreteTypeInformation info) {}
+
+  visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
+    bailout('Passed to a closure');
+  }
+
+  visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
+    analyzedElements.add(info.caller);
+    Element called = info.calledElement;
+    if (called.isForeign(compiler) && called.name == const SourceString('JS')) {
+      bailout('Used in JS ${info.call}');
     }
   }
 
-  void recordConstraint(Selector selector) {
-    constraints.add(selector);
-  }
-}
-
-class ContainerTracerVisitor
-    extends InferrerVisitor<TypeMask, InferrerEngineForContainerTracer> {
-  final Element analyzedElement;
-  final TracerForConcreteContainer tracer;
-  final bool visitingClosure;
-
-  ContainerTracerVisitor(element, tracer, [LocalsHandler<TypeMask> locals])
-      : super(element, tracer.inferrer, new TypeMaskSystem(tracer.compiler),
-              tracer.compiler, locals),
-        this.analyzedElement = element,
-        this.tracer = tracer,
-        visitingClosure = locals != null;
-
-  bool escaping = false;
-  bool visitingInitializers = false;
-
-  void run() {
-    compiler.withCurrentElement(analyzedElement, () {
-      visit(analyzedElement.parseNode(compiler));
-    });
-  }
-
-  /**
-   * Executes [f] and returns whether it triggered the list to escape.
-   */
-  bool visitAndCatchEscaping(Function f) {
-    bool oldEscaping = escaping;
-    escaping = false;
-    f();
-    bool foundEscaping = escaping;
-    escaping = oldEscaping;
-    return foundEscaping;
-  }
-
-  /**
-   * Visits the [arguments] of [callee], and records the parameters
-   * that could hold the container as escaping.
-   *
-   * Returns whether the container escaped.
-   */
-  bool visitArguments(Link<Node> arguments, /* Element or Selector */ callee) {
-    List<int> indices = [];
-    int index = 0;
-    for (Node node in arguments) {
-      if (visitAndCatchEscaping(() { visit(node); })) {
-        indices.add(index);
-      }
-      index++;
-    }
-    if (!indices.isEmpty) {
-      Iterable<Element> callees;
-      if (callee is Element) {
-        // No need to go further, we know the call will throw.
-        if (callee.isErroneous()) return false;
-        callees = [callee];
-      } else {
-        assert(callee is Selector);
-        callees = compiler.world.allFunctions.filter(callee);
-      }
-      for (var e in callees) {
-        e = e.implementation;
-        if (e.isField()) {
-          tracer.bailout('Passed to a closure');
-          break;
-        }
-        FunctionSignature signature = e.computeSignature(compiler);
-        index = 0;
-        int parameterIndex = 0;
-        signature.forEachRequiredParameter((Element parameter) {
-          if (index < indices.length && indices[index] == parameterIndex) {
-            tracer.addEscapingElement(parameter);
-            index++;
-          }
-          parameterIndex++;
-        });
-        if (index != indices.length) {
-          tracer.bailout('Used in a named parameter or closure');
-        }
-      }
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  TypeMask visitFunctionExpression(FunctionExpression node) {
-    FunctionElement function = elements[node];
-    if (function != analyzedElement) {
-      // Visiting a closure.
-      LocalsHandler closureLocals = new LocalsHandler<TypeMask>.from(
-          locals, node, useOtherTryBlock: false);
-      new ContainerTracerVisitor(function, tracer, closureLocals).run();
-      return types.functionType;
-    } else {
-      // Visiting [analyzedElement].
-      FunctionSignature signature = function.computeSignature(compiler);
-      signature.forEachParameter((element) {
-        locals.update(element, inferrer.typeOfElement(element), node);
-      });
-      visitingInitializers = true;
-      visit(node.initializers);
-      visitingInitializers = false;
-      visit(node.body);
-      return null;
-    }
-  }
-
-  TypeMask visitLiteralList(LiteralList node) {
-    if (node.isConst()) {
-      return inferrer.typeOfNode(node);
-    }
-    if (tracer.couldBeTheList(node)) {
-      escaping = true;
-      int length = 0;
-      for (Node element in node.elements.nodes) {
-        tracer.unionPotentialTypeWith(visit(element));
-        length++;
-      }
-      tracer.setPotentialLength(length);
-    } else {
-      node.visitChildren(this);
-    }
-    return types.growableListType;
-  }
-
-  TypeMask visitSendSet(SendSet node) {
-    bool isReceiver = visitAndCatchEscaping(() {
-      visit(node.receiver);
-    });
-    return handleSendSet(node, isReceiver);
-  }
-
-  TypeMask handleSendSet(SendSet node, bool isReceiver) {
-    TypeMask rhsType;
-    TypeMask indexType;
-
-    Selector getterSelector =
-        elements.getGetterSelectorInComplexSendSet(node);
-    Selector operatorSelector =
-        elements.getOperatorSelectorInComplexSendSet(node);
-    Selector setterSelector = elements.getSelector(node);
-
-    String op = node.assignmentOperator.source.stringValue;
-    bool isIncrementOrDecrement = op == '++' || op == '--';
-    bool isIndexEscaping = false;
-    bool isValueEscaping = false;
-    if (isIncrementOrDecrement) {
-      rhsType = types.intType;
-      if (node.isIndex) {
-        isIndexEscaping = visitAndCatchEscaping(() {
-          indexType = visit(node.arguments.head);
-        });
-      }
-    } else if (node.isIndex) {
-      isIndexEscaping = visitAndCatchEscaping(() {
-        indexType = visit(node.arguments.head);
-      });
-      isValueEscaping = visitAndCatchEscaping(() {
-        rhsType = visit(node.arguments.tail.head);
-      });
-    } else {
-      isValueEscaping = visitAndCatchEscaping(() {
-        rhsType = visit(node.arguments.head);
-      });
-    }
-
-    Element element = elements[node];
-
-    if (node.isIndex) {
-      if (isReceiver) {
-        if (op == '=') {
-          tracer.unionPotentialTypeWith(rhsType);
-        } else {
-          tracer.recordConstraint(operatorSelector);
-        }
-      } else if (isIndexEscaping || isValueEscaping) {
-        // If the index or value is escaping, iterate over all
-        // potential targets, and mark their parameter as escaping.
-        for (var e in compiler.world.allFunctions.filter(setterSelector)) {
-          e = e.implementation;
-          FunctionSignature signature = e.computeSignature(compiler);
-          int index = 0;
-          signature.forEachRequiredParameter((Element parameter) {
-            if (index == 0 && isIndexEscaping) {
-              tracer.addEscapingElement(parameter);
-            }
-            if (index == 1 && isValueEscaping) {
-              tracer.addEscapingElement(parameter);
-            }
-            index++;
-          });
-        }
-      }
-    } else if (isReceiver) {
-      if (setterSelector.name == const SourceString('length')) {
-        tracer.disableLengthTracking();
-        tracer.unionPotentialTypeWith(compiler.typesTask.nullType);
-      }
-    } else if (isValueEscaping) {
-      if (element != null
-          && element.isField()
-          && setterSelector == null
-          && !visitingInitializers) {
-        // Initializer at declaration of a field.
-        assert(analyzedElement.isField());
-        tracer.addEscapingElement(analyzedElement);
-      } else if (element != null
-                  && (!element.isInstanceMember() || visitingInitializers)) {
-        // A local, a static element, or a field in an initializer.
-        tracer.addEscapingElement(element);
-      } else {
-        tracer.addSettersToAnalysis(setterSelector);
-      }
-    }
-
-    TypeMask result;
-    if (node.isPostfix) {
-      // We don't check if [getterSelector] could be the container because
-      // a list++ will always throw.
-      result = inferrer.returnTypeOfSelector(getterSelector);
-    } else if (op != '=') {
-      // We don't check if [getterSelector] could be the container because
-      // a list += 42 will always throw.
-      result = inferrer.returnTypeOfSelector(operatorSelector);
-    } else {
-      if (isValueEscaping) {
-        escaping = true;
-      }
-      result = rhsType;
-    }
-
-    if (Elements.isLocal(element)) {
-      locals.update(element, result, node);
-    }
-
-    return result;
-  }
-
-  TypeMask visitSuperSend(Send node) {
-    Element element = elements[node];
-    if (!node.isPropertyAccess) {
-      visitArguments(node.arguments, element);
-    }
-
-    if (tracer.couldBeTheList(element)) {
-      escaping = true;
-    }
-
-    if (element.isField()) {
-      return inferrer.typeOfElement(element);
-    } else if (element.isFunction()) {
-      return inferrer.returnTypeOfElement(element);
-    } else {
-      return types.dynamicType;
-    }
-  }
-
-  TypeMask visitStaticSend(Send node) {
-    Element element = elements[node];
-
-    if (Elements.isGrowableListConstructorCall(element, node, compiler)) {
-      visitArguments(node.arguments, element);
-      if (tracer.couldBeTheList(node)) {
-        escaping = true;
-      }
-      return inferrer.typeOfNode(node);
-    } else if (Elements.isFixedListConstructorCall(element, node, compiler)) {
-      visitArguments(node.arguments, element);
-      if (tracer.couldBeTheList(node)) {
-        tracer.unionPotentialTypeWith(types.nullType);
-        escaping = true;
-        LiteralInt length = node.arguments.head.asLiteralInt();
-        if (length != null) {
-          tracer.setPotentialLength(length.value);
-        }
-      }
-      return inferrer.typeOfNode(node);
-    } else if (Elements.isFilledListConstructorCall(element, node, compiler)) {
-      if (tracer.couldBeTheList(node)) {
-        escaping = true;
-        visit(node.arguments.head);
-        TypeMask fillWithType = visit(node.arguments.tail.head);
-        tracer.unionPotentialTypeWith(fillWithType);
-        LiteralInt length = node.arguments.head.asLiteralInt();
-        if (length != null) {
-          tracer.setPotentialLength(length.value);
-        }
-      } else {
-        visitArguments(node.arguments, element);
-      }
-      return inferrer.typeOfNode(node);
-    }
-
-    bool isEscaping = visitArguments(node.arguments, element);
-
-    if (element.isForeign(compiler)) {
-      if (isEscaping) return tracer.bailout('Used in a JS');
-    }
-
-    if (tracer.couldBeTheList(element)) {
-      escaping = true;
-    }
-
-    if (element.isFunction() || element.isConstructor()) {
-      return inferrer.returnTypeOfElement(element);
-    } else {
-      // Closure call or unresolved.
-      return types.dynamicType;
-    }
-  }
-
-  TypeMask visitGetterSend(Send node) {
-    Element element = elements[node];
-    Selector selector = elements.getSelector(node);
-    if (Elements.isStaticOrTopLevelField(element)) {
-      if (tracer.couldBeTheList(element)) {
-        escaping = true;
-      }
-      return inferrer.typeOfElement(element);
-    } else if (Elements.isInstanceSend(node, elements)) {
-      return visitDynamicSend(node);
-    } else if (Elements.isStaticOrTopLevelFunction(element)) {
-      return types.functionType;
-    } else if (Elements.isErroneousElement(element)) {
-      return types.dynamicType;
-    } else if (Elements.isLocal(element)) {
-      if (tracer.couldBeTheList(element)) {
-        escaping = true;
-      }
-      return locals.use(element);
-    } else {
-      node.visitChildren(this);
-      return types.dynamicType;
-    }
-  }
-
-  TypeMask visitClosureSend(Send node) {
-    assert(node.receiver == null);
-    visit(node.selector);
-    bool isEscaping =
-        visitArguments(node.arguments, elements.getSelector(node));
-
-    if (isEscaping) return tracer.bailout('Passed to a closure');
-    return types.dynamicType;
-  }
-
-  TypeMask visitDynamicSend(Send node) {
-    bool isReceiver = visitAndCatchEscaping(() {
-      visit(node.receiver);
-    });
-    return handleDynamicSend(node, isReceiver);
-  }
-
-  TypeMask handleDynamicSend(Send node, bool isReceiver) {
-    Selector selector = elements.getSelector(node);
+  visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
+    Selector selector = info.selector;
     String selectorName = selector.name.slowToString();
-    if (isReceiver && !okSelectorsSet.contains(selectorName)) {
-      if (selector.isCall()
-          && (selectorName == 'add' || selectorName == 'insert')) {
-        TypeMask argumentType;
-        if (node.arguments.isEmpty
-            || (selectorName == 'insert' && node.arguments.tail.isEmpty)) {
-          return tracer.bailout('Invalid "add" or "insert" call on a list');
-        }
-        bool isEscaping = visitAndCatchEscaping(() {
-          argumentType = visit(node.arguments.head);
-          if (selectorName == 'insert') {
-            argumentType = visit(node.arguments.tail.head);
+    if (allUsers.contains(info.receiver)) {
+      if (!okSelectorsSet.contains(selectorName)) {
+        if (selector.isCall()) {
+          int positionalLength = info.arguments.positional.length;
+          if (selectorName == 'add') {
+            if (positionalLength == 1) {
+              assignments.add(info.arguments.positional[0]);
+            }
+          } else if (selectorName == 'insert') {
+            if (positionalLength == 2) {
+              assignments.add(info.arguments.positional[1]);
+            }
+          } else {
+            bailout('Used in a not-ok selector');
+            return;
           }
-        });
-        if (isEscaping) {
-          return tracer.bailout('List containing itself');
+        } else if (selector.isIndexSet()) {
+          assignments.add(info.arguments.positional[1]);
+        } else if (!selector.isIndex()) {
+          bailout('Used in a not-ok selector');
+          return;
         }
-        tracer.unionPotentialTypeWith(argumentType);
-      } else {
-        return tracer.bailout('Send with the node as receiver $node');
       }
-    } else if (!node.isPropertyAccess) {
-      visitArguments(node.arguments, selector);
+      if (!doNotChangeLengthSelectorsSet.contains(selectorName)) {
+        enableLengthTracking = false;
+      }
+      if (selectorName == 'length' && selector.isSetter()) {
+        enableLengthTracking = false;
+        assignments.add(inferrer.types.nullType);
+      }
+    } else if (selector.isCall()
+               && !info.targets.every((element) => element.isFunction())) {
+      bailout('Passed to a closure');
+      return;
     }
-    if (isReceiver && !doNotChangeLengthSelectorsSet.contains(selectorName)) {
-      tracer.disableLengthTracking();
-    }
-    if (tracer.couldBeTheList(selector)) {
-      escaping = true;
-    }
-    return inferrer.returnTypeOfSelector(selector);
   }
 
-  TypeMask visitReturn(Return node) {
-    if (node.expression == null) {
-      return types.nullType;
-    }
-
-    TypeMask type;
-    bool isEscaping = visitAndCatchEscaping(() {
-      type = visit(node.expression);
-    });
-
-    if (isEscaping) {
-      if (visitingClosure) {
-        tracer.bailout('Return from closure');
-      } else {
-        tracer.addEscapingElement(analyzedElement);
-      }
-    }
-    return type;
+  bool isClosure(Element element) {
+    if (!element.isFunction()) return false;
+    Element outermost = element.getOutermostEnclosingMemberOrTopLevel();
+    return outermost.declaration != element.declaration;
   }
 
-  TypeMask visitForIn(ForIn node) {
-    visit(node.expression);
-    Selector iteratorSelector = elements.getIteratorSelector(node);
-    Selector currentSelector = elements.getCurrentSelector(node);
-
-    TypeMask iteratorType = inferrer.returnTypeOfSelector(iteratorSelector);
-    TypeMask currentType = inferrer.returnTypeOfSelector(currentSelector);
-
-    // We nullify the type in case there is no element in the
-    // iterable.
-    currentType = currentType.nullable();
-
-    Node identifier = node.declaredIdentifier;
-    Element element = elements[identifier];
-    if (Elements.isLocal(element)) {
-      locals.update(element, currentType, node);
+  visitElementTypeInformation(ElementTypeInformation info) {
+    if (isClosure(info.element)) {
+      bailout('Returned from a closure');
     }
-
-    return handleLoop(node, () {
-      visit(node.body);
-    });
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart b/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
index bc58690..2a9d49b 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
@@ -31,10 +31,11 @@
   T get stringType;
   T get typeType;
 
-  T nonNullSubtype(DartType type);
-  T nonNullSubclass(DartType type);
-  T nonNullExact(DartType type);
+  T nonNullSubtype(ClassElement type);
+  T nonNullSubclass(ClassElement type);
+  T nonNullExact(ClassElement type);
   T nonNullEmpty();
+  bool isNull(T type);
   Selector newTypedSelector(T receiver, Selector selector);
 
   T allocateContainer(T type,
@@ -680,7 +681,7 @@
     // TODO(kasperl): We should be able to tell that the type of a literal
     // symbol is always a non-null exact symbol implementation -- not just
     // any non-null subtype of the symbol interface.
-    return types.nonNullSubtype(compiler.symbolClass.rawType);
+    return types.nonNullSubtype(compiler.symbolClass);
   }
 
   T visitTypeReferenceSend(Send node) {
@@ -701,11 +702,11 @@
     if (_thisType != null) return _thisType;
     ClassElement cls = outermostElement.getEnclosingClass();
     if (compiler.world.isUsedAsMixin(cls)) {
-      return _thisType = types.nonNullSubtype(cls.rawType);
+      return _thisType = types.nonNullSubtype(cls);
     } else if (compiler.world.hasAnySubclass(cls)) {
-      return _thisType = types.nonNullSubclass(cls.rawType);
+      return _thisType = types.nonNullSubclass(cls);
     } else {
-      return _thisType = types.nonNullExact(cls.rawType);
+      return _thisType = types.nonNullExact(cls);
     }
   }
 
@@ -713,7 +714,7 @@
   T get superType {
     if (_superType != null) return _superType;
     return _superType = types.nonNullExact(
-        outermostElement.getEnclosingClass().superclass.rawType);
+        outermostElement.getEnclosingClass().superclass);
   }
 
   T visitIdentifier(Identifier node) {
@@ -730,20 +731,54 @@
     isChecks.add(node);
   }
 
+  void potentiallyAddNullCheck(Send node, Node receiver) {
+    if (!accumulateIsChecks) return;
+    if (!Elements.isLocal(elements[receiver])) return;
+    isChecks.add(node);
+  }
+
   void updateIsChecks(List<Node> tests, {bool usePositive}) {
-    if (tests == null) return;
-    for (Send node in tests) {
-      if (node.isIsNotCheck) {
-        if (usePositive) continue;
-      } else {
-        if (!usePositive) continue;
-      }
-      DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
-      Element element = elements[node.receiver];
+    void narrow(Element element, DartType type, Node node) {
       T existing = locals.use(element);
       T newType = types.narrowType(existing, type, isNullable: false);
       locals.update(element, newType, node);
     }
+
+    if (tests == null) return;
+    for (Send node in tests) {
+      if (node.isTypeTest) {
+        if (node.isIsNotCheck) {
+          if (usePositive) continue;
+        } else {
+          if (!usePositive) continue;
+        }
+        DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
+        narrow(elements[node.receiver], type, node);
+      } else {
+        Element receiverElement = elements[node.receiver];
+        Element argumentElement = elements[node.arguments.first];
+        String operator = node.selector.asOperator().source.stringValue;
+        if ((operator == '==' && usePositive)
+            || (operator == '!=' && !usePositive)) {
+          // Type the elements as null.
+          if (Elements.isLocal(receiverElement)) {
+            locals.update(receiverElement, types.nullType, node);
+          }
+          if (Elements.isLocal(argumentElement)) {
+            locals.update(argumentElement, types.nullType, node);
+          }
+        } else {
+          // Narrow the elements to a non-null type.
+          DartType objectType = compiler.objectClass.rawType;
+          if (Elements.isLocal(receiverElement)) {
+            narrow(receiverElement, objectType, node);
+          }
+          if (Elements.isLocal(argumentElement)) {
+            narrow(argumentElement, objectType, node);
+          }
+        }
+      }
+    }
   }
 
   T visitOperatorSend(Send node) {
@@ -979,7 +1014,7 @@
       DartType type = elements.getType(node.type);
       T mask = type == null || type.treatAsDynamic
           ? types.dynamicType
-          : types.nonNullSubtype(type.asRaw());
+          : types.nonNullSubtype(type.element);
       locals.update(elements[exception], mask, node);
     }
     Node trace = node.trace;
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
index 6cdbd1f..932eb33 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
@@ -44,7 +44,7 @@
       return type;
     } else {
       assert(annotation.kind == TypeKind.INTERFACE);
-      otherType = new TypeMask.nonNullSubtype(annotation);
+      otherType = new TypeMask.nonNullSubtype(annotation.element);
     }
     if (isNullable) otherType = otherType.nullable();
     if (type == null) return otherType;
@@ -85,10 +85,14 @@
   TypeMask get constMapType => compiler.typesTask.constMapType;
   TypeMask get stringType => compiler.typesTask.stringType;
   TypeMask get typeType => compiler.typesTask.typeType;
+  bool isNull(TypeMask mask) => mask.isEmpty && mask.isNullable;
 
-  TypeMask nonNullSubtype(DartType type) => new TypeMask.nonNullSubtype(type);
-  TypeMask nonNullSubclass(DartType type) => new TypeMask.nonNullSubclass(type);
-  TypeMask nonNullExact(DartType type) => new TypeMask.nonNullExact(type);
+  TypeMask nonNullSubtype(ClassElement type)
+      => new TypeMask.nonNullSubtype(type.declaration);
+  TypeMask nonNullSubclass(ClassElement type)
+      => new TypeMask.nonNullSubclass(type.declaration);
+  TypeMask nonNullExact(ClassElement type)
+      => new TypeMask.nonNullExact(type.declaration);
   TypeMask nonNullEmpty() => new TypeMask.nonNullEmpty();
 
   TypeMask allocateContainer(TypeMask type,
@@ -296,7 +300,7 @@
     for (var type in typesReturned) {
       T mappedType;
       if (type == native.SpecialType.JsObject) {
-        mappedType = types.nonNullExact(compiler.objectClass.rawType);
+        mappedType = types.nonNullExact(compiler.objectClass);
       } else if (type.element == compiler.stringClass) {
         mappedType = types.stringType;
       } else if (type.element == compiler.intClass) {
@@ -314,15 +318,15 @@
       } else if (type.isDynamic) {
         return types.dynamicType;
       } else if (!compiler.world.hasAnySubtype(type.element)) {
-        mappedType = types.nonNullExact(type.element.rawType);
+        mappedType = types.nonNullExact(type.element);
       } else {
         ClassElement element = type.element;
         Set<ClassElement> subtypes = compiler.world.subtypesOf(element);
         Set<ClassElement> subclasses = compiler.world.subclassesOf(element);
         if (subclasses != null && subtypes.length == subclasses.length) {
-          mappedType = types.nonNullSubclass(element.rawType);
+          mappedType = types.nonNullSubclass(element);
         } else {
-          mappedType = types.nonNullSubtype(element.rawType);
+          mappedType = types.nonNullSubtype(element);
         }
       }
       returnType = types.computeLUB(returnType, mappedType);
@@ -474,7 +478,7 @@
           }
         });
       }
-      returnType = types.nonNullExact(cls.rawType);
+      returnType = types.nonNullExact(cls);
     } else {
       signature.forEachParameter((element) {
         locals.update(element, inferrer.typeOfElement(element), node);
@@ -535,38 +539,31 @@
   }
 
   T visitLiteralList(LiteralList node) {
-    if (node.isConst()) {
-      // We only set the type once. We don't need to re-visit the children
-      // when re-analyzing the node.
-      return inferrer.concreteTypes.putIfAbsent(node, () {
-        T elementType;
-        int length = 0;
-        for (Node element in node.elements.nodes) {
-          T type = visit(element);
-          elementType = elementType == null
-              ? types.allocatePhi(null, null, type)
-              : types.addPhiInput(null, elementType, type);
-          length++;
-        }
+    // We only set the type once. We don't need to re-visit the children
+    // when re-analyzing the node.
+    return inferrer.concreteTypes.putIfAbsent(node, () {
+      T elementType;
+      int length = 0;
+      for (Node element in node.elements.nodes) {
+        T type = visit(element);
         elementType = elementType == null
-            ? types.nonNullEmpty()
-            : types.simplifyPhi(null, null, elementType);
-        return types.allocateContainer(
-            types.constListType,
-            node,
-            outermostElement,
-            elementType,
-            length);
-      });
-    } else {
-      node.visitChildren(this);
-      return inferrer.concreteTypes.putIfAbsent(node, () {
-        return types.allocateContainer(
-            types.growableListType,
-            node,
-            outermostElement);
-      });
-    }
+            ? types.allocatePhi(null, null, type)
+            : types.addPhiInput(null, elementType, type);
+        length++;
+      }
+      elementType = elementType == null
+          ? types.nonNullEmpty()
+          : types.simplifyPhi(null, null, elementType);
+      T containerType = node.isConst()
+          ? types.constListType
+          : types.growableListType;
+      return types.allocateContainer(
+          containerType,
+          node,
+          outermostElement,
+          elementType,
+          length);
+    });
   }
 
   bool isThisOrSuper(Node node) => node.isThis() || node.isSuper();
@@ -823,12 +820,31 @@
     if (Elements.isGrowableListConstructorCall(element, node, compiler)) {
       return inferrer.concreteTypes.putIfAbsent(
           node, () => types.allocateContainer(
-              types.growableListType, node, outermostElement));
+              types.growableListType, node, outermostElement,
+              types.nonNullEmpty(), 0));
     } else if (Elements.isFixedListConstructorCall(element, node, compiler)
         || Elements.isFilledListConstructorCall(element, node, compiler)) {
+
+      int initialLength;
+      T elementType;
+      if (Elements.isFixedListConstructorCall(element, node, compiler)) {
+        LiteralInt length = node.arguments.head.asLiteralInt();
+        if (length != null) {
+          initialLength = length.value;
+        }
+        elementType = types.nullType;
+      } else {
+        LiteralInt length = node.arguments.head.asLiteralInt();
+        if (length != null) {
+          initialLength = length.value;
+        }
+        elementType = arguments.positional[1];
+      }
+
       return inferrer.concreteTypes.putIfAbsent(
           node, () => types.allocateContainer(
-              types.fixedListType, node, outermostElement));
+              types.fixedListType, node, outermostElement,
+              elementType, initialLength));
     } else if (element.isFunction() || element.isConstructor()) {
       return returnType;
     } else {
@@ -983,6 +999,16 @@
     ArgumentsTypes arguments = node.isPropertyAccess
         ? null
         : analyzeArguments(node.arguments);
+    if (selector.name == const SourceString('==')
+        || selector.name == const SourceString('!=')) {
+      if (types.isNull(receiverType)) {
+        potentiallyAddNullCheck(node, node.arguments.head);
+        return types.boolType;
+      } else if (types.isNull(arguments.positional[0])) {
+        potentiallyAddNullCheck(node, node.receiver);
+        return types.boolType;
+      }
+    }
     return handleDynamicSend(node, selector, receiverType, arguments);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
index fc8e211..2eb6270 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
@@ -7,7 +7,7 @@
 import 'dart:collection' show Queue, LinkedHashSet, IterableBase, HashMap;
 import '../dart_types.dart' show DartType, InterfaceType, TypeKind;
 import '../elements/elements.dart';
-import '../tree/tree.dart' show Node;
+import '../tree/tree.dart' show LiteralList, Node;
 import '../types/types.dart' show TypeMask, ContainerTypeMask, TypesInferrer;
 import '../universe/universe.dart' show Selector, TypedSelector, SideEffects;
 import '../dart2jslib.dart' show Compiler, SourceString, TreeElementMapping;
@@ -18,27 +18,28 @@
 import '../dart2jslib.dart' show invariant;
 
 part 'type_graph_nodes.dart';
+part 'container_tracer.dart';
 
 /**
  * A set of selector names that [List] implements, that we know return
  * their element type.
  */
-Set<String> returnsElementTypeSet = new Set<String>.from(
-  const <String>[
-    'first',
-    'last',
-    'single',
-    'singleWhere',
-    'elementAt',
-    '[]',
-    'removeAt',
-    'removeLast'
+Set<Selector> returnsElementTypeSet = new Set<Selector>.from(
+  <Selector>[
+    new Selector.getter(const SourceString('first'), null),
+    new Selector.getter(const SourceString('last'), null),
+    new Selector.getter(const SourceString('single'), null),
+    new Selector.call(const SourceString('singleWhere'), null, 1),
+    new Selector.call(const SourceString('elementAt'), null, 1),
+    new Selector.index(),
+    new Selector.call(const SourceString('removeAt'), null, 1),
+    new Selector.call(const SourceString('removeLast'), null, 0)
   ]);
 
 bool returnsElementType(Selector selector) {
   return (selector.mask != null)
          && selector.mask.isContainer
-         && returnsElementTypeSet.contains(selector.name.slowToString());
+         && returnsElementTypeSet.contains(selector.asUntyped);
 }
 
 class TypeInformationSystem extends TypeSystem<TypeInformation> {
@@ -203,7 +204,7 @@
       return type;
     } else {
       assert(annotation.kind == TypeKind.INTERFACE);
-      otherType = new TypeMask.nonNullSubtype(annotation);
+      otherType = new TypeMask.nonNullSubtype(annotation.element);
     }
     if (isNullable) otherType = otherType.nullable();
     if (type.type.isExact) {
@@ -228,28 +229,36 @@
     });
   }
 
-  TypeInformation nonNullSubtype(DartType type) {
-    return getConcreteTypeFor(new TypeMask.nonNullSubtype(type));
+  TypeInformation nonNullSubtype(ClassElement type) {
+    return getConcreteTypeFor(new TypeMask.nonNullSubtype(type.declaration));
   }
 
-  TypeInformation nonNullSubclass(DartType type) {
-    return getConcreteTypeFor(new TypeMask.nonNullSubclass(type));
+  TypeInformation nonNullSubclass(ClassElement type) {
+    return getConcreteTypeFor(new TypeMask.nonNullSubclass(type.declaration));
   }
 
-  TypeInformation nonNullExact(DartType type) {
-    return getConcreteTypeFor(new TypeMask.nonNullExact(type));
+  TypeInformation nonNullExact(ClassElement type) {
+    return getConcreteTypeFor(new TypeMask.nonNullExact(type.declaration));
   }
 
   TypeInformation nonNullEmpty() {
     return nonNullEmptyType;
   }
 
+  bool isNull(TypeInformation type) {
+    return type == nullType;
+  }
+
   TypeInformation allocateContainer(TypeInformation type,
                                     Node node,
                                     Element enclosing,
                                     [TypeInformation elementType, int length]) {
     ContainerTypeMask mask = new ContainerTypeMask(type.type, node, enclosing);
-    mask.elementType = elementType == null ? null : elementType.type;
+    // Set the element type now for const lists, so that the inferrer
+    // can use it.
+    mask.elementType = (type.type == compiler.typesTask.constListType)
+        ? elementType.type
+        : null;
     mask.length = length;
     TypeInformation element =
         new ElementInContainerTypeInformation(elementType, mask);
@@ -388,7 +397,7 @@
         compiler.log('Added $addedInGraph elements in inferencing graph.');
         compiler.progress.reset();
       }
-      // Force the creation of the [ElementTypeInformation] to ensure it is 
+      // Force the creation of the [ElementTypeInformation] to ensure it is
       // in the graph.
       types.getInferredTypeOf(element);
 
@@ -460,6 +469,7 @@
     }
 
     processLoopInformation();
+    types.allocatedContainers.values.forEach(analyzeContainer);
   }
 
   void processLoopInformation() {
@@ -498,6 +508,11 @@
     }
   }
 
+  void analyzeContainer(ContainerTypeInformation info) {
+    if (info.elementType.isInConstContainer) return;
+    new ContainerTracerVisitor(info, this).run();
+  }
+
   void buildWorkQueue() {
     workQueue.addAll(types.typeInformations.values);
     workQueue.addAll(types.allocatedTypes);
@@ -506,7 +521,7 @@
 
   /**
    * Update the assignments to parameters in the graph. [remove] tells
-   * wheter assignments must be added or removed. If [init] is true,
+   * wheter assignments must be added or removed. If [init] is false,
    * parameters are added to the work queue.
    */
   void updateParameterAssignments(TypeInformation caller,
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
index fc7bfb5..539db8a 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
@@ -48,7 +48,7 @@
   TypeInformation([users, assignments])
       : users = (users == null) ? new Set<TypeInformation>() : users,
         assignments = (assignments == null) ? <TypeInformation>[] : assignments;
-      
+
 
   void addUser(TypeInformation user) {
     assert(!user.isConcrete);
@@ -61,10 +61,14 @@
   }
 
   void addAssignment(TypeInformation assignment) {
-    if (abandonInferencing) return;
     // Cheap one-level cycle detection.
     if (assignment == this) return;
-    assignments.add(assignment);
+    if (!abandonInferencing) {
+      assignments.add(assignment);
+    }
+    // Even if we abandon inferencing on this [TypeInformation] we
+    // need to collect the users, so that phases that track where
+    // elements flow in still work.
     assignment.addUser(this);
   }
 
@@ -92,6 +96,17 @@
     assignments = const <TypeInformation>[];
     users = const <TypeInformation>[];
   }
+
+  bool reachedBy(TypeInformation info, TypeGraphInferrerEngine inferrer) {
+    return true;
+  }
+
+  accept(TypeInformationVisitor visitor);
+
+  /// The [Element] where this [TypeInformation] was created. May be
+  /// for some [TypeInformation] nodes, where we do not need to store
+  /// the information.
+  Element get owner => null;
 }
 
 /**
@@ -157,7 +172,7 @@
  * - Native functions and fields: because native methods contain no Dart
  *   code, and native fields do not have Dart assignments, we just
  *   trust their type annotation.
- *   
+ *
  */
 class ElementTypeInformation extends TypeInformation {
   final Element element;
@@ -227,7 +242,7 @@
         InterfaceType rawType = element.computeType(inferrer.compiler).asRaw();
         return rawType.treatAsDynamic
             ? inferrer.types.dynamicType.type
-            : new TypeMask.subtype(rawType);
+            : new TypeMask.subtype(rawType.element);
       } else {
         assert(element.isFunction()
                || element.isGetter()
@@ -268,6 +283,12 @@
   }
 
   String toString() => 'Element $element $type';
+
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitElementTypeInformation(this);
+  }
+
+  Element get owner => element.getOutermostEnclosingMemberOrTopLevel();
 }
 
 /**
@@ -301,6 +322,8 @@
 
   /// Return an iterable over the targets of this call.
   Iterable<Element> get callees;
+
+  Element get owner => caller;
 }
 
 class StaticCallSiteTypeInformation extends CallSiteTypeInformation {
@@ -344,6 +367,14 @@
   }
 
   Iterable<Element> get callees => [calledElement.implementation];
+
+  bool reachedBy(TypeInformation info, TypeGraphInferrerEngine inferrer) {
+    return info == inferrer.types.getInferredTypeOf(calledElement);
+  }
+
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitStaticCallSiteTypeInformation(this);
+  }
 }
 
 class DynamicCallSiteTypeInformation extends CallSiteTypeInformation {
@@ -454,7 +485,7 @@
         inferrer.updateParameterAssignments(
             this, element, arguments, typedSelector, remove: false);
       }
-      
+
       if (returnsElementType(typedSelector)) {
         // Find the [ElementInContainerTypeInformation] node and tell
         // that this node is a user of it. Later, when the element
@@ -506,7 +537,17 @@
     super.giveUp(inferrer);
   }
 
-  String toString() => 'Call site $call ${receiver.type} $type';
+  bool reachedBy(TypeInformation info, TypeGraphInferrerEngine inferrer) {
+    return targets
+            .map((element) => inferrer.types.getInferredTypeOf(element))
+            .any((other) => other == info);
+  }
+
+  String toString() => 'Call site $call on ${receiver.type} $type';
+
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitDynamicCallSiteTypeInformation(this);
+  }
 }
 
 class ClosureCallSiteTypeInformation extends CallSiteTypeInformation {
@@ -529,10 +570,14 @@
   }
 
   Iterable<Element> get callees {
-    throw new UnsupportedError("Cannot compute callees of a closure.");
+    throw new UnsupportedError("Cannot compute callees of a closure call.");
   }
 
   String toString() => 'Closure call $call on $closure';
+
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitClosureCallSiteTypeInformation(this);
+  }
 }
 
 /**
@@ -569,6 +614,10 @@
   }
 
   String toString() => 'Type $type';
+
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitConcreteTypeInformation(this);
+  }
 }
 
 /**
@@ -602,23 +651,28 @@
   }
 
   String toString() => 'Narrow ${assignments.first} to $typeAnnotation $type';
+
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitNarrowTypeInformation(this);
+  }
 }
 
 /**
- * A [ContainerTypeInformation] is a [ConcreteTypeInformation] created
+ * A [ContainerTypeInformation] is a [TypeInformation] created
  * for each `List` instantiations.
  */
-class ContainerTypeInformation extends ConcreteTypeInformation {
-  final TypeInformation elementType;
+class ContainerTypeInformation extends TypeInformation {
+  final ElementInContainerTypeInformation elementType;
 
-  ContainerTypeInformation(containerType, this.elementType)
-      : super(containerType);
-
-  void addUser(TypeInformation user) {
-    elementType.addUser(user);
+  ContainerTypeInformation(containerType, this.elementType) {
+    type = containerType;
   }
 
   String toString() => 'Container type $type';
+
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitContainerTypeInformation(this);
+  }
 }
 
 /**
@@ -629,17 +683,27 @@
   final ContainerTypeMask container;
 
   ElementInContainerTypeInformation(elementType, this.container) {
-    // [elementType] is not null for const lists.
     if (elementType != null) addAssignment(elementType);
   }
 
+  bool get isInConstContainer {
+    LiteralList literal = container.allocationNode.asLiteralList();
+    return (literal != null) && literal.isConst();
+  }
+
   TypeMask refine(TypeGraphInferrerEngine inferrer) {
-    if (assignments.isEmpty) return inferrer.types.dynamicType.type;
+    if (!isInConstContainer) {
+      return inferrer.types.dynamicType.type;
+    }
     return container.elementType =
         inferrer.types.computeTypeMask(assignments);
   }
 
   String toString() => 'Element in container $type';
+
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitElementInContainerTypeInformation(this);
+  }
 }
 
 /**
@@ -658,4 +722,21 @@
   }
 
   String toString() => 'Phi $element $type';
+
+  accept(TypeInformationVisitor visitor) {
+    return visitor.visitPhiElementTypeInformation(this);
+  }
+}
+
+abstract class TypeInformationVisitor<T> {
+  T visitNarrowTypeInformation(NarrowTypeInformation info);
+  T visitPhiElementTypeInformation(PhiElementTypeInformation info);
+  T visitElementInContainerTypeInformation(
+      ElementInContainerTypeInformation info);
+  T visitContainerTypeInformation(ContainerTypeInformation info);
+  T visitConcreteTypeInformation(ConcreteTypeInformation info);
+  T visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info);
+  T visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info);
+  T visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info);
+  T visitElementTypeInformation(ElementTypeInformation info);
 }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index b2cd1d9..754e5aa 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -319,17 +319,9 @@
   /// True if there isn't sufficient @MirrorsUsed data.
   bool hasInsufficientMirrorsUsed = false;
 
-  /// List of instantiated types from metadata.  If metadata must be preserved,
-  /// these types must registered.
-  final List<Dependency> metadataInstantiatedTypes = <Dependency>[];
-
-  /// List of elements used from metadata.  If metadata must be preserved,
-  /// these elements must be compiled.
-  final List<Element> metadataStaticUse = <Element>[];
-
-  /// List of tear-off functions referenced from metadata.  If metadata must be
-  /// preserved, these elements must be compiled.
-  final List<FunctionElement> metadataGetOfStaticFunction = <FunctionElement>[];
+  /// List of constants from metadata.  If metadata must be preserved,
+  /// these constants must be registered.
+  final List<Dependency> metadataConstants = <Dependency>[];
 
   /// List of symbols that the user has requested for reflection.
   final Set<String> symbolsUsed = new Set<String>();
@@ -660,17 +652,17 @@
     validateInterceptorImplementsAllObjectMethods(jsInterceptorClass);
 
     stringType = new HBoundedType(
-        new TypeMask.nonNullExact(jsStringClass.rawType));
+        new TypeMask.nonNullExact(jsStringClass));
     indexablePrimitiveType = new HBoundedType(
-        new TypeMask.nonNullSubtype(jsIndexableClass.rawType));
+        new TypeMask.nonNullSubtype(jsIndexableClass));
     readableArrayType = new HBoundedType(
-        new TypeMask.nonNullSubclass(jsArrayClass.rawType));
+        new TypeMask.nonNullSubclass(jsArrayClass));
     mutableArrayType = new HBoundedType(
-        new TypeMask.nonNullSubclass(jsMutableArrayClass.rawType));
+        new TypeMask.nonNullSubclass(jsMutableArrayClass));
     fixedArrayType = new HBoundedType(
-        new TypeMask.nonNullExact(jsFixedArrayClass.rawType));
+        new TypeMask.nonNullExact(jsFixedArrayClass));
     extendableArrayType = new HBoundedType(
-        new TypeMask.nonNullExact(jsExtendableArrayClass.rawType));
+        new TypeMask.nonNullExact(jsExtendableArrayClass));
   }
 
   void validateInterceptorImplementsAllObjectMethods(
@@ -745,6 +737,56 @@
     }
   }
 
+  Constant registerCompileTimeConstant(Constant constant,
+                                       TreeElements elements) {
+    registerCompileTimeConstantInternal(constant, elements);
+    for (Constant dependency in constant.getDependencies()) {
+      registerCompileTimeConstant(dependency, elements);
+    }
+  }
+
+  void registerCompileTimeConstantInternal(Constant constant,
+                                           TreeElements elements) {
+    DartType type = constant.computeType(compiler);
+    registerInstantiatedConstantType(type, elements);
+
+    if (constant.isFunction()) {
+      FunctionConstant function = constant;
+      compiler.enqueuer.codegen.registerGetOfStaticFunction(function.element);
+    } else if (constant.isInterceptor()) {
+      // An interceptor constant references the class's prototype chain.
+      InterceptorConstant interceptor = constant;
+      registerInstantiatedConstantType(interceptor.dispatchedType, elements);
+    } else if (constant.isType()) {
+      TypeConstant typeConstant = constant;
+      registerTypeLiteral(typeConstant.representedType.element,
+          compiler.enqueuer.codegen, elements);
+    }
+  }
+
+  void registerInstantiatedConstantType(DartType type, TreeElements elements) {
+    Enqueuer enqueuer = compiler.enqueuer.codegen;
+    enqueuer.registerInstantiatedType(type, elements);
+    if (type is InterfaceType && !type.treatAsRaw &&
+        classNeedsRti(type.element)) {
+      enqueuer.registerStaticUse(getSetRuntimeTypeInfo());
+    }
+    if (type.element == typeImplementation) {
+      // If we use a type literal in a constant, the compile time
+      // constant emitter will generate a call to the createRuntimeType
+      // helper so we register a use of that.
+      enqueuer.registerStaticUse(getCreateRuntimeType());
+    }
+  }
+
+  void registerMetadataConstant(Constant constant, TreeElements elements) {
+    if (mustRetainMetadata) {
+      registerCompileTimeConstant(constant, elements);
+    } else {
+      metadataConstants.add(new Dependency(constant, elements));
+    }
+  }
+
   void registerInstantiatedClass(ClassElement cls,
                                  Enqueuer enqueuer,
                                  TreeElements elements) {
@@ -990,7 +1032,7 @@
       }
     }
     bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE;
-    if (!type.isRaw || type.containsTypeVariables) {
+    if (!type.treatAsRaw || type.containsTypeVariables) {
       enqueueInResolution(getSetRuntimeTypeInfo(), elements);
       enqueueInResolution(getGetRuntimeTypeInfo(), elements);
       enqueueInResolution(getGetRuntimeTypeArgument(), elements);
@@ -1187,8 +1229,12 @@
       return;
     }
     if (kind.category == ElementCategory.VARIABLE) {
-      Constant initialValue = compiler.constantHandler.compileWorkItem(work);
+      Constant initialValue =
+          compiler.constantHandler.getConstantForVariable(element);
       if (initialValue != null) {
+        registerCompileTimeConstant(initialValue, work.resolutionTree);
+        compiler.constantHandler.addCompileTimeConstantForEmission(
+            initialValue);
         return;
       } else {
         // If the constant-handler was not able to produce a result we have to
@@ -1372,7 +1418,7 @@
             : 'stringSuperTypeCheck';
       }
     } else if ((element == compiler.listClass || element == jsArrayClass) &&
-               type.isRaw) {
+               type.treatAsRaw) {
       if (nativeCheckOnly) return null;
       return typeCast
           ? 'listTypeCast'
@@ -1396,7 +1442,7 @@
               ? 'interceptedTypeCast'
               : 'interceptedTypeCheck';
         } else {
-          if (type.kind == TypeKind.INTERFACE && !type.isRaw) {
+          if (type.kind == TypeKind.INTERFACE && !type.treatAsRaw) {
             return typeCast
                 ? 'subtypeCast'
                 : 'assertSubtype';
@@ -1612,8 +1658,9 @@
     if (mustRetainMetadata) hasRetainedMetadata = true;
     if (mustRetainMetadata && isNeededForReflection(element)) {
       for (MetadataAnnotation metadata in element.metadata) {
-        metadata.ensureResolved(compiler)
-            .value.accept(new ConstantCopier(compiler.constantHandler));
+        metadata.ensureResolved(compiler);
+        compiler.constantHandler.addCompileTimeConstantForEmission(
+            metadata.value);
       }
       return true;
     }
@@ -1633,30 +1680,6 @@
     return new Future.value();
   }
 
-  void registerMetadataInstantiatedType(DartType type, TreeElements elements) {
-    if (mustRetainMetadata) {
-      compiler.constantHandler.registerInstantiatedType(type, elements);
-    } else {
-      metadataInstantiatedTypes.add(new Dependency(type, elements));
-    }
-  }
-
-  void registerMetadataStaticUse(Element element) {
-    if (mustRetainMetadata) {
-      compiler.constantHandler.registerStaticUse(element);
-    } else {
-      metadataStaticUse.add(element);
-    }
-  }
-
-  void registerMetadataGetOfStaticFunction(FunctionElement element) {
-    if (mustRetainMetadata) {
-      compiler.constantHandler.registerGetOfStaticFunction(element);
-    } else {
-      metadataGetOfStaticFunction.add(element);
-    }
-  }
-
   void registerMirrorUsage(Set<String> symbols,
                            Set<Element> targets,
                            Set<Element> metaTargets) {
@@ -1777,28 +1800,21 @@
       compiler.log('Retaining metadata.');
 
       compiler.libraries.values.forEach(retainMetadataOf);
-      for (Dependency dependency in metadataInstantiatedTypes) {
-        registerMetadataInstantiatedType(dependency.type, dependency.user);
+      for (Dependency dependency in metadataConstants) {
+        registerCompileTimeConstant(
+            dependency.constant, dependency.user);
       }
-      metadataInstantiatedTypes.clear();
-      for (Element e in metadataStaticUse) {
-        registerMetadataStaticUse(e);
-      }
-      metadataStaticUse.clear();
-      for (Element e in metadataGetOfStaticFunction) {
-        registerMetadataGetOfStaticFunction(e);
-      }
-      metadataGetOfStaticFunction.clear();
+      metadataConstants.clear();
     }
   }
 }
 
-/// Records that [type] is used by [user.element].
+/// Records that [constant] is used by [user.element].
 class Dependency {
-  final DartType type;
+  final Constant constant;
   final TreeElements user;
 
-  const Dependency(this.type, this.user);
+  const Dependency(this.constant, this.user);
 }
 
 /// Used to copy metadata to the the actual constant handler.
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
index 16ffce5..bd5c8aa 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
@@ -332,7 +332,7 @@
   jsAst.Expression maybeAddTypeArguments(InterfaceType type,
                                          jsAst.Expression value) {
     if (type is InterfaceType &&
-        !type.isRaw &&
+        !type.treatAsRaw &&
         backend.classNeedsRti(type.element)) {
       InterfaceType interface = type;
       RuntimeTypes rti = backend.rti;
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
index bee8ea9..b7cf4f2 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
@@ -11,6 +11,7 @@
 import '../../compiler.dart' as api;
 import '../elements/elements.dart';
 import '../elements/modelx.dart' show FunctionElementX;
+import '../js_emitter/js_emitter.dart' show Emitter, CodeEmitterTask, ClassBuilder;
 
 // TODO(ahe): There seems to be a bug in the VM, so we have to hide "js".
 import '../dart2jslib.dart' hide Selector, TypedSelector, js;
@@ -31,7 +32,6 @@
 part 'backend.dart';
 part 'constant_emitter.dart';
 part 'constant_system_javascript.dart';
-part 'emitter.dart';
 part 'minify_namer.dart';
 part 'namer.dart';
 part 'native_emitter.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 141cd89..f11ac3b 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -352,21 +352,16 @@
         ? library
         : shortPrivateNameOwners.putIfAbsent(nameString, () => library);
 
-    // If a private name could clash with a mangled private name we don't
-    // use the short name. For example a private name "_lib3_foo" would
-    // clash with "_foo" from "lib3".
-    if (owner == library &&
-        !nameString.startsWith('_$LIBRARY_PREFIX') &&
-        !shouldMinify) {
+    if (owner == library && !shouldMinify && !nameString.contains('\$')) {
+      // Since the name doesn't contain $ it doesn't clash with any
+      // of the private names that have the library name as the prefix.
       return nameString;
+    } else {
+      // Make sure to return a private name that starts with _ so it
+      // cannot clash with any public names.
+      String libraryName = getNameOfLibrary(library);
+      return '_$libraryName\$$nameString';
     }
-
-    // If a library name does not start with the [LIBRARY_PREFIX] then our
-    // assumptions about clashing with mangled private members do not hold.
-    String libraryName = getNameOfLibrary(library);
-    assert(shouldMinify || libraryName.startsWith(LIBRARY_PREFIX));
-    // TODO(erikcorry): Fix this with other manglings to avoid clashes.
-    return '_lib$libraryName\$$nameString';
   }
 
   String instanceMethodName(FunctionElement element) {
@@ -563,8 +558,6 @@
     return new SourceString("${name.slowToString()}_$id");
   }
 
-  static const String LIBRARY_PREFIX = "lib";
-
   /**
    * Returns a preferred JS-id for the given top-level or static element.
    * The returned id is guaranteed to be a valid JS-id.
@@ -589,7 +582,16 @@
         name = element.name.slowToString().replaceAll('+', '_');
       }
     } else if (element.isLibrary()) {
-      name = LIBRARY_PREFIX;
+      LibraryElement library = element;
+      name = library.getLibraryOrScriptName();
+      if (name.contains('.')) {
+        // For libraries that have a library tag, we use the last part
+        // of the fully qualified name as their base name. For all other
+        // libraries, we use the first part of their filename.
+        name = library.hasLibraryName()
+            ? name.substring(name.lastIndexOf('.') + 1)
+            : name.substring(0, name.indexOf('.'));
+      }
     } else {
       name = element.name.slowToString();
     }
@@ -777,9 +779,6 @@
           kind == ElementKind.TYPEDEF ||
           kind == ElementKind.LIBRARY) {
         bool fixedName = false;
-        if (kind == ElementKind.CLASS) {
-          ClassElement classElement = element;
-        }
         if (Elements.isInstanceField(element)) {
           fixedName = element.hasFixedBackendName();
         }
@@ -803,10 +802,14 @@
 
   String getNameOfField(VariableElement field) => getNameX(field);
 
+  // TODO(ahe): Remove this method. Use get getNameOfMember instead.
   String getNameOfInstanceMember(Element member) => getNameX(member);
 
+  String getNameOfMember(Element member) => getNameX(member);
+
   String getNameOfGlobalField(VariableElement field) => getNameX(field);
 
+  // TODO(ahe): Remove this method. Use get getNameOfMember instead.
   String getNameOfGlobalFunction(FunctionElement element) => getNameX(element);
 
   /// Returns true if [element] is stored on CURRENT_ISOLATE ('$').  We intend
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
index 1153082..1f83c5f 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
@@ -35,7 +35,7 @@
   Compiler get compiler => emitter.compiler;
   JavaScriptBackend get backend => compiler.backend;
 
-  String get _ => emitter._;
+  String get _ => emitter.space;
   String get n => emitter.n;
   String get N => emitter.N;
 
@@ -325,7 +325,9 @@
   }
 
   ClassBuilder generateNativeClass(ClassElement classElement) {
-    assert(!classElement.hasBackendMembers);
+    // TODO(sra): Issue #13731- this is commented out as part of custom element
+    // constructor work.
+    //assert(!classElement.hasBackendMembers);
     nativeClasses.add(classElement);
 
     ClassElement superclass = classElement.superclass;
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
index 6a52399..fbb9da7 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -162,7 +162,7 @@
     compiler.resolverWorld.isChecks.forEach((DartType type) {
       if (type.kind == TypeKind.INTERFACE) {
         InterfaceType itf = type;
-        if (!itf.isRaw) {
+        if (!itf.treatAsRaw) {
           potentiallyAddForRti(itf.element);
         }
       } else {
@@ -559,7 +559,7 @@
   static bool hasTypeArguments(DartType type) {
     if (type is InterfaceType) {
       InterfaceType interfaceType = type;
-      return !interfaceType.isRaw;
+      return !interfaceType.treatAsRaw;
     }
     return false;
   }
@@ -613,7 +613,7 @@
 
   visitInterfaceType(InterfaceType type, _) {
     jsAst.Expression name = getJavaScriptClassName(type.element);
-    return type.isRaw ? name : visitList(type.typeArguments, head: name);
+    return type.treatAsRaw ? name : visitList(type.typeArguments, head: name);
   }
 
   jsAst.Expression visitList(Link<DartType> types, {jsAst.Expression head}) {
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/class_builder.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/class_builder.dart
new file mode 100644
index 0000000..626de96
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/class_builder.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart2js.js_emitter;
+
+/**
+ * A data structure for collecting fragments of a class definition.
+ */
+class ClassBuilder {
+  final List<jsAst.Property> properties = <jsAst.Property>[];
+
+  /// Set to true by user if class is indistinguishable from its superclass.
+  bool isTrivial = false;
+
+  // Has the same signature as [DefineStubFunction].
+  void addProperty(String name, jsAst.Expression value) {
+    properties.add(new jsAst.Property(js.string(name), value));
+  }
+
+  jsAst.Expression toObjectInitializer() {
+    return new jsAst.ObjectInitializer(properties);
+  }
+
+  /// This method is temporary. Do not use it unless you're working on
+  /// transforming code to build jsAst.Nodes.
+  void writeOn_DO_NOT_USE(CodeBuffer buffer,
+                          Compiler compiler,
+                          String separatedBy) {
+    for (jsAst.Property property in properties) {
+      if (!buffer.isEmpty) buffer.write(separatedBy);
+      buffer.write(jsAst.prettyPrint(property, compiler));
+    }
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/closure_invocation_element.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/closure_invocation_element.dart
new file mode 100644
index 0000000..bd52fe2
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/closure_invocation_element.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart2js.js_emitter;
+
+/**
+ * A function element that represents a closure call. The signature is copied
+ * from the given element.
+ */
+class ClosureInvocationElement extends FunctionElementX {
+  ClosureInvocationElement(SourceString name,
+                           FunctionElement other)
+      : super.from(name, other, other.enclosingElement),
+        methodElement = other;
+
+  isInstanceMember() => true;
+
+  Element getOutermostEnclosingMemberOrTopLevel() => methodElement;
+
+  /**
+   * The [member] this invocation refers to.
+   */
+  Element methodElement;
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
similarity index 77%
rename from sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
rename to sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
index a284cbe..dae8663 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
@@ -2,86 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of js_backend;
-
-/// Enables debugging of fast/slow objects using V8-specific primitives.
-const DEBUG_FAST_OBJECTS = false;
-
-/**
- * A function element that represents a closure call. The signature is copied
- * from the given element.
- */
-class ClosureInvocationElement extends FunctionElementX {
-  ClosureInvocationElement(SourceString name,
-                           FunctionElement other)
-      : super.from(name, other, other.enclosingElement),
-        methodElement = other;
-
-  isInstanceMember() => true;
-
-  Element getOutermostEnclosingMemberOrTopLevel() => methodElement;
-
-  /**
-   * The [member] this invocation refers to.
-   */
-  Element methodElement;
-}
-
-/**
- * A convenient type alias for some functions that emit keyed values.
- */
-typedef void DefineStubFunction(String invocationName, jsAst.Expression value);
-
-/**
- * [member] is a field (instance, static, or top level).
- *
- * [name] is the field name that the [Namer] has picked for this field's
- * storage, that is, the JavaScript property name.
- *
- * [accessorName] is the name of the accessor. For instance fields this is
- * mostly the same as [name] except when [member] is shadowing a field in its
- * superclass.  For other fields, they are rarely the same.
- *
- * [needsGetter] and [needsSetter] represent if a getter or a setter
- * respectively is needed.  There are many factors in this, for example, if the
- * accessor can be inlined.
- *
- * [needsCheckedSetter] indicates that a checked getter is needed, and in this
- * case, [needsSetter] is always false. [needsCheckedSetter] is only true when
- * type assertions are enabled (checked mode).
- */
-typedef void AcceptField(VariableElement member,
-                         String name,
-                         String accessorName,
-                         bool needsGetter,
-                         bool needsSetter,
-                         bool needsCheckedSetter);
-
-/**
- * A data structure for collecting fragments of a class definition.
- */
-class ClassBuilder {
-  final List<jsAst.Property> properties = <jsAst.Property>[];
-
-  /// Set to true by user if class is indistinguishable from its superclass.
-  bool isTrivial = false;
-
-  // Has the same signature as [DefineStubFunction].
-  void addProperty(String name, jsAst.Expression value) {
-    properties.add(new jsAst.Property(js.string(name), value));
-  }
-
-  jsAst.Expression toObjectInitializer() {
-    return new jsAst.ObjectInitializer(properties);
-  }
-}
-
-// Function signatures used in the generation of runtime type information.
-typedef void FunctionTypeSignatureEmitter(Element method,
-                                          FunctionType methodType);
-// TODO(johnniwinther): Clean up terminology for rti in the emitter.
-typedef void FunctionTypeTestEmitter(FunctionType functionType);
-typedef void SubstitutionEmitter(Element element, {bool emitNull});
+part of dart2js.js_emitter;
 
 /**
  * Generates the code for all used classes in the program. Static fields (even
@@ -90,6 +11,7 @@
  * The code for the containing (used) methods must exist in the [:universe:].
  */
 class CodeEmitterTask extends CompilerTask {
+  final ContainerBuilder containerBuilder = new ContainerBuilder();
   bool needsDefineClass = false;
   bool needsMixinSupport = false;
   bool needsLazyInitializer = false;
@@ -124,29 +46,14 @@
   // TODO(ngeoffray): remove this field.
   Set<ClassElement> instantiatedClasses;
 
-  final List<jsAst.Expression> boundClosures = <jsAst.Expression>[];
-
   JavaScriptBackend get backend => compiler.backend;
 
-  String get _ => compiler.enableMinification ? "" : " ";
+  String get _ => space;
+  String get space => compiler.enableMinification ? "" : " ";
   String get n => compiler.enableMinification ? "" : "\n";
   String get N => compiler.enableMinification ? "\n" : ";\n";
 
   /**
-   * A cache of closures that are used to closurize instance methods.
-   * A closure is dynamically bound to the instance used when
-   * closurized.
-   */
-  final Map<int, String> boundClosureCache;
-
-  /**
-   * A cache of closures that are used to closurize instance methods
-   * of interceptors. These closures are dynamically bound to the
-   * interceptor instance, and the actual receiver of the method.
-   */
-  final Map<int, String> interceptorClosureCache;
-
-  /**
    * Raw ClassElement symbols occuring in is-checks and type assertions.  If the
    * program contains parameterized checks `x is Set<int>` and
    * `x is Set<String>` then the ClassElement `Set` will occur once in
@@ -219,11 +126,10 @@
   CodeEmitterTask(Compiler compiler, Namer namer, this.generateSourceMap)
       : mainBuffer = new CodeBuffer(),
         this.namer = namer,
-        boundClosureCache = new Map<int, String>(),
-        interceptorClosureCache = new Map<int, String>(),
         constantEmitter = new ConstantEmitter(compiler, namer),
         super(compiler) {
     nativeEmitter = new NativeEmitter(this);
+    containerBuilder.task = this;
   }
 
   void addComment(String comment, CodeBuffer buffer) {
@@ -983,241 +889,6 @@
     buffer.write("$isolate = $finishIsolateConstructorName($isolate)$N");
   }
 
-  /**
-   * Generate stubs to handle invocation of methods with optional
-   * arguments.
-   *
-   * A method like [: foo([x]) :] may be invoked by the following
-   * calls: [: foo(), foo(1), foo(x: 1) :]. See the sources of this
-   * function for detailed examples.
-   */
-  void addParameterStub(FunctionElement member,
-                        Selector selector,
-                        DefineStubFunction defineStub,
-                        Set<String> alreadyGenerated) {
-    FunctionSignature parameters = member.computeSignature(compiler);
-    int positionalArgumentCount = selector.positionalArgumentCount;
-    if (positionalArgumentCount == parameters.parameterCount) {
-      assert(selector.namedArgumentCount == 0);
-      return;
-    }
-    if (parameters.optionalParametersAreNamed
-        && selector.namedArgumentCount == parameters.optionalParameterCount) {
-      // If the selector has the same number of named arguments as the element,
-      // we don't need to add a stub. The call site will hit the method
-      // directly.
-      return;
-    }
-    ConstantHandler handler = compiler.constantHandler;
-    List<SourceString> names = selector.getOrderedNamedArguments();
-
-    String invocationName = namer.invocationName(selector);
-    if (alreadyGenerated.contains(invocationName)) return;
-    alreadyGenerated.add(invocationName);
-
-    bool isInterceptedMethod = backend.isInterceptedMethod(member);
-
-    // If the method is intercepted, we need to also pass the actual receiver.
-    int extraArgumentCount = isInterceptedMethod ? 1 : 0;
-    // Use '$receiver' to avoid clashes with other parameter names. Using
-    // '$receiver' works because [:namer.safeName:] used for getting parameter
-    // names never returns a name beginning with a single '$'.
-    String receiverArgumentName = r'$receiver';
-
-    // The parameters that this stub takes.
-    List<jsAst.Parameter> parametersBuffer =
-        new List<jsAst.Parameter>(selector.argumentCount + extraArgumentCount);
-    // The arguments that will be passed to the real method.
-    List<jsAst.Expression> argumentsBuffer =
-        new List<jsAst.Expression>(
-            parameters.parameterCount + extraArgumentCount);
-
-    int count = 0;
-    if (isInterceptedMethod) {
-      count++;
-      parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName);
-      argumentsBuffer[0] = js(receiverArgumentName);
-      interceptorInvocationNames.add(invocationName);
-    }
-
-    int optionalParameterStart = positionalArgumentCount + extraArgumentCount;
-    // Includes extra receiver argument when using interceptor convention
-    int indexOfLastOptionalArgumentInParameters = optionalParameterStart - 1;
-
-    TreeElements elements =
-        compiler.enqueuer.resolution.getCachedElements(member);
-
-    parameters.orderedForEachParameter((Element element) {
-      String jsName = backend.namer.safeName(element.name.slowToString());
-      assert(jsName != receiverArgumentName);
-      if (count < optionalParameterStart) {
-        parametersBuffer[count] = new jsAst.Parameter(jsName);
-        argumentsBuffer[count] = js(jsName);
-      } else {
-        int index = names.indexOf(element.name);
-        if (index != -1) {
-          indexOfLastOptionalArgumentInParameters = count;
-          // The order of the named arguments is not the same as the
-          // one in the real method (which is in Dart source order).
-          argumentsBuffer[count] = js(jsName);
-          parametersBuffer[optionalParameterStart + index] =
-              new jsAst.Parameter(jsName);
-        } else {
-          Constant value = handler.initialVariableValues[element];
-          if (value == null) {
-            argumentsBuffer[count] = constantReference(new NullConstant());
-          } else {
-            if (!value.isNull()) {
-              // If the value is the null constant, we should not pass it
-              // down to the native method.
-              indexOfLastOptionalArgumentInParameters = count;
-            }
-            argumentsBuffer[count] = constantReference(value);
-          }
-        }
-      }
-      count++;
-    });
-
-    List body;
-    if (member.hasFixedBackendName()) {
-      body = nativeEmitter.generateParameterStubStatements(
-          member, isInterceptedMethod, invocationName,
-          parametersBuffer, argumentsBuffer,
-          indexOfLastOptionalArgumentInParameters);
-    } else {
-      body = [js.return_(
-          js('this')[namer.getNameOfInstanceMember(member)](argumentsBuffer))];
-    }
-
-    jsAst.Fun function = js.fun(parametersBuffer, body);
-
-    defineStub(invocationName, function);
-
-    String reflectionName = getReflectionName(selector, invocationName);
-    if (reflectionName != null) {
-      var reflectable =
-          js(backend.isAccessibleByReflection(member) ? '1' : '0');
-      defineStub('+$reflectionName', reflectable);
-    }
-  }
-
-  void addParameterStubs(FunctionElement member,
-                         DefineStubFunction defineStub) {
-    // We fill the lists depending on the selector. For example,
-    // take method foo:
-    //    foo(a, b, {c, d});
-    //
-    // We may have multiple ways of calling foo:
-    // (1) foo(1, 2);
-    // (2) foo(1, 2, c: 3);
-    // (3) foo(1, 2, d: 4);
-    // (4) foo(1, 2, c: 3, d: 4);
-    // (5) foo(1, 2, d: 4, c: 3);
-    //
-    // What we generate at the call sites are:
-    // (1) foo$2(1, 2);
-    // (2) foo$3$c(1, 2, 3);
-    // (3) foo$3$d(1, 2, 4);
-    // (4) foo$4$c$d(1, 2, 3, 4);
-    // (5) foo$4$c$d(1, 2, 3, 4);
-    //
-    // The stubs we generate are (expressed in Dart):
-    // (1) foo$2(a, b) => foo$4$c$d(a, b, null, null)
-    // (2) foo$3$c(a, b, c) => foo$4$c$d(a, b, c, null);
-    // (3) foo$3$d(a, b, d) => foo$4$c$d(a, b, null, d);
-    // (4) No stub generated, call is direct.
-    // (5) No stub generated, call is direct.
-
-    // Keep a cache of which stubs have already been generated, to
-    // avoid duplicates. Note that even if selectors are
-    // canonicalized, we would still need this cache: a typed selector
-    // on A and a typed selector on B could yield the same stub.
-    Set<String> generatedStubNames = new Set<String>();
-    bool isClosureInvocation =
-        member.name == namer.closureInvocationSelectorName;
-    if (backend.isNeededForReflection(member) ||
-        (compiler.enabledFunctionApply && isClosureInvocation)) {
-      // If [Function.apply] is called, we pessimistically compile all
-      // possible stubs for this closure.
-      FunctionSignature signature = member.computeSignature(compiler);
-      Set<Selector> selectors = signature.optionalParametersAreNamed
-          ? computeSeenNamedSelectors(member)
-          : computeOptionalSelectors(signature, member);
-      for (Selector selector in selectors) {
-        addParameterStub(member, selector, defineStub, generatedStubNames);
-      }
-      if (signature.optionalParametersAreNamed && isClosureInvocation) {
-        addCatchAllParameterStub(member, signature, defineStub);
-      }
-    } else {
-      Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
-      if (selectors == null) return;
-      for (Selector selector in selectors) {
-        if (!selector.applies(member, compiler)) continue;
-        addParameterStub(member, selector, defineStub, generatedStubNames);
-      }
-    }
-  }
-
-  Set<Selector> computeSeenNamedSelectors(FunctionElement element) {
-    Set<Selector> selectors = compiler.codegenWorld.invokedNames[element.name];
-    Set<Selector> result = new Set<Selector>();
-    if (selectors == null) return result;
-    for (Selector selector in selectors) {
-      if (!selector.applies(element, compiler)) continue;
-      result.add(selector);
-    }
-    return result;
-  }
-
-  void addCatchAllParameterStub(FunctionElement member,
-                                FunctionSignature signature,
-                                DefineStubFunction defineStub) {
-    // See Primities.applyFunction in js_helper.dart for details.
-    List<jsAst.Property> properties = <jsAst.Property>[];
-    for (Element element in signature.orderedOptionalParameters) {
-      String jsName = backend.namer.safeName(element.name.slowToString());
-      Constant value = compiler.constantHandler.initialVariableValues[element];
-      jsAst.Expression reference = null;
-      if (value == null) {
-        reference = new jsAst.LiteralNull();
-      } else {
-        reference = constantReference(value);
-      }
-      properties.add(new jsAst.Property(js.string(jsName), reference));
-    }
-    defineStub(
-        backend.namer.callCatchAllName,
-        js.fun([], js.return_(new jsAst.ObjectInitializer(properties))));
-  }
-
-  /**
-   * Compute the set of possible selectors in the presence of optional
-   * non-named parameters.
-   */
-  Set<Selector> computeOptionalSelectors(FunctionSignature signature,
-                                         FunctionElement element) {
-    Set<Selector> selectors = new Set<Selector>();
-    // Add the selector that does not have any optional argument.
-    selectors.add(new Selector(SelectorKind.CALL,
-                               element.name,
-                               element.getLibrary(),
-                               signature.requiredParameterCount,
-                               <SourceString>[]));
-
-    // For each optional parameter, we increment the number of passed
-    // argument.
-    for (int i = 1; i <= signature.optionalParameterCount; i++) {
-      selectors.add(new Selector(SelectorKind.CALL,
-                                 element.name,
-                                 element.getLibrary(),
-                                 signature.requiredParameterCount + i,
-                                 <SourceString>[]));
-    }
-    return selectors;
-  }
-
   bool fieldNeedsGetter(VariableElement field) {
     assert(field.isField());
     if (fieldAccessNeverThrows(field)) return false;
@@ -1240,55 +911,6 @@
     return field is ClosureFieldElement;
   }
 
-  /**
-   * Documentation wanted -- johnniwinther
-   *
-   * Invariant: [member] must be a declaration element.
-   */
-  void addInstanceMember(Element member, ClassBuilder builder) {
-    assert(invariant(member, member.isDeclaration));
-    // TODO(floitsch): we don't need to deal with members of
-    // uninstantiated classes, that have been overwritten by subclasses.
-
-    if (member.isFunction()
-        || member.isGenerativeConstructorBody()
-        || member.isAccessor()) {
-      if (member.isAbstract(compiler)) return;
-      jsAst.Expression code = backend.generatedCode[member];
-      if (code == null) return;
-      String name = namer.getNameOfInstanceMember(member);
-      if (backend.isInterceptedMethod(member)) {
-        interceptorInvocationNames.add(name);
-      }
-      code = extendWithMetadata(member, code);
-      builder.addProperty(name, code);
-      String reflectionName = getReflectionName(member, name);
-      if (reflectionName != null) {
-        var reflectable =
-            js(backend.isAccessibleByReflection(member) ? '1' : '0');
-        builder.addProperty('+$reflectionName', reflectable);
-        jsAst.Node defaultValues = reifyDefaultArguments(member);
-        if (defaultValues != null) {
-          String unmangledName = member.name.slowToString();
-          builder.addProperty('*$unmangledName', defaultValues);
-        }
-      }
-      code = backend.generatedBailoutCode[member];
-      if (code != null) {
-        builder.addProperty(namer.getBailoutName(member), code);
-      }
-      FunctionElement function = member;
-      FunctionSignature parameters = function.computeSignature(compiler);
-      if (!parameters.optionalParameters.isEmpty) {
-        addParameterStubs(function, builder.addProperty);
-      }
-    } else if (!member.isField()) {
-      compiler.internalError('unexpected kind: "${member.kind}"',
-                             element: member);
-    }
-    emitExtraAccessors(member, builder);
-  }
-
   /// Returns the "reflection name" of an [Element] or [Selector].
   /// The reflection name of a getter 'foo' is 'foo'.
   /// The reflection name of a setter 'foo' is 'foo='.
@@ -1411,7 +1033,7 @@
     void visitMember(ClassElement enclosing, Element member) {
       assert(invariant(classElement, member.isDeclaration));
       if (member.isInstanceMember()) {
-        addInstanceMember(member, builder);
+        containerBuilder.addMember(member, builder);
       }
     }
 
@@ -2367,18 +1989,6 @@
     }
   }
 
-  void emitStaticFunction(CodeBuffer buffer,
-                          String name,
-                          jsAst.Expression functionExpression) {
-    // TODO(ahe): This method (emitStaticFunction) should return a
-    // jsAst.Expression.
-    if (!buffer.isEmpty) {
-      buffer.write(',$n$n');
-    }
-    buffer.write('$name:$_');
-    buffer.write(jsAst.prettyPrint(functionExpression, compiler));
-  }
-
   void emitStaticFunctions(CodeBuffer eagerBuffer) {
     bool isStaticFunction(Element element) =>
         !element.isInstanceMember() && !element.isField();
@@ -2391,27 +2001,11 @@
             .toSet();
 
     for (Element element in Elements.sortedByPosition(elements)) {
-      CodeBuffer buffer = bufferForElement(element, eagerBuffer);
-      jsAst.Expression code = backend.generatedCode[element];
-      String name = namer.getNameOfGlobalFunction(element);
-      code = extendWithMetadata(element, code);
-      emitStaticFunction(buffer, name, code);
-      String reflectionName = getReflectionName(element, name);
-      if (reflectionName != null) {
-        var reflectable = backend.isAccessibleByReflection(element) ? 1 : 0;
-        buffer.write(',$n$n"+$reflectionName":${_}$reflectable');
-        jsAst.Node defaultValues = reifyDefaultArguments(element);
-        if (defaultValues != null) {
-          String unmangledName = element.name.slowToString();
-          buffer.write(',$n$n"*$unmangledName":${_}');
-          buffer.write(jsAst.prettyPrint(defaultValues, compiler));
-        }
-      }
-      jsAst.Expression bailoutCode = backend.generatedBailoutCode[element];
-      if (bailoutCode != null) {
-        pendingElementsWithBailouts.remove(element);
-        emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode);
-      }
+      pendingElementsWithBailouts.remove(element);
+      ClassBuilder builder = new ClassBuilder();
+      containerBuilder.addMember(element, builder);
+      builder.writeOn_DO_NOT_USE(
+          bufferForElement(element, eagerBuffer), compiler, ',$n$n');
     }
 
     if (!pendingElementsWithBailouts.isEmpty) {
@@ -2420,355 +2014,11 @@
     // Is it possible the primary function was inlined but the bailout was not?
     for (Element element in
              Elements.sortedByPosition(pendingElementsWithBailouts)) {
-      CodeBuffer buffer = bufferForElement(element, eagerBuffer);
       jsAst.Expression bailoutCode = backend.generatedBailoutCode[element];
-      emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode);
-    }
-  }
-
-  final Map<Element, Element> staticGetters = new Map<Element, Element>();
-
-  void emitStaticFunctionGetters(CodeBuffer eagerBuffer) {
-    addComment('Static function getters', mainBuffer);
-    for (FunctionElement element in
-             Elements.sortedByPosition(staticGetters.keys)) {
-      Element closure = staticGetters[element];
-      CodeBuffer buffer = isDeferred(element) ? deferredConstants : eagerBuffer;
-      String closureClass = namer.isolateAccess(closure);
-      String name = namer.getStaticClosureName(element);
-
-      String closureName = namer.getStaticClosureName(element);
-      jsAst.Node assignment = js(
-          'init.globalFunctions["$closureName"] ='
-          ' ${namer.globalObjectFor(element)}.$name ='
-          ' new $closureClass(#, "$closureName")',
-          namer.elementAccess(element));
-      buffer.write(jsAst.prettyPrint(assignment, compiler));
-      buffer.write('$N');
-    }
-  }
-
-  void emitStaticFunctionClosures() {
-    Set<FunctionElement> functionsNeedingGetter =
-        compiler.codegenWorld.staticFunctionsNeedingGetter;
-    for (FunctionElement element in
-             Elements.sortedByPosition(functionsNeedingGetter)) {
-      String superName = namer.getNameOfClass(compiler.closureClass);
-      String name = 'Closure\$${element.name.slowToString()}';
-      assert(instantiatedClasses.contains(compiler.closureClass));
-
-      ClassElement closureClassElement = new ClosureClassElement(
-          null, new SourceString(name), compiler, element,
-          element.getCompilationUnit());
-      // Now add the methods on the closure class. The instance method does not
-      // have the correct name. Since [addParameterStubs] use the name to create
-      // its stubs we simply create a fake element with the correct name.
-      // Note: the callElement will not have any enclosingElement.
-      FunctionElement callElement =
-          new ClosureInvocationElement(namer.closureInvocationSelectorName,
-                                       element);
-
-      String invocationName = namer.instanceMethodName(callElement);
-      String mangledName = namer.getNameOfClass(closureClassElement);
-
-      // Define the constructor with a name so that Object.toString can
-      // find the class name of the closure class.
-      ClassBuilder closureBuilder = new ClassBuilder();
-      // If a static function is used as a closure we need to add its name
-      // in case it is used in spawnFunction.
-      String methodName = namer.STATIC_CLOSURE_NAME_NAME;
-      emitClosureClassHeader(
-          mangledName, superName, <String>[invocationName, methodName],
-          closureBuilder);
-
-      addParameterStubs(callElement, closureBuilder.addProperty);
-
-      // TODO(ngeoffray): Cache common base classes for closures, bound
-      // closures, and static closures that have common type checks.
-      boundClosures.add(
-          js('$classesCollector.$mangledName = #',
-             js('[${namer.globalObjectFor(closureClassElement)}, #]',
-                closureBuilder.toObjectInitializer())));
-
-      staticGetters[element] = closureClassElement;
-
-      void emitFunctionTypeSignature(Element method, FunctionType methodType) {
-        RuntimeTypes rti = backend.rti;
-        // [:() => null:] is dummy encoding of [this] which is never needed for
-        // the encoding of the type of the static [method].
-        jsAst.Expression encoding =
-            rti.getSignatureEncoding(methodType, js('null'));
-        String operatorSignature = namer.operatorSignature();
-        // TODO(johnniwinther): Make MiniJsParser support function expressions.
-        closureBuilder.addProperty(operatorSignature, encoding);
-      }
-
-      void emitIsFunctionTypeTest(FunctionType functionType) {
-        String operator = namer.operatorIsType(functionType);
-        closureBuilder.addProperty(operator, js('true'));
-      }
-
-      FunctionType methodType = element.computeType(compiler);
-      Map<FunctionType, bool> functionTypeChecks =
-          getFunctionTypeChecksOn(methodType);
-      generateFunctionTypeTests(element, methodType, functionTypeChecks,
-          emitFunctionTypeSignature, emitIsFunctionTypeTest);
-    }
-  }
-
-  void emitClosureClassHeader(String mangledName,
-                              String superName,
-                              List<String> fieldNames,
-                              ClassBuilder builder) {
-    builder.addProperty('',
-        js.string("$superName;${fieldNames.join(',')}"));
-
-    List<String> fields = fieldNames;
-    String constructorName = mangledName;
-    precompiledFunction.add(new jsAst.FunctionDeclaration(
-        new jsAst.VariableDeclaration(constructorName),
-        js.fun(fields, fields.map(
-            (name) => js('this.$name = $name')).toList())));
-    precompiledFunction.addAll([
-        js('$constructorName.builtin\$cls = "$constructorName"'),
-        js('\$desc=\$collectedClasses.$constructorName'),
-        js.if_('\$desc instanceof Array', js('\$desc = \$desc[1]')),
-        js('$constructorName.prototype = \$desc'),
-    ]);
-
-    precompiledConstructorNames.add(js(constructorName));
-  }
-
-  /**
-   * Documentation wanted -- johnniwinther
-   *
-   * Invariant: [member] must be a declaration element.
-   */
-  void emitDynamicFunctionGetter(FunctionElement member,
-                                 DefineStubFunction defineStub) {
-    assert(invariant(member, member.isDeclaration));
-    assert(instantiatedClasses.contains(compiler.boundClosureClass));
-    // For every method that has the same name as a property-get we create a
-    // getter that returns a bound closure. Say we have a class 'A' with method
-    // 'foo' and somewhere in the code there is a dynamic property get of
-    // 'foo'. Then we generate the following code (in pseudo Dart/JavaScript):
-    //
-    // class A {
-    //    foo(x, y, z) { ... } // Original function.
-    //    get foo { return new BoundClosure499(this, "foo"); }
-    // }
-    // class BoundClosure499 extends BoundClosure {
-    //   BoundClosure499(this.self, this.name);
-    //   $call3(x, y, z) { return self[name](x, y, z); }
-    // }
-
-    // TODO(floitsch): share the closure classes with other classes
-    // if they share methods with the same signature. Currently we do this only
-    // if there are no optional parameters. Closures with optional parameters
-    // are more difficult to canonicalize because they would need to have the
-    // same default values.
-
-    bool hasOptionalParameters = member.optionalParameterCount(compiler) != 0;
-    int parameterCount = member.parameterCount(compiler);
-
-    Map<int, String> cache;
-    // Intercepted methods take an extra parameter, which is the
-    // receiver of the call.
-    bool inInterceptor = backend.isInterceptedMethod(member);
-    if (inInterceptor) {
-      cache = interceptorClosureCache;
-    } else {
-      cache = boundClosureCache;
-    }
-    List<String> fieldNames = <String>[];
-    compiler.boundClosureClass.forEachInstanceField((_, Element field) {
-      fieldNames.add(namer.getNameOfInstanceMember(field));
-    });
-
-    DartType memberType = member.computeType(compiler);
-    Map<FunctionType, bool> functionTypeChecks =
-        getFunctionTypeChecksOn(memberType);
-    bool hasFunctionTypeChecks = !functionTypeChecks.isEmpty;
-
-    bool canBeShared = !hasOptionalParameters && !hasFunctionTypeChecks;
-
-    ClassElement classElement = member.getEnclosingClass();
-    String closureClass = canBeShared ? cache[parameterCount] : null;
-    if (closureClass == null) {
-      // Either the class was not cached yet, or there are optional parameters.
-      // Create a new closure class.
-      String name;
-      if (canBeShared) {
-        if (inInterceptor) {
-          name = 'BoundClosure\$i${parameterCount}';
-        } else {
-          name = 'BoundClosure\$${parameterCount}';
-        }
-      } else {
-        name = 'Bound_${member.name.slowToString()}'
-            '_${member.enclosingElement.name.slowToString()}';
-      }
-
-      ClassElement closureClassElement = new ClosureClassElement(
-          null, new SourceString(name), compiler, member,
-          member.getCompilationUnit());
-      String mangledName = namer.getNameOfClass(closureClassElement);
-      String superName = namer.getNameOfClass(closureClassElement.superclass);
-
-      // Define the constructor with a name so that Object.toString can
-      // find the class name of the closure class.
-      ClassBuilder boundClosureBuilder = new ClassBuilder();
-      emitClosureClassHeader(
-          mangledName, superName, fieldNames, boundClosureBuilder);
-      // Now add the methods on the closure class. The instance method does not
-      // have the correct name. Since [addParameterStubs] use the name to create
-      // its stubs we simply create a fake element with the correct name.
-      // Note: the callElement will not have any enclosingElement.
-      FunctionElement callElement =
-          new ClosureInvocationElement(namer.closureInvocationSelectorName,
-                                       member);
-
-      String invocationName = namer.instanceMethodName(callElement);
-
-      List<String> parameters = <String>[];
-      List<jsAst.Expression> arguments = <jsAst.Expression>[];
-      arguments.add(js('this')[fieldNames[0]]);
-      if (inInterceptor) {
-        arguments.add(js('this')[fieldNames[2]]);
-      }
-      for (int i = 0; i < parameterCount; i++) {
-        String name = 'p$i';
-        parameters.add(name);
-        arguments.add(js(name));
-      }
-
-      jsAst.Expression fun = js.fun(
-          parameters,
-          js.return_(
-              js('this')[fieldNames[1]]['call'](arguments)));
-      boundClosureBuilder.addProperty(invocationName, fun);
-
-      addParameterStubs(callElement, boundClosureBuilder.addProperty);
-
-      void emitFunctionTypeSignature(Element method, FunctionType methodType) {
-        jsAst.Expression encoding = backend.rti.getSignatureEncoding(
-            methodType, js('this')[fieldNames[0]]);
-        String operatorSignature = namer.operatorSignature();
-        boundClosureBuilder.addProperty(operatorSignature, encoding);
-      }
-
-      void emitIsFunctionTypeTest(FunctionType functionType) {
-        String operator = namer.operatorIsType(functionType);
-        boundClosureBuilder.addProperty(operator,
-            new jsAst.LiteralBool(true));
-      }
-
-      generateFunctionTypeTests(member, memberType, functionTypeChecks,
-          emitFunctionTypeSignature, emitIsFunctionTypeTest);
-
-      boundClosures.add(
-          js('$classesCollector.$mangledName = #',
-             js('[${namer.globalObjectFor(closureClassElement)}, #]',
-                boundClosureBuilder.toObjectInitializer())));
-
-      closureClass = namer.isolateAccess(closureClassElement);
-
-      // Cache it.
-      if (canBeShared) {
-        cache[parameterCount] = closureClass;
-      }
-    }
-
-    // And finally the getter.
-    String getterName = namer.getterName(member);
-    String targetName = namer.instanceMethodName(member);
-
-    List<String> parameters = <String>[];
-    List<jsAst.Expression> arguments = <jsAst.Expression>[];
-    arguments.add(js('this'));
-    jsAst.PropertyAccess method =
-        backend.namer.elementAccess(classElement)['prototype'][targetName];
-
-    arguments.add(method);
-    if (inInterceptor) {
-      String receiverArg = fieldNames[2];
-      parameters.add(receiverArg);
-      arguments.add(js(receiverArg));
-    } else {
-      // Put null in the intercepted receiver field.
-      arguments.add(new jsAst.LiteralNull());
-    }
-    arguments.add(js.string(targetName));
-
-    jsAst.Expression getterFunction = js.fun(
-        parameters, js.return_(js(closureClass).newWith(arguments)));
-
-    defineStub(getterName, getterFunction);
-  }
-
-  /**
-   * Documentation wanted -- johnniwinther
-   *
-   * Invariant: [member] must be a declaration element.
-   */
-  void emitCallStubForGetter(Element member,
-                             Set<Selector> selectors,
-                             DefineStubFunction defineStub) {
-    assert(invariant(member, member.isDeclaration));
-    LibraryElement memberLibrary = member.getLibrary();
-    // If the method is intercepted, the stub gets the
-    // receiver explicitely and we need to pass it to the getter call.
-    bool isInterceptedMethod = backend.isInterceptedMethod(member);
-
-    const String receiverArgumentName = r'$receiver';
-
-    jsAst.Expression buildGetter() {
-      if (member.isGetter()) {
-        String getterName = namer.getterName(member);
-        return js('this')[getterName](
-            isInterceptedMethod
-                ? <jsAst.Expression>[js(receiverArgumentName)]
-                : <jsAst.Expression>[]);
-      } else {
-        String fieldName = member.hasFixedBackendName()
-            ? member.fixedBackendName()
-            : namer.instanceFieldName(member);
-        return js('this')[fieldName];
-      }
-    }
-
-    // Two selectors may match but differ only in type.  To avoid generating
-    // identical stubs for each we track untyped selectors which already have
-    // stubs.
-    Set<Selector> generatedSelectors = new Set<Selector>();
-    for (Selector selector in selectors) {
-      if (selector.applies(member, compiler)) {
-        selector = selector.asUntyped;
-        if (generatedSelectors.contains(selector)) continue;
-        generatedSelectors.add(selector);
-
-        String invocationName = namer.invocationName(selector);
-        Selector callSelector = new Selector.callClosureFrom(selector);
-        String closureCallName = namer.invocationName(callSelector);
-
-        List<jsAst.Parameter> parameters = <jsAst.Parameter>[];
-        List<jsAst.Expression> arguments = <jsAst.Expression>[];
-        if (isInterceptedMethod) {
-          parameters.add(new jsAst.Parameter(receiverArgumentName));
-        }
-
-        for (int i = 0; i < selector.argumentCount; i++) {
-          String name = 'arg$i';
-          parameters.add(new jsAst.Parameter(name));
-          arguments.add(js(name));
-        }
-
-        jsAst.Fun function = js.fun(
-            parameters,
-            js.return_(buildGetter()[closureCallName](arguments)));
-
-        defineStub(invocationName, function);
-      }
+      new ClassBuilder()
+          ..addProperty(namer.getBailoutName(element), bailoutCode)
+          ..writeOn_DO_NOT_USE(
+              bufferForElement(element, eagerBuffer), compiler, ',$n$n');
     }
   }
 
@@ -2887,25 +2137,6 @@
 ''');
   }
 
-  /**
-   * Documentation wanted -- johnniwinther
-   *
-   * Invariant: [member] must be a declaration element.
-   */
-  void emitExtraAccessors(Element member, ClassBuilder builder) {
-    assert(invariant(member, member.isDeclaration));
-    if (member.isGetter() || member.isField()) {
-      Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
-      if (selectors != null && !selectors.isEmpty) {
-        emitCallStubForGetter(member, selectors, builder.addProperty);
-      }
-    } else if (member.isFunction()) {
-      if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) {
-        emitDynamicFunctionGetter(member, builder.addProperty);
-      }
-    }
-  }
-
   // Identify the noSuchMethod handlers that are so simple that we can
   // generate them programatically.
   bool isTrivialNsmHandler(
@@ -2948,7 +2179,7 @@
       for (Selector selector in selectors) {
         TypeMask mask = selector.mask;
         if (mask == null) {
-          mask = new TypeMask.subclass(compiler.objectClass.rawType);
+          mask = new TypeMask.subclass(compiler.objectClass);
         }
 
         if (!mask.needsNoSuchMethodHandling(selector, compiler)) continue;
@@ -3760,33 +2991,6 @@
     });
   }
 
-  jsAst.Fun extendWithMetadata(FunctionElement element, jsAst.Fun code) {
-    if (!backend.retainMetadataOf(element)) return code;
-    return compiler.withCurrentElement(element, () {
-      List<int> metadata = <int>[];
-      FunctionSignature signature = element.functionSignature;
-      if (element.isConstructor()) {
-        metadata.add(reifyType(element.getEnclosingClass().thisType));
-      } else {
-        metadata.add(reifyType(signature.returnType));
-      }
-      signature.forEachParameter((Element parameter) {
-        metadata
-            ..add(reifyName(parameter.name))
-            ..add(reifyType(parameter.computeType(compiler)));
-      });
-      Link link = element.metadata;
-      // TODO(ahe): Why is metadata sometimes null?
-      if (link != null) {
-        for (; !link.isEmpty; link = link.tail) {
-          metadata.add(reifyMetadata(link.head));
-        }
-      }
-      code.body.statements.add(js.string(metadata.join(',')).toStatement());
-      return code;
-    });
-  }
-
   void emitMetadata(CodeBuffer buffer) {
     var literals = backend.typedefTypeLiterals.toList();
     Elements.sortedByPosition(literals);
@@ -3890,11 +3094,11 @@
       }
 
       // As a side-effect, emitting classes will produce "bound closures" in
-      // [boundClosures].  The bound closures are JS AST nodes that add
+      // [methodClosures].  The bound closures are JS AST nodes that add
       // properties to $$ [classesCollector].  The bound closures are not
       // emitted until we have emitted all other classes (native or not).
 
-      // Might create boundClosures.
+      // Might create methodClosures.
       if (!regularClasses.isEmpty) {
         for (ClassElement element in regularClasses) {
           generateClass(element, bufferForElement(element, mainBuffer));
@@ -3902,7 +3106,7 @@
       }
 
       // Emit native classes on [nativeBuffer].
-      // Might create boundClosures.
+      // Might create methodClosures.
       final CodeBuffer nativeBuffer = new CodeBuffer();
       if (!nativeClasses.isEmpty) {
         addComment('Native classes', nativeBuffer);
@@ -3912,23 +3116,25 @@
       nativeEmitter.finishGenerateNativeClasses();
       nativeEmitter.assembleCode(nativeBuffer);
 
-      // Might create boundClosures.
+      // Might create methodClosures.
       if (!deferredClasses.isEmpty) {
         for (ClassElement element in deferredClasses) {
           generateClass(element, bufferForElement(element, mainBuffer));
         }
       }
 
-      emitStaticFunctionClosures();
+      containerBuilder.emitStaticFunctionClosures();
 
-      addComment('Bound closures', mainBuffer);
-      // Now that we have emitted all classes, we know all the bound
+      addComment('Method closures', mainBuffer);
+      // Now that we have emitted all classes, we know all the method
       // closures that will be needed.
-      for (jsAst.Node node in boundClosures) {
+      containerBuilder.methodClosures.forEach((String code, Element closure) {
         // TODO(ahe): Some of these can be deferred.
-        mainBuffer.add(jsAst.prettyPrint(node, compiler));
+        String mangledName = namer.getNameOfClass(closure);
+        mainBuffer.add('$classesCollector.$mangledName$_=$_'
+             '[${namer.globalObjectFor(closure)},$_$code]');
         mainBuffer.add("$N$n");
-      }
+      });
 
       // After this assignment we will produce invalid JavaScript code if we use
       // the classesCollector variable.
@@ -3995,7 +3201,7 @@
           }
         }
         mainBuffer
-            ..write(getReflectionDataParser())
+            ..write(getReflectionDataParser(classesCollector, namer))
             ..write('([$n');
 
         List<Element> sortedElements =
@@ -4065,7 +3271,7 @@
         classesCollector = oldClassesCollector;
       }
 
-      emitStaticFunctionGetters(mainBuffer);
+      containerBuilder.emitStaticFunctionGetters(mainBuffer);
 
       emitRuntimeTypeSupport(mainBuffer);
       emitGetInterceptorMethods(mainBuffer);
@@ -4238,7 +3444,7 @@
                 '$_${namer.isolateName}.prototype$N$n'
                 // The classesCollector object ($$).
                 '$classesCollector$_=$_{};$n')
-        ..write(getReflectionDataParser())
+        ..write(getReflectionDataParser(classesCollector, namer))
         ..write('([$n')
         ..addBuffer(deferredLibraries)
         ..write('])$N');
@@ -4296,139 +3502,4 @@
   bool get areAnyElementsDeferred {
     return compiler.deferredLoadTask.areAnyElementsDeferred;
   }
-
-  // TODO(ahe): Remove this when deferred loading is fully implemented.
-  void warnNotImplemented(Element element, String message) {
-    compiler.reportMessage(compiler.spanFromSpannable(element),
-                           MessageKind.GENERIC.error({'text': message}),
-                           api.Diagnostic.WARNING);
-  }
-
-  // TODO(ahe): This code should be integrated in finishClasses.
-  String getReflectionDataParser() {
-    String metadataField = '"${namer.metadataField}"';
-    String reflectableField = namer.reflectableField;
-    String defaultValuesField = namer.defaultValuesField;
-    String methodsWithOptionalArgumentsField =
-        namer.methodsWithOptionalArgumentsField;
-    return '''
-(function (reflectionData) {
-'''
-// [map] returns an object literal that V8 shouldn't try to optimize with a
-// hidden class. This prevents a potential performance problem where V8 tries
-// to build a hidden class for an object used as a hashMap.
-'''
-  function map(x){x={x:x};delete x.x;return x}
-  if (!init.libraries) init.libraries = [];
-  if (!init.mangledNames) init.mangledNames = map();
-  if (!init.mangledGlobalNames) init.mangledGlobalNames = map();
-  if (!init.statics) init.statics = map();
-  if (!init.interfaces) init.interfaces = map();
-  if (!init.globalFunctions) init.globalFunctions = map();
-  var libraries = init.libraries;
-  var mangledNames = init.mangledNames;
-  var mangledGlobalNames = init.mangledGlobalNames;
-  var hasOwnProperty = Object.prototype.hasOwnProperty;
-  var length = reflectionData.length;
-  for (var i = 0; i < length; i++) {
-    var data = reflectionData[i];
-'''
-// [data] contains these elements:
-// 0. The library name (not unique).
-// 1. The library URI (unique).
-// 2. A function returning the metadata associated with this library.
-// 3. The global object to use for this library.
-// 4. An object literal listing the members of the library.
-// 5. This element is optional and if present it is true and signals that this
-// library is the root library (see dart:mirrors IsolateMirror.rootLibrary).
-//
-// The entries of [data] are built in [assembleProgram] above.
-'''
-    var name = data[0];
-    var uri = data[1];
-    var metadata = data[2];
-    var globalObject = data[3];
-    var descriptor = data[4];
-    var isRoot = !!data[5];
-    var fields = descriptor && descriptor[""];
-    var classes = [];
-    var functions = [];
-    function processStatics(descriptor) {
-      for (var property in descriptor) {
-        if (!hasOwnProperty.call(descriptor, property)) continue;
-        if (property === "") continue;
-        var element = descriptor[property];
-        var firstChar = property.substring(0, 1);
-        var previousProperty;
-        if (firstChar === "+") {
-          mangledGlobalNames[previousProperty] = property.substring(1);
-          if (descriptor[property] == 1) ''' // Break long line.
-'''descriptor[previousProperty].$reflectableField = 1;
-          if (element && element.length) ''' // Break long line.
-'''init.interfaces[previousProperty] = element;
-        } else if (firstChar === "@") {
-          property = property.substring(1);
-          ${namer.CURRENT_ISOLATE}[property][$metadataField] = element;
-        } else if (firstChar === "*") {
-          globalObject[previousProperty].$defaultValuesField = element;
-          var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
-          if (!optionalMethods) {
-            descriptor.$methodsWithOptionalArgumentsField = optionalMethods = {}
-          }
-          optionalMethods[property] = previousProperty;
-        } else if (typeof element === "function") {
-          globalObject[previousProperty = property] = element;
-          functions.push(property);
-          init.globalFunctions[property] = element;
-        } else {
-          previousProperty = property;
-          var newDesc = {};
-          var previousProp;
-          for (var prop in element) {
-            if (!hasOwnProperty.call(element, prop)) continue;
-            firstChar = prop.substring(0, 1);
-            if (prop === "static") {
-              processStatics(init.statics[property] = element[prop]);
-            } else if (firstChar === "+") {
-              mangledNames[previousProp] = prop.substring(1);
-              if (element[prop] == 1) ''' // Break long line.
-'''element[previousProp].$reflectableField = 1;
-            } else if (firstChar === "@" && prop !== "@") {
-              newDesc[prop.substring(1)][$metadataField] = element[prop];
-            } else if (firstChar === "*") {
-              newDesc[previousProp].$defaultValuesField = element[prop];
-              var optionalMethods = newDesc.$methodsWithOptionalArgumentsField;
-              if (!optionalMethods) {
-                newDesc.$methodsWithOptionalArgumentsField = optionalMethods={}
-              }
-              optionalMethods[prop] = previousProp;
-            } else {
-              newDesc[previousProp = prop] = element[prop];
-            }
-          }
-          $classesCollector[property] = [globalObject, newDesc];
-          classes.push(property);
-        }
-      }
-    }
-    processStatics(descriptor);
-    libraries.push([name, uri, classes, functions, metadata, fields, isRoot,
-                    globalObject]);
-  }
-})''';
-  }
 }
-
-const String GENERATED_BY = """
-// Generated by dart2js, the Dart to JavaScript compiler.
-""";
-
-const String HOOKS_API_USAGE = """
-// The code supports the following hooks:
-// dartPrint(message)   - if this function is defined it is called
-//                        instead of the Dart [print] method.
-// dartMainRunner(main) - if this function is defined, the Dart [main]
-//                        method will not be invoked directly.
-//                        Instead, a closure that will invoke [main] is
-//                        passed to [dartMainRunner].
-""";
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
new file mode 100644
index 0000000..15ad85a
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
@@ -0,0 +1,678 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart2js.js_emitter;
+
+/// This class should morph into something that makes it easy to build
+/// JavaScript representations of libraries, class-sides, and instance-sides.
+/// Initially, it is just a placeholder for code that is moved from
+/// [CodeEmitterTask].
+class ContainerBuilder {
+  final Map<Element, Element> staticGetters = new Map<Element, Element>();
+
+  /// A cache of synthesized closures for top-level, static or
+  /// instance methods.
+  final Map<String, Element> methodClosures = <String, Element>{};
+
+  CodeEmitterTask task;
+
+  Namer get namer => task.namer;
+
+  Compiler get compiler => task.compiler;
+
+  String get N => task.N;
+
+  JavaScriptBackend get backend => task.backend;
+
+  /**
+   * Generate stubs to handle invocation of methods with optional
+   * arguments.
+   *
+   * A method like [: foo([x]) :] may be invoked by the following
+   * calls: [: foo(), foo(1), foo(x: 1) :]. See the sources of this
+   * function for detailed examples.
+   */
+  void addParameterStub(FunctionElement member,
+                        Selector selector,
+                        DefineStubFunction defineStub,
+                        Set<String> alreadyGenerated) {
+    FunctionSignature parameters = member.computeSignature(compiler);
+    int positionalArgumentCount = selector.positionalArgumentCount;
+    if (positionalArgumentCount == parameters.parameterCount) {
+      assert(selector.namedArgumentCount == 0);
+      return;
+    }
+    if (parameters.optionalParametersAreNamed
+        && selector.namedArgumentCount == parameters.optionalParameterCount) {
+      // If the selector has the same number of named arguments as the element,
+      // we don't need to add a stub. The call site will hit the method
+      // directly.
+      return;
+    }
+    ConstantHandler handler = compiler.constantHandler;
+    List<SourceString> names = selector.getOrderedNamedArguments();
+
+    String invocationName = namer.invocationName(selector);
+    if (alreadyGenerated.contains(invocationName)) return;
+    alreadyGenerated.add(invocationName);
+
+    bool isInterceptedMethod = backend.isInterceptedMethod(member);
+
+    // If the method is intercepted, we need to also pass the actual receiver.
+    int extraArgumentCount = isInterceptedMethod ? 1 : 0;
+    // Use '$receiver' to avoid clashes with other parameter names. Using
+    // '$receiver' works because [:namer.safeName:] used for getting parameter
+    // names never returns a name beginning with a single '$'.
+    String receiverArgumentName = r'$receiver';
+
+    // The parameters that this stub takes.
+    List<jsAst.Parameter> parametersBuffer =
+        new List<jsAst.Parameter>(selector.argumentCount + extraArgumentCount);
+    // The arguments that will be passed to the real method.
+    List<jsAst.Expression> argumentsBuffer =
+        new List<jsAst.Expression>(
+            parameters.parameterCount + extraArgumentCount);
+
+    int count = 0;
+    if (isInterceptedMethod) {
+      count++;
+      parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName);
+      argumentsBuffer[0] = js(receiverArgumentName);
+      task.interceptorInvocationNames.add(invocationName);
+    }
+
+    int optionalParameterStart = positionalArgumentCount + extraArgumentCount;
+    // Includes extra receiver argument when using interceptor convention
+    int indexOfLastOptionalArgumentInParameters = optionalParameterStart - 1;
+
+    TreeElements elements =
+        compiler.enqueuer.resolution.getCachedElements(member);
+
+    int parameterIndex = 0;
+    parameters.orderedForEachParameter((Element element) {
+      // Use generic names for closures to facilitate code sharing.
+      String jsName = member is ClosureInvocationElement
+          ? 'p${parameterIndex++}'
+          : backend.namer.safeName(element.name.slowToString());
+      assert(jsName != receiverArgumentName);
+      if (count < optionalParameterStart) {
+        parametersBuffer[count] = new jsAst.Parameter(jsName);
+        argumentsBuffer[count] = js(jsName);
+      } else {
+        int index = names.indexOf(element.name);
+        if (index != -1) {
+          indexOfLastOptionalArgumentInParameters = count;
+          // The order of the named arguments is not the same as the
+          // one in the real method (which is in Dart source order).
+          argumentsBuffer[count] = js(jsName);
+          parametersBuffer[optionalParameterStart + index] =
+              new jsAst.Parameter(jsName);
+        } else {
+          Constant value = handler.initialVariableValues[element];
+          if (value == null) {
+            argumentsBuffer[count] = task.constantReference(new NullConstant());
+          } else {
+            if (!value.isNull()) {
+              // If the value is the null constant, we should not pass it
+              // down to the native method.
+              indexOfLastOptionalArgumentInParameters = count;
+            }
+            argumentsBuffer[count] = task.constantReference(value);
+          }
+        }
+      }
+      count++;
+    });
+
+    List body;
+    if (member.hasFixedBackendName()) {
+      body = task.nativeEmitter.generateParameterStubStatements(
+          member, isInterceptedMethod, invocationName,
+          parametersBuffer, argumentsBuffer,
+          indexOfLastOptionalArgumentInParameters);
+    } else {
+      body = [js.return_(
+          js('this')[namer.getNameOfInstanceMember(member)](argumentsBuffer))];
+    }
+
+    jsAst.Fun function = js.fun(parametersBuffer, body);
+
+    defineStub(invocationName, function);
+
+    String reflectionName = task.getReflectionName(selector, invocationName);
+    if (reflectionName != null) {
+      var reflectable =
+          js(backend.isAccessibleByReflection(member) ? '1' : '0');
+      defineStub('+$reflectionName', reflectable);
+    }
+  }
+
+  void addParameterStubs(FunctionElement member,
+                         DefineStubFunction defineStub) {
+    // We fill the lists depending on the selector. For example,
+    // take method foo:
+    //    foo(a, b, {c, d});
+    //
+    // We may have multiple ways of calling foo:
+    // (1) foo(1, 2);
+    // (2) foo(1, 2, c: 3);
+    // (3) foo(1, 2, d: 4);
+    // (4) foo(1, 2, c: 3, d: 4);
+    // (5) foo(1, 2, d: 4, c: 3);
+    //
+    // What we generate at the call sites are:
+    // (1) foo$2(1, 2);
+    // (2) foo$3$c(1, 2, 3);
+    // (3) foo$3$d(1, 2, 4);
+    // (4) foo$4$c$d(1, 2, 3, 4);
+    // (5) foo$4$c$d(1, 2, 3, 4);
+    //
+    // The stubs we generate are (expressed in Dart):
+    // (1) foo$2(a, b) => foo$4$c$d(a, b, null, null)
+    // (2) foo$3$c(a, b, c) => foo$4$c$d(a, b, c, null);
+    // (3) foo$3$d(a, b, d) => foo$4$c$d(a, b, null, d);
+    // (4) No stub generated, call is direct.
+    // (5) No stub generated, call is direct.
+
+    // Keep a cache of which stubs have already been generated, to
+    // avoid duplicates. Note that even if selectors are
+    // canonicalized, we would still need this cache: a typed selector
+    // on A and a typed selector on B could yield the same stub.
+    Set<String> generatedStubNames = new Set<String>();
+    bool isClosureInvocation =
+        member.name == namer.closureInvocationSelectorName;
+    if (backend.isNeededForReflection(member) ||
+        (compiler.enabledFunctionApply && isClosureInvocation)) {
+      // If [Function.apply] is called, we pessimistically compile all
+      // possible stubs for this closure.
+      FunctionSignature signature = member.computeSignature(compiler);
+      Set<Selector> selectors = signature.optionalParametersAreNamed
+          ? computeSeenNamedSelectors(member)
+          : computeOptionalSelectors(signature, member);
+      for (Selector selector in selectors) {
+        addParameterStub(member, selector, defineStub, generatedStubNames);
+      }
+      if (signature.optionalParametersAreNamed && isClosureInvocation) {
+        addCatchAllParameterStub(member, signature, defineStub);
+      }
+    } else {
+      Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
+      if (selectors == null) return;
+      for (Selector selector in selectors) {
+        if (!selector.applies(member, compiler)) continue;
+        addParameterStub(member, selector, defineStub, generatedStubNames);
+      }
+    }
+  }
+
+  Set<Selector> computeSeenNamedSelectors(FunctionElement element) {
+    Set<Selector> selectors = compiler.codegenWorld.invokedNames[element.name];
+    Set<Selector> result = new Set<Selector>();
+    if (selectors == null) return result;
+    for (Selector selector in selectors) {
+      if (!selector.applies(element, compiler)) continue;
+      result.add(selector);
+    }
+    return result;
+  }
+
+  void addCatchAllParameterStub(FunctionElement member,
+                                FunctionSignature signature,
+                                DefineStubFunction defineStub) {
+    // See Primities.applyFunction in js_helper.dart for details.
+    List<jsAst.Property> properties = <jsAst.Property>[];
+    for (Element element in signature.orderedOptionalParameters) {
+      String jsName = backend.namer.safeName(element.name.slowToString());
+      Constant value = compiler.constantHandler.initialVariableValues[element];
+      jsAst.Expression reference = null;
+      if (value == null) {
+        reference = new jsAst.LiteralNull();
+      } else {
+        reference = task.constantReference(value);
+      }
+      properties.add(new jsAst.Property(js.string(jsName), reference));
+    }
+    defineStub(
+        backend.namer.callCatchAllName,
+        js.fun([], js.return_(new jsAst.ObjectInitializer(properties))));
+  }
+
+  /**
+   * Compute the set of possible selectors in the presence of optional
+   * non-named parameters.
+   */
+  Set<Selector> computeOptionalSelectors(FunctionSignature signature,
+                                         FunctionElement element) {
+    Set<Selector> selectors = new Set<Selector>();
+    // Add the selector that does not have any optional argument.
+    selectors.add(new Selector(SelectorKind.CALL,
+                               element.name,
+                               element.getLibrary(),
+                               signature.requiredParameterCount,
+                               <SourceString>[]));
+
+    // For each optional parameter, we increment the number of passed
+    // argument.
+    for (int i = 1; i <= signature.optionalParameterCount; i++) {
+      selectors.add(new Selector(SelectorKind.CALL,
+                                 element.name,
+                                 element.getLibrary(),
+                                 signature.requiredParameterCount + i,
+                                 <SourceString>[]));
+    }
+    return selectors;
+  }
+
+  void emitStaticFunctionGetters(CodeBuffer eagerBuffer) {
+    task.addComment('Static function getters', task.mainBuffer);
+    for (FunctionElement element in
+             Elements.sortedByPosition(staticGetters.keys)) {
+      Element closure = staticGetters[element];
+      CodeBuffer buffer =
+          task.isDeferred(element) ? task.deferredConstants : eagerBuffer;
+      String closureClass = namer.isolateAccess(closure);
+      String name = namer.getStaticClosureName(element);
+
+      String closureName = namer.getStaticClosureName(element);
+      jsAst.Node assignment = js(
+          'init.globalFunctions["$closureName"] ='
+          ' ${namer.globalObjectFor(element)}.$name ='
+          ' new $closureClass(#, "$closureName")',
+          namer.elementAccess(element));
+      buffer.write(jsAst.prettyPrint(assignment, compiler));
+      buffer.write('$N');
+    }
+  }
+
+  void emitStaticFunctionClosures() {
+    Set<FunctionElement> functionsNeedingGetter =
+        compiler.codegenWorld.staticFunctionsNeedingGetter;
+    for (FunctionElement element in
+             Elements.sortedByPosition(functionsNeedingGetter)) {
+      String superName = namer.getNameOfClass(compiler.closureClass);
+      int parameterCount = element.functionSignature.parameterCount;
+      String name = 'Closure\$$parameterCount';
+      assert(task.instantiatedClasses.contains(compiler.closureClass));
+
+      ClassElement closureClassElement = new ClosureClassElement(
+          null, new SourceString(name), compiler, element,
+          element.getCompilationUnit());
+      // Now add the methods on the closure class. The instance method does not
+      // have the correct name. Since [addParameterStubs] use the name to create
+      // its stubs we simply create a fake element with the correct name.
+      // Note: the callElement will not have any enclosingElement.
+      FunctionElement callElement =
+          new ClosureInvocationElement(namer.closureInvocationSelectorName,
+                                       element);
+
+      String invocationName = namer.instanceMethodName(callElement);
+      String mangledName = namer.getNameOfClass(closureClassElement);
+
+      // Define the constructor with a name so that Object.toString can
+      // find the class name of the closure class.
+      ClassBuilder closureBuilder = new ClassBuilder();
+      // If a static function is used as a closure we need to add its name
+      // in case it is used in spawnFunction.
+      String methodName = namer.STATIC_CLOSURE_NAME_NAME;
+      List<String> fieldNames = <String>[invocationName, methodName];
+      closureBuilder.addProperty('',
+          js.string("$superName;${fieldNames.join(',')}"));
+
+      addParameterStubs(callElement, closureBuilder.addProperty);
+
+      void emitFunctionTypeSignature(Element method, FunctionType methodType) {
+        RuntimeTypes rti = backend.rti;
+        // [:() => null:] is dummy encoding of [this] which is never needed for
+        // the encoding of the type of the static [method].
+        jsAst.Expression encoding =
+            rti.getSignatureEncoding(methodType, js('null'));
+        String operatorSignature = namer.operatorSignature();
+        // TODO(johnniwinther): Make MiniJsParser support function expressions.
+        closureBuilder.addProperty(operatorSignature, encoding);
+      }
+
+      void emitIsFunctionTypeTest(FunctionType functionType) {
+        String operator = namer.operatorIsType(functionType);
+        closureBuilder.addProperty(operator, js('true'));
+      }
+
+      FunctionType methodType = element.computeType(compiler);
+      Map<FunctionType, bool> functionTypeChecks =
+          task.getFunctionTypeChecksOn(methodType);
+      task.generateFunctionTypeTests(element, methodType, functionTypeChecks,
+          emitFunctionTypeSignature, emitIsFunctionTypeTest);
+
+      closureClassElement =
+          addClosureIfNew(closureBuilder, closureClassElement, fieldNames);
+      staticGetters[element] = closureClassElement;
+
+    }
+  }
+
+  ClassElement addClosureIfNew(ClassBuilder builder,
+                               ClassElement closure,
+                               List<String> fieldNames) {
+    String key =
+        jsAst.prettyPrint(builder.toObjectInitializer(), compiler).getText();
+    return methodClosures.putIfAbsent(key, () {
+      String mangledName = namer.getNameOfClass(closure);
+      emitClosureInPrecompiledFunction(mangledName, fieldNames);
+      return closure;
+    });
+  }
+
+  void emitClosureInPrecompiledFunction(String mangledName,
+                                        List<String> fieldNames) {
+    List<String> fields = fieldNames;
+    String constructorName = mangledName;
+    task.precompiledFunction.add(new jsAst.FunctionDeclaration(
+        new jsAst.VariableDeclaration(constructorName),
+        js.fun(fields, fields.map(
+            (name) => js('this.$name = $name')).toList())));
+    task.precompiledFunction.addAll([
+        js('$constructorName.builtin\$cls = "$constructorName"'),
+        js('\$desc=\$collectedClasses.$constructorName'),
+        js.if_('\$desc instanceof Array', js('\$desc = \$desc[1]')),
+        js('$constructorName.prototype = \$desc'),
+    ]);
+
+    task.precompiledConstructorNames.add(js(constructorName));
+  }
+
+  /**
+   * Documentation wanted -- johnniwinther
+   *
+   * Invariant: [member] must be a declaration element.
+   */
+  void emitDynamicFunctionGetter(FunctionElement member,
+                                 DefineStubFunction defineStub) {
+    assert(invariant(member, member.isDeclaration));
+    assert(task.instantiatedClasses.contains(compiler.boundClosureClass));
+    // For every method that has the same name as a property-get we create a
+    // getter that returns a bound closure. Say we have a class 'A' with method
+    // 'foo' and somewhere in the code there is a dynamic property get of
+    // 'foo'. Then we generate the following code (in pseudo Dart/JavaScript):
+    //
+    // class A {
+    //    foo(x, y, z) { ... } // Original function.
+    //    get foo { return new BoundClosure499(this, "foo"); }
+    // }
+    // class BoundClosure499 extends BoundClosure {
+    //   BoundClosure499(this.self, this.name);
+    //   $call3(x, y, z) { return self[name](x, y, z); }
+    // }
+
+    bool hasOptionalParameters = member.optionalParameterCount(compiler) != 0;
+    int parameterCount = member.parameterCount(compiler);
+
+    // Intercepted methods take an extra parameter, which is the
+    // receiver of the call.
+    bool inInterceptor = backend.isInterceptedMethod(member);
+    List<String> fieldNames = <String>[];
+    compiler.boundClosureClass.forEachInstanceField((_, Element field) {
+      fieldNames.add(namer.getNameOfInstanceMember(field));
+    });
+
+    ClassElement classElement = member.getEnclosingClass();
+    String name = inInterceptor
+        ? 'BoundClosure\$i${parameterCount}'
+        : 'BoundClosure\$${parameterCount}';
+
+    ClassElement closureClassElement = new ClosureClassElement(
+        null, new SourceString(name), compiler, member,
+        member.getCompilationUnit());
+    String superName = namer.getNameOfClass(closureClassElement.superclass);
+
+    // Define the constructor with a name so that Object.toString can
+    // find the class name of the closure class.
+    ClassBuilder boundClosureBuilder = new ClassBuilder();
+    boundClosureBuilder.addProperty('',
+        js.string("$superName;${fieldNames.join(',')}"));
+    // Now add the methods on the closure class. The instance method does not
+    // have the correct name. Since [addParameterStubs] use the name to create
+    // its stubs we simply create a fake element with the correct name.
+    // Note: the callElement will not have any enclosingElement.
+    FunctionElement callElement = new ClosureInvocationElement(
+        namer.closureInvocationSelectorName, member);
+
+    String invocationName = namer.instanceMethodName(callElement);
+
+    List<String> parameters = <String>[];
+    List<jsAst.Expression> arguments =
+        <jsAst.Expression>[js('this')[fieldNames[0]]];
+    if (inInterceptor) {
+      arguments.add(js('this')[fieldNames[2]]);
+    }
+    for (int i = 0; i < parameterCount; i++) {
+      String name = 'p$i';
+      parameters.add(name);
+      arguments.add(js(name));
+    }
+
+    jsAst.Expression fun = js.fun(
+        parameters,
+        js.return_(
+            js('this')[fieldNames[1]]['call'](arguments)));
+    boundClosureBuilder.addProperty(invocationName, fun);
+
+    addParameterStubs(callElement, boundClosureBuilder.addProperty);
+
+    void emitFunctionTypeSignature(Element method, FunctionType methodType) {
+      jsAst.Expression encoding = backend.rti.getSignatureEncoding(
+          methodType, js('this')[fieldNames[0]]);
+      String operatorSignature = namer.operatorSignature();
+      boundClosureBuilder.addProperty(operatorSignature, encoding);
+    }
+
+    void emitIsFunctionTypeTest(FunctionType functionType) {
+      String operator = namer.operatorIsType(functionType);
+      boundClosureBuilder.addProperty(operator,
+          new jsAst.LiteralBool(true));
+    }
+
+    DartType memberType = member.computeType(compiler);
+    Map<FunctionType, bool> functionTypeChecks =
+        task.getFunctionTypeChecksOn(memberType);
+
+    task.generateFunctionTypeTests(member, memberType, functionTypeChecks,
+        emitFunctionTypeSignature, emitIsFunctionTypeTest);
+
+    closureClassElement =
+        addClosureIfNew(boundClosureBuilder, closureClassElement, fieldNames);
+
+    String closureClass = namer.isolateAccess(closureClassElement);
+
+    // And finally the getter.
+    String getterName = namer.getterName(member);
+    String targetName = namer.instanceMethodName(member);
+
+    parameters = <String>[];
+    jsAst.PropertyAccess method =
+        backend.namer.elementAccess(classElement)['prototype'][targetName];
+    arguments = <jsAst.Expression>[js('this'), method];
+
+    if (inInterceptor) {
+      String receiverArg = fieldNames[2];
+      parameters.add(receiverArg);
+      arguments.add(js(receiverArg));
+    } else {
+      // Put null in the intercepted receiver field.
+      arguments.add(new jsAst.LiteralNull());
+    }
+
+    arguments.add(js.string(targetName));
+
+    jsAst.Expression getterFunction = js.fun(
+        parameters, js.return_(js(closureClass).newWith(arguments)));
+
+    defineStub(getterName, getterFunction);
+  }
+
+  /**
+   * Documentation wanted -- johnniwinther
+   *
+   * Invariant: [member] must be a declaration element.
+   */
+  void emitCallStubForGetter(Element member,
+                             Set<Selector> selectors,
+                             DefineStubFunction defineStub) {
+    assert(invariant(member, member.isDeclaration));
+    LibraryElement memberLibrary = member.getLibrary();
+    // If the method is intercepted, the stub gets the
+    // receiver explicitely and we need to pass it to the getter call.
+    bool isInterceptedMethod = backend.isInterceptedMethod(member);
+
+    const String receiverArgumentName = r'$receiver';
+
+    jsAst.Expression buildGetter() {
+      if (member.isGetter()) {
+        String getterName = namer.getterName(member);
+        return js('this')[getterName](
+            isInterceptedMethod
+                ? <jsAst.Expression>[js(receiverArgumentName)]
+                : <jsAst.Expression>[]);
+      } else {
+        String fieldName = member.hasFixedBackendName()
+            ? member.fixedBackendName()
+            : namer.instanceFieldName(member);
+        return js('this')[fieldName];
+      }
+    }
+
+    // Two selectors may match but differ only in type.  To avoid generating
+    // identical stubs for each we track untyped selectors which already have
+    // stubs.
+    Set<Selector> generatedSelectors = new Set<Selector>();
+    for (Selector selector in selectors) {
+      if (selector.applies(member, compiler)) {
+        selector = selector.asUntyped;
+        if (generatedSelectors.contains(selector)) continue;
+        generatedSelectors.add(selector);
+
+        String invocationName = namer.invocationName(selector);
+        Selector callSelector = new Selector.callClosureFrom(selector);
+        String closureCallName = namer.invocationName(callSelector);
+
+        List<jsAst.Parameter> parameters = <jsAst.Parameter>[];
+        List<jsAst.Expression> arguments = <jsAst.Expression>[];
+        if (isInterceptedMethod) {
+          parameters.add(new jsAst.Parameter(receiverArgumentName));
+        }
+
+        for (int i = 0; i < selector.argumentCount; i++) {
+          String name = 'arg$i';
+          parameters.add(new jsAst.Parameter(name));
+          arguments.add(js(name));
+        }
+
+        jsAst.Fun function = js.fun(
+            parameters,
+            js.return_(buildGetter()[closureCallName](arguments)));
+
+        defineStub(invocationName, function);
+      }
+    }
+  }
+
+  /**
+   * Documentation wanted -- johnniwinther
+   *
+   * Invariant: [member] must be a declaration element.
+   */
+  void emitExtraAccessors(Element member, ClassBuilder builder) {
+    assert(invariant(member, member.isDeclaration));
+    if (member.isGetter() || member.isField()) {
+      Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
+      if (selectors != null && !selectors.isEmpty) {
+        emitCallStubForGetter(member, selectors, builder.addProperty);
+      }
+    } else if (member.isFunction()) {
+      if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) {
+        emitDynamicFunctionGetter(member, builder.addProperty);
+      }
+    }
+  }
+
+  void addMember(Element member, ClassBuilder builder) {
+    assert(invariant(member, member.isDeclaration));
+
+    if (member.isField()) {
+      addMemberField(member, builder);
+    } else if (member.isFunction() ||
+               member.isGenerativeConstructorBody() ||
+               member.isGenerativeConstructor() ||
+               member.isAccessor()) {
+      addMemberMethod(member, builder);
+    } else {
+      compiler.internalErrorOnElement(
+          member, 'unexpected kind: "${member.kind}"');
+    }
+    if (member.isInstanceMember()) emitExtraAccessors(member, builder);
+  }
+
+  void addMemberMethod(FunctionElement member, ClassBuilder builder) {
+    if (member.isAbstract(compiler)) return;
+    jsAst.Expression code = backend.generatedCode[member];
+    if (code == null) return;
+    String name = namer.getNameOfMember(member);
+    if (backend.isInterceptedMethod(member)) {
+      task.interceptorInvocationNames.add(name);
+    }
+    code = extendWithMetadata(member, code);
+    builder.addProperty(name, code);
+    String reflectionName = task.getReflectionName(member, name);
+    if (reflectionName != null) {
+      var reflectable =
+          js(backend.isAccessibleByReflection(member) ? '1' : '0');
+      builder.addProperty('+$reflectionName', reflectable);
+      jsAst.Node defaultValues = task.reifyDefaultArguments(member);
+      if (defaultValues != null) {
+        String unmangledName = member.name.slowToString();
+        builder.addProperty('*$unmangledName', defaultValues);
+      }
+    }
+    code = backend.generatedBailoutCode[member];
+    if (code != null) {
+      builder.addProperty(namer.getBailoutName(member), code);
+    }
+    if (member.isInstanceMember()) {
+      // TODO(ahe): Where is this done for static/top-level methods?
+      FunctionSignature parameters = member.computeSignature(compiler);
+      if (!parameters.optionalParameters.isEmpty) {
+        addParameterStubs(member, builder.addProperty);
+      }
+    }
+  }
+
+  void addMemberField(VariableElement member, ClassBuilder builder) {
+    // For now, do nothing.
+  }
+
+  jsAst.Fun extendWithMetadata(FunctionElement element, jsAst.Fun code) {
+    if (!backend.retainMetadataOf(element)) return code;
+    return compiler.withCurrentElement(element, () {
+      List<int> metadata = <int>[];
+      FunctionSignature signature = element.functionSignature;
+      if (element.isConstructor()) {
+        metadata.add(task.reifyType(element.getEnclosingClass().thisType));
+      } else {
+        metadata.add(task.reifyType(signature.returnType));
+      }
+      signature.forEachParameter((Element parameter) {
+        metadata
+            ..add(task.reifyName(parameter.name))
+            ..add(task.reifyType(parameter.computeType(compiler)));
+      });
+      Link link = element.metadata;
+      // TODO(ahe): Why is metadata sometimes null?
+      if (link != null) {
+        for (; !link.isEmpty; link = link.tail) {
+          metadata.add(task.reifyMetadata(link.head));
+        }
+      }
+      code.body.statements.add(js.string(metadata.join(',')).toStatement());
+      return code;
+    });
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart
new file mode 100644
index 0000000..7a3e055
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart2js.js_emitter;
+
+/// Enables debugging of fast/slow objects using V8-specific primitives.
+const DEBUG_FAST_OBJECTS = false;
+
+/**
+ * A convenient type alias for some functions that emit keyed values.
+ */
+typedef void DefineStubFunction(String invocationName, jsAst.Expression value);
+
+/**
+ * [member] is a field (instance, static, or top level).
+ *
+ * [name] is the field name that the [Namer] has picked for this field's
+ * storage, that is, the JavaScript property name.
+ *
+ * [accessorName] is the name of the accessor. For instance fields this is
+ * mostly the same as [name] except when [member] is shadowing a field in its
+ * superclass.  For other fields, they are rarely the same.
+ *
+ * [needsGetter] and [needsSetter] represent if a getter or a setter
+ * respectively is needed.  There are many factors in this, for example, if the
+ * accessor can be inlined.
+ *
+ * [needsCheckedSetter] indicates that a checked getter is needed, and in this
+ * case, [needsSetter] is always false. [needsCheckedSetter] is only true when
+ * type assertions are enabled (checked mode).
+ */
+typedef void AcceptField(VariableElement member,
+                         String name,
+                         String accessorName,
+                         bool needsGetter,
+                         bool needsSetter,
+                         bool needsCheckedSetter);
+
+// Function signatures used in the generation of runtime type information.
+typedef void FunctionTypeSignatureEmitter(Element method,
+                                          FunctionType methodType);
+
+// TODO(johnniwinther): Clean up terminology for rti in the emitter.
+typedef void FunctionTypeTestEmitter(FunctionType functionType);
+
+typedef void SubstitutionEmitter(Element element, {bool emitNull});
+
+const String GENERATED_BY = """
+// Generated by dart2js, the Dart to JavaScript compiler.
+""";
+
+const String HOOKS_API_USAGE = """
+// The code supports the following hooks:
+// dartPrint(message)   - if this function is defined it is called
+//                        instead of the Dart [print] method.
+// dartMainRunner(main) - if this function is defined, the Dart [main]
+//                        method will not be invoked directly.
+//                        Instead, a closure that will invoke [main] is
+//                        passed to [dartMainRunner].
+""";
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart
new file mode 100644
index 0000000..dfd526b
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.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.
+
+library dart2js.js_emitter;
+
+import 'dart:collection' show LinkedHashMap, Queue;
+
+import '../common.dart';
+
+import '../js/js.dart' as jsAst;
+
+import '../closure.dart' show
+    ClosureClassElement,
+    ClosureClassMap,
+    ClosureFieldElement;
+
+import '../dart2jslib.dart' show
+    CodeBuffer;
+
+import '../elements/modelx.dart' show
+    FunctionElementX;
+
+import '../js/js.dart' show
+    js;
+
+import '../js_backend/js_backend.dart' show
+    CheckedModeHelper,
+    CheckedModeHelper,
+    ConstantEmitter,
+    JavaScriptBackend,
+    JavaScriptBackend,
+    Namer,
+    NativeEmitter,
+    RuntimeTypes,
+    Substitution,
+    TypeCheck,
+    TypeChecks;
+
+import '../source_file.dart' show
+    SourceFile;
+
+import '../source_map_builder.dart' show
+    SourceMapBuilder;
+
+import '../util/characters.dart' show
+    $$,
+    $A,
+    $HASH,
+    $PERIOD,
+    $Z,
+    $a,
+    $z;
+
+import '../util/uri_extras.dart' show
+    relativize;
+
+part 'class_builder.dart';
+part 'closure_invocation_element.dart';
+part 'code_emitter_task.dart';
+part 'container_builder.dart';
+part 'declarations.dart';
+part 'reflection_data_parser.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
new file mode 100644
index 0000000..d90caf6
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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 dart2js.js_emitter;
+
+// TODO(ahe): This code should be integrated in CodeEmitterTask.finishClasses.
+String getReflectionDataParser(String classesCollector, Namer namer) {
+  String metadataField = '"${namer.metadataField}"';
+  String reflectableField = namer.reflectableField;
+  String defaultValuesField = namer.defaultValuesField;
+  String methodsWithOptionalArgumentsField =
+      namer.methodsWithOptionalArgumentsField;
+  return '''
+(function (reflectionData) {
+'''
+// [map] returns an object literal that V8 shouldn't try to optimize with a
+// hidden class. This prevents a potential performance problem where V8 tries
+// to build a hidden class for an object used as a hashMap.
+'''
+  function map(x){x={x:x};delete x.x;return x}
+  if (!init.libraries) init.libraries = [];
+  if (!init.mangledNames) init.mangledNames = map();
+  if (!init.mangledGlobalNames) init.mangledGlobalNames = map();
+  if (!init.statics) init.statics = map();
+  if (!init.interfaces) init.interfaces = map();
+  if (!init.globalFunctions) init.globalFunctions = map();
+  var libraries = init.libraries;
+  var mangledNames = init.mangledNames;
+  var mangledGlobalNames = init.mangledGlobalNames;
+  var hasOwnProperty = Object.prototype.hasOwnProperty;
+  var length = reflectionData.length;
+  for (var i = 0; i < length; i++) {
+    var data = reflectionData[i];
+'''
+// [data] contains these elements:
+// 0. The library name (not unique).
+// 1. The library URI (unique).
+// 2. A function returning the metadata associated with this library.
+// 3. The global object to use for this library.
+// 4. An object literal listing the members of the library.
+// 5. This element is optional and if present it is true and signals that this
+// library is the root library (see dart:mirrors IsolateMirror.rootLibrary).
+//
+// The entries of [data] are built in [assembleProgram] above.
+'''
+    var name = data[0];
+    var uri = data[1];
+    var metadata = data[2];
+    var globalObject = data[3];
+    var descriptor = data[4];
+    var isRoot = !!data[5];
+    var fields = descriptor && descriptor[""];
+    var classes = [];
+    var functions = [];
+    function processStatics(descriptor) {
+      for (var property in descriptor) {
+        if (!hasOwnProperty.call(descriptor, property)) continue;
+        if (property === "") continue;
+        var element = descriptor[property];
+        var firstChar = property.substring(0, 1);
+        var previousProperty;
+        if (firstChar === "+") {
+          mangledGlobalNames[previousProperty] = property.substring(1);
+          if (descriptor[property] == 1) ''' // Break long line.
+'''descriptor[previousProperty].$reflectableField = 1;
+          if (element && element.length) ''' // Break long line.
+'''init.interfaces[previousProperty] = element;
+        } else if (firstChar === "@") {
+          property = property.substring(1);
+          ${namer.CURRENT_ISOLATE}[property][$metadataField] = element;
+        } else if (firstChar === "*") {
+          globalObject[previousProperty].$defaultValuesField = element;
+          var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
+          if (!optionalMethods) {
+            descriptor.$methodsWithOptionalArgumentsField = optionalMethods = {}
+          }
+          optionalMethods[property] = previousProperty;
+        } else if (typeof element === "function") {
+          globalObject[previousProperty = property] = element;
+          functions.push(property);
+          init.globalFunctions[property] = element;
+        } else {
+          previousProperty = property;
+          var newDesc = {};
+          var previousProp;
+          for (var prop in element) {
+            if (!hasOwnProperty.call(element, prop)) continue;
+            firstChar = prop.substring(0, 1);
+            if (prop === "static") {
+              processStatics(init.statics[property] = element[prop]);
+            } else if (firstChar === "+") {
+              mangledNames[previousProp] = prop.substring(1);
+              if (element[prop] == 1) ''' // Break long line.
+'''element[previousProp].$reflectableField = 1;
+            } else if (firstChar === "@" && prop !== "@") {
+              newDesc[prop.substring(1)][$metadataField] = element[prop];
+            } else if (firstChar === "*") {
+              newDesc[previousProp].$defaultValuesField = element[prop];
+              var optionalMethods = newDesc.$methodsWithOptionalArgumentsField;
+              if (!optionalMethods) {
+                newDesc.$methodsWithOptionalArgumentsField = optionalMethods={}
+              }
+              optionalMethods[prop] = previousProp;
+            } else {
+              newDesc[previousProp = prop] = element[prop];
+            }
+          }
+          $classesCollector[property] = [globalObject, newDesc];
+          classes.push(property);
+        }
+      }
+    }
+    processStatics(descriptor);
+    libraries.push([name, uri, classes, functions, metadata, fields, isRoot,
+                    globalObject]);
+  }
+})''';
+}
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index 5431753..79bb281 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -14,7 +14,6 @@
 import '../resolution/resolution.dart' show Scope;
 import '../dart2jslib.dart';
 import '../dart_types.dart';
-import '../source_file.dart';
 import '../tree/tree.dart';
 import '../util/util.dart' show Spannable, Link;
 import '../util/characters.dart' show $CR, $LF;
@@ -634,7 +633,7 @@
   Dart2JsSourceLocation(this._script, this._span);
 
   int _computeLine() {
-    var sourceFile = _script.file as SourceFile;
+    var sourceFile = _script.file;
     if (sourceFile != null) {
       return sourceFile.getLine(offset) + 1;
     }
@@ -658,7 +657,7 @@
   int _computeColumn() {
     if (length == 0) return 0;
 
-    var sourceFile = _script.file as SourceFile;
+    var sourceFile = _script.file;
     if (sourceFile != null) {
       return sourceFile.getColumn(sourceFile.getLine(offset), offset) + 1;
     }
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors_used.dart b/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
index 98707c6..aad7d8b 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
@@ -134,11 +134,11 @@
     for (Node argument in node.send.arguments) {
       NamedArgument named = argument.asNamedArgument();
       if (named == null) continue;
-      Constant value = compiler.metadataHandler.compileNodeWithDefinitions(
+      Constant value = compiler.constantHandler.compileNodeWithDefinitions(
           named.expression, mapping, isConst: true);
 
       ConstantMapper mapper =
-          new ConstantMapper(compiler.metadataHandler, mapping, compiler);
+          new ConstantMapper(compiler.constantHandler, mapping, compiler);
       named.expression.accept(mapper);
 
       MirrorUsageBuilder builder =
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index 9643027..e475aa7 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -16,7 +16,7 @@
 import 'universe/universe.dart' show SideEffects;
 import 'util/util.dart';
 import 'js/js.dart' as js;
-
+import 'js_emitter/js_emitter.dart' show CodeEmitterTask;
 
 /// This class is a temporary work-around until we get a more powerful DartType.
 class SpecialType {
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 2658d01..af4208d 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -25,6 +25,8 @@
   Selector setIteratorSelector(ForIn node, Selector selector);
   Selector setMoveNextSelector(ForIn node, Selector selector);
   Selector setCurrentSelector(ForIn node, Selector selector);
+  void setConstant(Node node, Constant constant);
+  Constant getConstant(Node node);
 
   /**
    * Returns [:true:] if [node] is a type literal.
@@ -46,6 +48,7 @@
   final Map<Node, DartType> types = new LinkedHashMap<Node, DartType>();
   final Set<Node> superUses = new LinkedHashSet<Node>();
   final Set<Element> otherDependencies = new LinkedHashSet<Element>();
+  final Map<Node, Constant> constants = new Map<Node, Constant>();
   final int hashCode = ++hashCodeCounter;
   static int hashCodeCounter = 0;
 
@@ -140,6 +143,14 @@
     return selectors[node.inToken];
   }
 
+  void setConstant(Node node, Constant constant) {
+    constants[node] = constant;
+  }
+
+  Constant getConstant(Node node) {
+    return constants[node];
+  }
+
   bool isTypeLiteral(Send node) {
     return getType(node) != null;
   }
@@ -348,7 +359,11 @@
       TreeElements elements =
           compiler.enqueuer.resolution.getCachedElements(element);
       if (elements != null) {
-        assert(isConstructor);
+        // TODO(karlklose): Remove the check for [isConstructor]. [elememts]
+        // should never be non-null, not even for constructors.
+        assert(invariant(element, isConstructor,
+            message: 'Non-constructor element $element '
+                     'has already been analyzed.'));
         return elements;
       }
       if (element.isSynthesized) {
@@ -402,7 +417,12 @@
         } else if (tree.initializers != null) {
           error(tree, MessageKind.FUNCTION_WITH_INITIALIZER);
         }
-        visitBody(visitor, tree.body);
+
+        if (!compiler.analyzeSignaturesOnly || tree.isRedirectingFactory) {
+          // We need to analyze the redirecting factory bodies to ensure that
+          // we can analyze compile-time constants.
+          visitor.visit(tree.body);
+        }
 
         // Get the resolution tree and check that the resolved
         // function doesn't use 'super' if it is mixed into another
@@ -448,15 +468,26 @@
     ResolverVisitor visitor = visitorFor(element);
     visitor.useElement(tree, element);
 
-    // TODO(johnniwinther): Avoid analyzing initializers if
-    // [Compiler.analyzeSignaturesOnly] is set.
-    initializerDo(tree, visitor.visit);
+    SendSet send = tree.asSendSet();
+    if (send != null) {
+      // TODO(johnniwinther): Avoid analyzing initializers if
+      // [Compiler.analyzeSignaturesOnly] is set.
+      visitor.visit(send.arguments.head);
+    } else if (element.modifiers.isConst()) {
+      compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER);
+    }
 
     if (Elements.isStaticOrTopLevelField(element)) {
+      visitor.addPostProcessAction(element, () {
+        compiler.constantHandler.compileVariable(
+            element, isConst: element.modifiers.isConst());
+      });
       if (tree.asSendSet() != null) {
-        // TODO(13429): We could do better here by using the
-        // constant handler to figure out if it's a lazy field or not.
-        compiler.backend.registerLazyField(visitor.mapping);
+        if (!element.modifiers.isConst()) {
+          // TODO(johnniwinther): Determine the const-ness eagerly to avoid
+          // unnecessary registrations.
+          compiler.backend.registerLazyField(visitor.mapping);
+        }
       } else {
         compiler.enqueuer.resolution.registerInstantiatedClass(
             compiler.nullClass, visitor.mapping);
@@ -1038,8 +1069,10 @@
       }
       ResolverVisitor visitor = visitorFor(context);
       node.accept(visitor);
-      annotation.value = compiler.metadataHandler.compileNodeWithDefinitions(
+      annotation.value = compiler.constantHandler.compileNodeWithDefinitions(
           node, visitor.mapping, isConst: true);
+      compiler.backend.registerMetadataConstant(annotation.value,
+                                                visitor.mapping);
 
       annotation.resolutionState = STATE_DONE;
     }));
@@ -1390,6 +1423,10 @@
   void unimplemented(Node node, String message) {
     compiler.unimplemented(message, node: node);
   }
+
+  void addPostProcessAction(Element element, PostProcessAction action) {
+    compiler.enqueuer.resolution.addPostProcessAction(element, action);
+  }
 }
 
 abstract class LabelScope {
@@ -1652,7 +1689,7 @@
       // Remove the guarded when this is fixed.
       if (!compiler.enqueuer.resolution.queueIsClosed &&
           addTypeVariableBoundsCheck) {
-        compiler.enqueuer.resolution.addPostProcessAction(
+        visitor.addPostProcessAction(
             visitor.enclosingElement,
             () => checkTypeVariableBounds(node, type));
       }
@@ -2028,6 +2065,11 @@
       }
       parameterNodes = parameterNodes.tail;
     });
+    addPostProcessAction(enclosingElement, () {
+      functionParameters.forEachOptionalParameter((Element parameter) {
+        compiler.constantHandler.compileConstant(parameter);
+      });
+    });
     if (inCheckContext) {
       functionParameters.forEachParameter((Element element) {
         compiler.enqueuer.resolution.registerIsCheck(
@@ -2399,6 +2441,9 @@
         // type literal.
         mapping.setType(node, compiler.typeClass.computeType(compiler));
         world.registerTypeLiteral(target, mapping);
+
+        // Don't try to make constants of calls to type literals.
+        analyzeConstant(node, isConst: !node.isCall);
       }
     }
 
@@ -2510,7 +2555,11 @@
         }
       } else if (target.impliesType()) {
         compiler.backend.registerThrowNoSuchMethod(mapping);
-      } else if (target.modifiers.isFinal() || target.modifiers.isConst()) {
+      } else if (target.modifiers.isFinal() ||
+                 target.modifiers.isConst() ||
+                 (target.isFunction() &&
+                     Elements.isStaticOrTopLevelFunction(target) &&
+                     !target.isSetter())) {
         setter = warnAndCreateErroneousElement(
             node.selector, target.name, MessageKind.CANNOT_RESOLVE_SETTER);
         compiler.backend.registerThrowNoSuchMethod(mapping);
@@ -2615,6 +2664,7 @@
       compiler.reportError(node, MessageKind.UNSUPPORTED_LITERAL_SYMBOL,
                            {'value': node.slowNameString});
     }
+    analyzeConstant(node);
   }
 
   visitStringJuxtaposition(StringJuxtaposition node) {
@@ -2700,7 +2750,7 @@
 
     // Register a post process to check for cycles in the redirection chain and
     // set the actual generative constructor at the end of the chain.
-    compiler.enqueuer.resolution.addPostProcessAction(constructor, () {
+    addPostProcessAction(constructor, () {
       compiler.resolver.resolveRedirectionChain(constructor, node);
     });
 
@@ -2734,7 +2784,9 @@
     Modifiers modifiers = node.modifiers;
     void reportExtraModifier(String modifier) {
       Node modifierNode;
-      for (var nodes = modifiers.nodes; !nodes.isEmpty; nodes = nodes.tail) {
+      for (Link<Node> nodes = modifiers.nodes.nodes;
+           !nodes.isEmpty;
+           nodes = nodes.tail) {
         if (modifier == nodes.head.asIdentifier().source.stringValue) {
           modifierNode = nodes.head;
           break;
@@ -2750,7 +2802,14 @@
     if (modifiers.isVar() && (modifiers.isConst() || node.type != null)) {
       reportExtraModifier('var');
     }
-
+    if (enclosingElement.isFunction()) {
+      if (modifiers.isAbstract()) {
+        reportExtraModifier('abstract');
+      }
+      if (modifiers.isStatic()) {
+        reportExtraModifier('static');
+      }
+    }
     visitor.visit(node.definitions);
   }
 
@@ -2803,7 +2862,7 @@
     if (isSymbolConstructor) {
       if (node.isConst()) {
         Node argumentNode = node.send.arguments.head;
-        Constant name = compiler.metadataHandler.compileNodeWithDefinitions(
+        Constant name = compiler.constantHandler.compileNodeWithDefinitions(
             argumentNode, mapping, isConst: true);
         if (!name.isString()) {
           DartType type = name.computeType(compiler);
@@ -2828,10 +2887,20 @@
     } else if (isMirrorsUsedConstant) {
       compiler.mirrorUsageAnalyzerTask.validate(node, mapping);
     }
+    if (node.isConst()) {
+      analyzeConstant(node);
+    }
 
     return null;
   }
 
+  void analyzeConstant(Node node, {bool isConst: true}) {
+    addPostProcessAction(enclosingElement, () {
+       compiler.constantHandler.compileNodeWithDefinitions(
+           node, mapping, isConst: isConst);
+    });
+  }
+
   bool validateSymbol(Node node, String name, {bool reportError: true}) {
     if (name.isEmpty) return true;
     if (name.startsWith('_')) {
@@ -2915,6 +2984,9 @@
     world.registerInstantiatedType(listType, mapping);
     compiler.backend.registerRequiredType(listType, enclosingElement);
     visit(node.elements);
+    if (node.isConst()) {
+      analyzeConstant(node);
+    }
   }
 
   visitConditional(Conditional node) {
@@ -3130,6 +3202,9 @@
     }
     compiler.backend.registerRequiredType(mapType, enclosingElement);
     node.visitChildren(this);
+    if (node.isConst()) {
+      analyzeConstant(node);
+    }
   }
 
   visitLiteralMapEntry(LiteralMapEntry node) {
@@ -3149,7 +3224,11 @@
     while (!cases.isEmpty) {
       SwitchCase switchCase = cases.head;
       for (Node labelOrCase in switchCase.labelsAndCases) {
-        if (labelOrCase is! Label) continue;
+        CaseMatch caseMatch = labelOrCase.asCaseMatch();
+        if (caseMatch != null) {
+          analyzeConstant(caseMatch.expression);
+          continue;
+        }
         Label label = labelOrCase;
         String labelName = label.slowToString();
 
@@ -3355,8 +3434,7 @@
             bound = element.bound;
           }
         }
-        compiler.enqueuer.resolution.addPostProcessAction(
-            element, checkTypeVariableBound);
+        addPostProcessAction(element, checkTypeVariableBound);
       } else {
         variableElement.bound = compiler.objectClass.computeType(compiler);
       }
@@ -3396,8 +3474,7 @@
       var visitor = new TypedefCyclicVisitor(compiler, element);
       type.accept(visitor, null);
     }
-    compiler.enqueuer.resolution.addPostProcessAction(element,
-                                                      checkCyclicReference);
+    addPostProcessAction(element, checkCyclicReference);
   }
 }
 
@@ -3529,7 +3606,8 @@
         DartType supertype = resolveSupertype(element, superMixin.superclass);
         Link<Node> link = superMixin.mixins.nodes;
         while (!link.isEmpty) {
-          supertype = applyMixin(supertype, resolveType(link.head), node);
+          supertype = applyMixin(
+              supertype, checkMixinType(link.head), link.head);
           link = link.tail;
         }
         element.supertype = supertype;
@@ -3580,6 +3658,17 @@
     return element.computeType(compiler);
   }
 
+  /// Resolves the mixed type for [mixinNode] and checks that the the mixin type
+  /// is not black-listed. The mixin type is returned.
+  DartType checkMixinType(TypeAnnotation mixinNode) {
+    DartType mixinType = resolveType(mixinNode);
+    if (isBlackListed(mixinType)) {
+      compiler.reportError(mixinNode,
+          MessageKind.CANNOT_MIXIN, {'type': mixinType});
+    }
+    return mixinType;
+  }
+
   DartType visitNamedMixinApplication(NamedMixinApplication node) {
     compiler.ensure(element != null);
     compiler.ensure(element.resolutionState == STATE_STARTED);
@@ -3593,10 +3682,10 @@
     DartType supertype = resolveSupertype(element, node.superclass);
     Link<Node> link = node.mixins.nodes;
     while (!link.tail.isEmpty) {
-      supertype = applyMixin(supertype, resolveType(link.head), link.head);
+      supertype = applyMixin(supertype, checkMixinType(link.head), link.head);
       link = link.tail;
     }
-    doApplyMixinTo(element, supertype, resolveType(link.head));
+    doApplyMixinTo(element, supertype, checkMixinType(link.head));
     return element.computeType(compiler);
   }
 
@@ -3903,9 +3992,10 @@
   void visitIdentifier(Identifier node) {
     Element element = context.lookup(node.source);
     if (element == null) {
-      error(node, MessageKind.CANNOT_RESOLVE_TYPE.error, {'typeName': node});
+      compiler.reportError(
+          node, MessageKind.CANNOT_RESOLVE_TYPE.error, {'typeName': node});
     } else if (!element.impliesType()) {
-      error(node, MessageKind.NOT_A_TYPE.error, {'node': node});
+      compiler.reportError(node, MessageKind.NOT_A_TYPE.error, {'node': node});
     } else {
       if (element.isClass()) {
         loadSupertype(element, node);
@@ -3981,6 +4071,11 @@
       VariableElement element =
           new VariableElementX(name, variables, kind, link.head);
       resolver.defineElement(link.head, element);
+      if (definitions.modifiers.isConst()) {
+        compiler.enqueuer.resolution.addPostProcessAction(element, () {
+          compiler.constantHandler.compileVariable(element, isConst: true);
+        });
+      }
     }
   }
 }
@@ -3993,6 +4088,7 @@
   final bool defaultValuesAllowed;
   Link<Element> optionalParameters = const Link<Element>();
   int optionalParameterCount = 0;
+  bool isOptionalParameter = false;
   bool optionalParametersAreNamed = false;
   VariableDefinitions currentDefinitions;
 
@@ -4008,6 +4104,7 @@
       internalError(node, "expected optional parameters");
     }
     optionalParametersAreNamed = (identical(value, '{'));
+    isOptionalParameter = true;
     LinkBuilder<Element> elements = analyzeNodes(node.nodes);
     optionalParameterCount = elements.length;
     optionalParameters = elements.toLink();
@@ -4044,7 +4141,17 @@
     return element;
   }
 
+  void validateName(Identifier node) {
+    SourceString name = node.source;
+    if (isOptionalParameter &&
+        optionalParametersAreNamed &&
+        node.source.isPrivate()) {
+      compiler.reportError(node, MessageKind.PRIVATE_NAMED_PARAMETER);
+    }
+  }
+
   Element visitIdentifier(Identifier node) {
+    validateName(node);
     Element variables = new VariableListElementX.node(currentDefinitions,
         ElementKind.VARIABLE_LIST, enclosingElement);
     // Ensure a parameter is not typed 'void'.
@@ -4057,12 +4164,14 @@
     var identifier = node.selector.asIdentifier();
     if (identifier != null) {
       // Normal parameter: [:Type name:].
+      validateName(identifier);
       return identifier.source;
     } else {
       // Function type parameter: [:void name(DartType arg):].
       var functionExpression = node.selector.asFunctionExpression();
       if (functionExpression != null &&
           functionExpression.name.asIdentifier() != null) {
+        validateName(functionExpression.name);
         return functionExpression.name.asIdentifier().source;
       } else {
         cancel(node,
@@ -4106,9 +4215,11 @@
                node.selector.asFunctionExpression() != null) {
       Element variables = new VariableListElementX.node(currentDefinitions,
           ElementKind.VARIABLE_LIST, enclosingElement);
-      SourceString source = node.selector.asIdentifier() != null ?
-          node.selector.asIdentifier().source :
-          node.selector.asFunctionExpression().name.asIdentifier().source;
+      Identifier identifier = node.selector.asIdentifier() != null ?
+          node.selector.asIdentifier() :
+          node.selector.asFunctionExpression().name.asIdentifier();
+      validateName(identifier);
+      SourceString source = identifier.source;
       element = new VariableElementX(source, variables,
           ElementKind.PARAMETER, node);
     }
@@ -4123,6 +4234,14 @@
   }
 
   Element visitFunctionExpression(FunctionExpression node) {
+    Modifiers modifiers = currentDefinitions.modifiers;
+    if (modifiers.isFinal()) {
+      compiler.reportError(modifiers,
+          MessageKind.FINAL_FUNCTION_TYPE_PARAMETER);
+    }
+    if (modifiers.isVar()) {
+      compiler.reportError(modifiers, MessageKind.VAR_FUNCTION_TYPE_PARAMETER);
+    }
     // This is a function typed parameter.
     // TODO(ahe): Resolve the function type.
     return visit(node.name);
@@ -4238,7 +4357,7 @@
       compiler.backend.registerThrowRuntimeError(resolver.mapping);
     }
     if (inConstContext) {
-      error(diagnosticNode, kind.error, arguments);
+      compiler.reportError(diagnosticNode, kind.error, arguments);
     } else {
       ResolutionWarning warning  =
           new ResolutionWarning(
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index dc912fb..6b955ba 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -899,6 +899,7 @@
     TypeAnnotation bound = popNode();
     Identifier name = popNode();
     pushNode(new TypeVariable(name, bound));
+    rejectBuiltInIdentifier(name);
   }
 
   void endTypeVariables(int count, Token beginToken, Token endToken) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
index 2548c6a..90f2196 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
@@ -143,7 +143,7 @@
       DartType sourceType = source.computeType(compiler);
       if (!sourceType.treatAsDynamic &&
           sourceType.kind == TypeKind.INTERFACE) {
-        TypeMask sourceMask = new TypeMask.subtype(sourceType);
+        TypeMask sourceMask = new TypeMask.subtype(sourceType.element);
         TypeMask speculatedMask = speculativeType.computeMask(compiler);
         if (sourceMask.intersection(speculatedMask, compiler).isEmpty) {
           return false;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 6123f69..70713da 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -57,10 +57,13 @@
           FunctionSignature signature = function.computeSignature(compiler);
           signature.forEachOptionalParameter((Element parameter) {
             // This ensures the default value will be computed.
-            builder.compileVariable(parameter);
+            Constant constant =
+                compiler.constantHandler.getConstantForVariable(parameter);
+            backend.registerCompileTimeConstant(constant, work.resolutionTree);
+            compiler.constantHandler.addCompileTimeConstantForEmission(
+                constant);
           });
         }
-
         if (compiler.tracer.enabled) {
           String name;
           if (element.isMember()) {
@@ -953,21 +956,21 @@
     _current = c;
   }
 
-  /**
-   * Compiles compile-time constants. Never returns [:null:]. If the
-   * initial value is not a compile-time constants, it reports an
-   * internal error.
-   */
-  Constant compileConstant(VariableElement element) {
-    return compiler.constantHandler.compileConstant(element);
+  Constant getConstantForNode(Node node) {
+    ConstantHandler handler = compiler.constantHandler;
+    Constant constant = elements.getConstant(node);
+    assert(invariant(node, constant != null,
+        message: 'No constant computed for $node'));
+    return constant;
   }
 
-  Constant compileVariable(VariableElement element) {
-    return compiler.constantHandler.compileVariable(element);
+  HInstruction addConstant(Node node) {
+    return graph.addConstant(getConstantForNode(node), compiler);
   }
 
   bool isLazilyInitialized(VariableElement element) {
-    Constant initialValue = compileVariable(element);
+    Constant initialValue =
+        compiler.constantHandler.getConstantForVariable(element);
     return initialValue == null;
   }
 
@@ -978,17 +981,14 @@
     if (result == null) {
       Element element = localsHandler.closureData.thisElement;
       ClassElement cls = element.enclosingElement.getEnclosingClass();
-      // Use the raw type because we don't have the type context for the
-      // type parameters.
-      DartType type = cls.rawType;
       if (compiler.world.isUsedAsMixin(cls)) {
         // If the enclosing class is used as a mixin, [:this:] can be
         // of the class that mixins the enclosing class. These two
         // classes do not have a subclass relationship, so, for
         // simplicity, we mark the type as an interface type.
-        result = new HType.nonNullSubtype(type, compiler);
+        result = new HType.nonNullSubtype(cls, compiler);
       } else {
-        result = new HType.nonNullSubclass(type, compiler);
+        result = new HType.nonNullSubclass(cls, compiler);
       }
       cachedTypeOfThis = result;
     }
@@ -1322,7 +1322,8 @@
           && !element.isGenerativeConstructorBody()
           && (selector.mask == null || selector.mask.isNullable)) {
         addWithPosition(
-            new HFieldGet(element, providedArguments[0]), currentNode);
+            new HFieldGet(null, providedArguments[0], isAssignable: false),
+            currentNode);
       }
       InliningState state = enterInlinedMethod(
           function, selector, providedArguments, currentNode);
@@ -1661,7 +1662,7 @@
         includeSuperAndInjectedMembers: true);
 
     InterfaceType type = classElement.computeType(compiler);
-    HType ssaType = new HType.nonNullExact(type, compiler);
+    HType ssaType = new HType.nonNullExact(classElement, compiler);
     List<DartType> instantiatedTypes;
     addInlinedInstantiation(type);
     if (!currentInlinedInstantiations.isEmpty) {
@@ -1807,11 +1808,11 @@
                                    int kind) {
     if (type == null) return original;
     type = type.unalias(compiler);
-    if (type.kind == TypeKind.INTERFACE && !type.isRaw) {
-     HType subtype = new HType.subtype(type, compiler);
-     HInstruction representations = buildTypeArgumentRepresentations(type);
-     add(representations);
-     return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
+    if (type.kind == TypeKind.INTERFACE && !type.treatAsRaw) {
+      HType subtype = new HType.subtype(type.element, compiler);
+      HInstruction representations = buildTypeArgumentRepresentations(type);
+      add(representations);
+      return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
           original, representations);
     } else if (type.kind == TypeKind.TYPE_VARIABLE) {
       HType subtype = original.instructionType;
@@ -2495,9 +2496,7 @@
       }
     });
 
-    HType type = new HType.nonNullExact(
-        compiler.functionClass.computeType(compiler),
-        compiler);
+    HType type = new HType.nonNullExact(compiler.functionClass, compiler);
     push(new HForeignNew(closureClassElement, type, capturedVariables));
 
     Element methodElement = nestedClosureData.closureElement;
@@ -2628,7 +2627,7 @@
       if (element.isField() && !element.isAssignable()) {
         // A static final or const. Get its constant value and inline it if
         // the value can be compiled eagerly.
-        value = compileVariable(element);
+        value = compiler.constantHandler.getConstantForVariable(element);
       }
       if (value != null) {
         HInstruction instruction = graph.addConstant(value, compiler);
@@ -2955,7 +2954,10 @@
   }
 
   HInstruction handleConstantForOptionalParameter(Element parameter) {
-    Constant constant = compileConstant(parameter);
+    Constant constant =
+        compiler.constantHandler.getConstantForVariable(parameter);
+    assert(invariant(parameter, constant != null,
+        message: 'No constant computed for $parameter'));
     return graph.addConstant(constant, compiler);
   }
 
@@ -3481,7 +3483,7 @@
                              Node currentNode,
                              HInstruction newObject) {
     if (!backend.classNeedsRti(type.element)) return;
-    if (!type.isRaw) {
+    if (!type.treatAsRaw) {
       List<HInstruction> inputs = <HInstruction>[];
       type.typeArguments.forEach((DartType argument) {
         inputs.add(analyzeTypeArgument(argument));
@@ -3531,7 +3533,7 @@
         return inferred.isUnknown() ? backend.extendableArrayType : inferred;
       } else if (element.isGenerativeConstructor()) {
         ClassElement cls = element.getEnclosingClass();
-        return new HType.nonNullExact(cls.thisType, compiler);
+        return new HType.nonNullExact(cls.thisType.element, compiler);
       } else {
         return new HType.inferredReturnTypeForElement(
             originalElement, compiler);
@@ -3673,9 +3675,13 @@
     Element element = elements[node];
     if (element.isClass() || element.isTypedef()) {
       // TODO(karlklose): add type representation
-      ConstantHandler handler = compiler.constantHandler;
-      Constant constant = handler.compileNodeWithDefinitions(node, elements);
-      stack.add(graph.addConstant(constant, compiler));
+      if (node.isCall) {
+        // The node itself is not a constant but we register the selector (the
+        // identifier that refers to the class/typedef) as a constant.
+        stack.add(addConstant(node.selector));
+      } else {
+        stack.add(addConstant(node));
+      }
     } else if (element.isTypeVariable()) {
       HInstruction value =
           addTypeVariableReference(element.computeType(compiler));
@@ -3806,11 +3812,9 @@
         generateRuntimeError(node.send, message.toString());
       }
     } else if (node.isConst()) {
-      ConstantHandler handler = compiler.constantHandler;
-      Constant constant = handler.compileNodeWithDefinitions(node, elements);
-      stack.add(graph.addConstant(constant, compiler));
+      stack.add(addConstant(node));
       if (isSymbolConstructor) {
-        ConstructedConstant symbol = constant;
+        ConstructedConstant symbol = elements.getConstant(node);
         StringConstant stringConstant = symbol.fields.single;
         String nameString = stringConstant.toDartString().slowToString();
         compiler.enqueuer.codegen.registerConstSymbol(nameString, elements);
@@ -3834,12 +3838,12 @@
       bool isLength = selector.isGetter()
           && selector.name == const SourceString("length");
       if (isLength || selector.isIndex()) {
-        DartType classType = element.getEnclosingClass().computeType(compiler);
-        HType type = new HType.nonNullExact(classType, compiler);
+        HType type = new HType.nonNullExact(
+            element.getEnclosingClass(), compiler);
         return type.isIndexable(compiler);
       } else if (selector.isIndexSet()) {
-        DartType classType = element.getEnclosingClass().computeType(compiler);
-        HType type = new HType.nonNullExact(classType, compiler);
+        HType type = new HType.nonNullExact(
+            element.getEnclosingClass(), compiler);
         return type.isMutableIndexable(compiler);
       } else {
         return false;
@@ -4126,11 +4130,9 @@
   }
 
   void visitLiteralSymbol(LiteralSymbol node) {
-    ConstantHandler handler = compiler.constantHandler;
-    ConstructedConstant constant =
-        handler.compileNodeWithDefinitions(node, elements);
-    stack.add(graph.addConstant(constant, compiler));
-    compiler.enqueuer.codegen.registerConstSymbol(node.slowNameString, elements);
+    stack.add(addConstant(node));
+    compiler.enqueuer.codegen.registerConstSymbol(
+        node.slowNameString, elements);
   }
 
   void visitStringJuxtaposition(StringJuxtaposition node) {
@@ -4204,7 +4206,7 @@
     }
     HInstruction value;
     if (node.isRedirectingFactoryBody) {
-      FunctionElement element = elements[node.expression];
+      FunctionElement element = elements[node.expression].implementation;
       FunctionElement function = currentElement;
       List<HInstruction> inputs = <HInstruction>[];
       FunctionSignature calleeSignature = element.functionSignature;
@@ -4288,9 +4290,7 @@
     HInstruction instruction;
 
     if (node.isConst()) {
-      ConstantHandler handler = compiler.constantHandler;
-      Constant constant = handler.compileNodeWithDefinitions(node, elements);
-      instruction = graph.addConstant(constant, compiler);
+      instruction = addConstant(node);
     } else {
       List<HInstruction> inputs = <HInstruction>[];
       for (Link<Node> link = node.elements.nodes;
@@ -4487,9 +4487,7 @@
 
   visitLiteralMap(LiteralMap node) {
     if (node.isConst()) {
-      ConstantHandler handler = compiler.constantHandler;
-      Constant constant = handler.compileNodeWithDefinitions(node, elements);
-      stack.add(graph.addConstant(constant, compiler));
+      stack.add(addConstant(node));
       return;
     }
     List<HInstruction> inputs = <HInstruction>[];
@@ -4502,8 +4500,7 @@
     }
     HLiteralList keyValuePairs = buildLiteralList(inputs);
     add(keyValuePairs);
-    HType mapType = new HType.nonNullSubtype(
-        backend.mapLiteralClass.computeType(compiler), compiler);
+    HType mapType = new HType.nonNullSubtype(backend.mapLiteralClass, compiler);
     pushInvokeStatic(node, backend.getMapMaker(), [keyValuePairs], mapType);
   }
 
@@ -4528,9 +4525,7 @@
       for (Node labelOrCase in switchCase.labelsAndCases) {
         if (labelOrCase is CaseMatch) {
           CaseMatch match = labelOrCase;
-          Constant constant =
-              compiler.constantHandler.compileNodeWithDefinitions(
-                  match.expression, elements, isConst: true);
+          Constant constant = getConstantForNode(match.expression);
           if (firstConstantType == null) {
             firstConstantType = constant.computeType(compiler);
             if (nonPrimitiveTypeOverridesEquals(constant)) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 2c22260..7b0b1a1 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -1570,8 +1570,9 @@
       // [node.element] will be enqueued. We're not using the receiver
       // type because our optimizations might end up in a state where the
       // invoke dynamic knows more than the receiver.
+      ClassElement enclosing = node.element.getEnclosingClass();
       HType receiverType = new HType.fromMask(
-          new TypeMask.nonNullExact(node.element.getEnclosingClass().rawType),
+          new TypeMask.nonNullExact(enclosing.declaration),
           compiler);
       return receiverType.refine(selector, compiler);
     }
@@ -1679,7 +1680,7 @@
         // If the selector we need to register a typed getter to the
         // [world]. The emitter needs to know if it needs to emit a
         // bound closure for a method.
-        TypeMask receiverType = new TypeMask.nonNullExact(superClass.rawType);
+        TypeMask receiverType = new TypeMask.nonNullExact(superClass);
         selector = new TypedSelector(receiverType, selector);
         world.registerDynamicGetter(selector);
         methodName = backend.namer.invocationName(selector);
@@ -1696,7 +1697,12 @@
   visitFieldGet(HFieldGet node) {
     use(node.receiver);
     Element element = node.element;
-    if (element == backend.jsIndexableLength) {
+    if (node.isNullCheck) {
+      // We access a JavaScript member we know all objects besides
+      // null and undefined have: V8 does not like accessing a member
+      // that does not exist.
+      push(new js.PropertyAccess.field(pop(), 'toString'), node);
+    } else if (element == backend.jsIndexableLength) {
       // We're accessing a native JavaScript property called 'length'
       // on a JS String or a JS array. Therefore, the name of that
       // property should not be mangled.
@@ -1709,7 +1715,10 @@
         // constant value instead.
         Element element = compiler.findRequiredElement(
             compiler.typedDataLibrary, const SourceString('fetchLength'));
-        Constant constant = compiler.constantHandler.compileConstant(element);
+        Constant constant =
+            compiler.constantHandler.getConstantForVariable(element);
+        assert(invariant(element, constant != null,
+            message: 'No constant computed for $element'));
         var jsConstant = backend.emitter.constantReference(constant);
         push(new js.Call(jsConstant, [pop()]), node);
       } else {
@@ -1817,15 +1826,9 @@
   visitConstant(HConstant node) {
     assert(isGenerateAtUseSite(node));
     generateConstant(node.constant);
-    DartType type = node.constant.computeType(compiler);
-    if (node.constant is ConstructedConstant ||
-        node.constant is InterceptorConstant) {
-      ConstantHandler handler = compiler.constantHandler;
-      handler.registerCompileTimeConstant(node.constant, work.resolutionTree);
-    }
-    if (node.constant is! InterceptorConstant) {
-      world.registerInstantiatedClass(type.element, work.resolutionTree);
-    }
+
+    backend.registerCompileTimeConstant(node.constant, work.resolutionTree);
+    compiler.constantHandler.addCompileTimeConstantForEmission(node.constant);
   }
 
   visitNot(HNot node) {
@@ -2462,20 +2465,22 @@
     TypeMask receiver = input.instructionType.computeMask(compiler);
     TypeMask mask = node.instructionType.computeMask(compiler);
     // Figure out if it is beneficial to turn this into a null check.
-    // V8 generally prefers 'typeof' checks, but for integers and 
+    // V8 generally prefers 'typeof' checks, but for integers and
     // indexable primitives we cannot compile this test into a single
     // typeof check so the null check is cheaper.
-    bool turnIntoNullCheck = (mask.nullable() == receiver)
+    bool turnIntoNumCheck = input.isIntegerOrNull() && node.isInteger();
+    bool turnIntoNullCheck = !turnIntoNumCheck
+        && (mask.nullable() == receiver)
         && (node.isInteger() || node.isIndexablePrimitive(compiler));
     js.Expression test;
     if (turnIntoNullCheck) {
       use(input);
       test = new js.Binary("==", pop(), new js.LiteralNull());
-    } else if (node.isInteger()) {
+    } else if (node.isInteger() && !turnIntoNumCheck) {
       // input is !int
       checkInt(input, '!==');
       test = pop();
-    } else if (node.isNumber()) {
+    } else if (node.isNumber() || turnIntoNumCheck) {
       // input is !num
       checkNum(input, '!==');
       test = pop();
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
index 98e5a73..d80e5a8 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
@@ -85,8 +85,8 @@
     return interceptedClasses
         .where((cls) => cls != compiler.objectClass)
         .map((cls) => backend.classesMixedIntoNativeClasses.contains(cls)
-            ? new TypeMask.subtype(cls.rawType)
-            : new TypeMask.subclass(cls.rawType))
+            ? new TypeMask.subtype(cls)
+            : new TypeMask.subclass(cls))
         .every((mask) => receiverMask.intersection(mask, compiler).isEmpty);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 8c723df..c3dc5a6 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -175,7 +175,8 @@
     // TODO(sra): What is the type of the prototype of an interceptor?
     if (constant.isInterceptor()) return HType.UNKNOWN;
     ObjectConstant objectConstant = constant;
-    return new HBoundedType(new TypeMask.nonNullExact(objectConstant.type));
+    TypeMask mask = new TypeMask.nonNullExact(objectConstant.type.element);
+    return new HBoundedType(mask);
   }
 
   HConstant addConstant(Constant constant, Compiler compiler) {
@@ -1124,18 +1125,20 @@
     // instructions with generics. It has the generic type context
     // available.
     assert(type.kind != TypeKind.TYPE_VARIABLE);
-    assert(type.isRaw || type.kind == TypeKind.FUNCTION);
+    assert(type.treatAsRaw || type.kind == TypeKind.FUNCTION);
     if (type.treatAsDynamic) return this;
-    if (identical(type.element, compiler.objectClass)) return this;
+    // The type element is either a class or the void element.
+    Element element = type.element;
+    if (identical(element, compiler.objectClass)) return this;
     if (type.kind != TypeKind.INTERFACE) {
       return new HTypeConversion(type, kind, HType.UNKNOWN, this);
     } else if (kind == HTypeConversion.BOOLEAN_CONVERSION_CHECK) {
       // Boolean conversion checks work on non-nullable booleans.
       return new HTypeConversion(type, kind, HType.BOOLEAN, this);
-    } else if (kind == HTypeConversion.CHECKED_MODE_CHECK && !type.isRaw) {
-        throw 'creating compound check to $type (this = ${this})';
+    } else if (kind == HTypeConversion.CHECKED_MODE_CHECK && !type.treatAsRaw) {
+      throw 'creating compound check to $type (this = ${this})';
     } else {
-      HType subtype = new HType.subtype(type, compiler);
+      HType subtype = new HType.subtype(element, compiler);
       return new HTypeConversion(type, kind, subtype, this);
     }
   }
@@ -1497,6 +1500,7 @@
 
   HInstruction getDartReceiver(Compiler compiler) => receiver;
   bool onlyThrowsNSM() => true;
+  bool get isNullCheck => element == null;
 
   accept(HVisitor visitor) => visitor.visitFieldGet(this);
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index 333bd7e..1cd4b7d 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -201,11 +201,10 @@
     HType type = input.instructionType;
     if (type.isBoolean()) return input;
     // All values that cannot be 'true' are boolified to false.
-    DartType booleanType = backend.jsBoolClass.computeType(compiler);
     TypeMask mask = type.computeMask(compiler);
     // TODO(kasperl): Get rid of the null check here once all HTypes
     // have a proper mask.
-    if (mask != null && !mask.contains(booleanType, compiler)) {
+    if (mask != null && !mask.contains(backend.jsBoolClass, compiler)) {
       return graph.addConstantBool(false, compiler);
     }
     return node;
@@ -637,7 +636,8 @@
     } else if (!RuntimeTypes.hasTypeArguments(type)) {
       TypeMask expressionMask = expressionType.computeMask(compiler);
       TypeMask typeMask = (element == compiler.nullClass)
-          ? new TypeMask.subtype(type) : new TypeMask.nonNullSubtype(type);
+          ? new TypeMask.subtype(element)
+          : new TypeMask.nonNullSubtype(element);
       if (expressionMask.union(typeMask, compiler) == typeMask) {
         return graph.addConstantBool(true, compiler);
       } else if (expressionMask.intersection(typeMask, compiler).isEmpty) {
@@ -651,7 +651,7 @@
     HInstruction value = node.inputs[0];
     DartType type = node.typeExpression;
     if (type != null) {
-      if (!type.isRaw || type.kind == TypeKind.TYPE_VARIABLE) {
+      if (!type.treatAsRaw || type.kind == TypeKind.TYPE_VARIABLE) {
         return node;
       }
       if (type.kind == TypeKind.FUNCTION) {
@@ -694,7 +694,17 @@
       } else {
         var type = receiver.instructionType.computeMask(compiler);
         if (type.isContainer && type.length != null) {
-          return graph.addConstantInt(type.length, compiler);
+          HInstruction constant = graph.addConstantInt(type.length, compiler);
+          if (type.isNullable) {
+            // If the container can be null, we update all uses of the
+            // length access to use the constant instead, but keep the
+            // length access in the graph, to ensure we still have a
+            // null check.
+            node.block.rewrite(node, constant);
+            return node;
+          } else {
+            return constant;
+          }
         }
       }
     }
@@ -769,7 +779,7 @@
     HInstruction value = node.inputs.last;
     if (compiler.enableTypeAssertions) {
       DartType type = field.computeType(compiler);
-      if (!type.isRaw || type.kind == TypeKind.TYPE_VARIABLE) {
+      if (!type.treatAsRaw || type.kind == TypeKind.TYPE_VARIABLE) {
         // We cannot generate the correct type representation here, so don't
         // inline this access.
         return node;
@@ -948,7 +958,14 @@
       if (current.canThrow() || current.sideEffects.hasSideEffects()) {
         return false;
       }
-      current = current.next;
+      if (current.next == null && current is HGoto) {
+        // We do not merge blocks in our SSA graph, so if this block
+        // just jumps to a single predecessor, visit this predecessor.
+        assert(current.block.successors.length == 1);
+        current = current.block.successors[0].first;
+      } else {
+        current = current.next;
+      }
     } while (current != null);
     return false;
   }
@@ -1503,7 +1520,6 @@
     visitDominatorTree(graph);
   }
 
-
   // Update users of [input] that are dominated by [:dominator.first:]
   // to use [newInput] instead.
   void changeUsesDominatedBy(HBasicBlock dominator,
@@ -1543,7 +1559,7 @@
 
     if (ifUsers.isEmpty && notIfUsers.isEmpty) return;
 
-    HType convertedType = new HType.nonNullSubtype(type, compiler);
+    HType convertedType = new HType.nonNullSubtype(element, compiler);
     HInstruction input = instruction.expression;
     for (HIf ifUser in ifUsers) {
       changeUsesDominatedBy(ifUser.thenBlock, input, convertedType);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
index 60014f2..95b020f 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
@@ -27,6 +27,8 @@
     show ElementX,
          ConstructorBodyElementX;
 
+import '../js_emitter/js_emitter.dart' show CodeEmitterTask;
+
 part 'bailout.dart';
 part 'builder.dart';
 part 'codegen.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
index 659737c..bfdb564 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
@@ -30,8 +30,7 @@
       // TODO(ngeoffray): Avoid creating [TypeMask]s with the string
       // class as base.
       return isNullable
-          ? new HBoundedType(
-                  new TypeMask.exact(backend.jsStringClass.rawType))
+          ? new HBoundedType(new TypeMask.exact(backend.jsStringClass))
           : backend.stringType;
     } else if (mask.containsOnlyBool(compiler)) {
       return isNullable ? HType.BOOLEAN_OR_NULL : HType.BOOLEAN;
@@ -48,33 +47,33 @@
     return new HBoundedType(mask);
   }
 
-  factory HType.exact(DartType type, Compiler compiler) {
-    TypeMask mask = new TypeMask.exact(type);
+  factory HType.exact(ClassElement type, Compiler compiler) {
+    TypeMask mask = new TypeMask.exact(type.declaration);
     return new HType.fromMask(mask, compiler);
   }
 
-  factory HType.subclass(DartType type, Compiler compiler) {
-    TypeMask mask = new TypeMask.subclass(type);
+  factory HType.subclass(ClassElement type, Compiler compiler) {
+    TypeMask mask = new TypeMask.subclass(type.declaration);
     return new HType.fromMask(mask, compiler);
   }
 
-  factory HType.subtype(DartType type, Compiler compiler) {
-    TypeMask mask = new TypeMask.subtype(type);
+  factory HType.subtype(ClassElement type, Compiler compiler) {
+    TypeMask mask = new TypeMask.subtype(type.declaration);
     return new HType.fromMask(mask, compiler);
   }
 
-  factory HType.nonNullExact(DartType type, Compiler compiler) {
-    TypeMask mask = new TypeMask.nonNullExact(type);
+  factory HType.nonNullExact(ClassElement type, Compiler compiler) {
+    TypeMask mask = new TypeMask.nonNullExact(type.declaration);
     return new HType.fromMask(mask, compiler);
   }
 
-  factory HType.nonNullSubclass(DartType type, Compiler compiler) {
-    TypeMask mask = new TypeMask.nonNullSubclass(type);
+  factory HType.nonNullSubclass(ClassElement type, Compiler compiler) {
+    TypeMask mask = new TypeMask.nonNullSubclass(type.declaration);
     return new HType.fromMask(mask, compiler);
   }
 
-  factory HType.nonNullSubtype(DartType type, Compiler compiler) {
-    TypeMask mask = new TypeMask.nonNullSubtype(type);
+  factory HType.nonNullSubtype(ClassElement type, Compiler compiler) {
+    TypeMask mask = new TypeMask.nonNullSubtype(type.declaration);
     return new HType.fromMask(mask, compiler);
   }
 
@@ -123,8 +122,7 @@
   // like [native.SpecialType.JsObject].
   static HType fromNativeType(type, Compiler compiler) {
     if (type == native.SpecialType.JsObject) {
-      return new HType.nonNullExact(
-          compiler.objectClass.computeType(compiler), compiler);
+      return new HType.nonNullExact(compiler.objectClass, compiler);
     } else if (type.isVoid) {
       return HType.NULL;
     } else if (type.element == compiler.nullClass) {
@@ -132,11 +130,11 @@
     } else if (type.treatAsDynamic) {
       return HType.UNKNOWN;
     } else if (compiler.world.hasAnySubtype(type.element)) {
-      return new HType.nonNullSubtype(type, compiler);
+      return new HType.nonNullSubtype(type.element, compiler);
     } else if (compiler.world.hasAnySubclass(type.element)) {
-      return new HType.nonNullSubclass(type, compiler);
+      return new HType.nonNullSubclass(type.element, compiler);
     } else {
-      return new HType.nonNullExact(type, compiler);
+      return new HType.nonNullExact(type.element, compiler);
     }
   }
 
@@ -190,8 +188,7 @@
   }
 
   bool implementsInterface(ClassElement interfaceElement, Compiler compiler) {
-    DartType interfaceType = interfaceElement.computeType(compiler);
-    TypeMask mask = new TypeMask.subtype(interfaceType);
+    TypeMask mask = new TypeMask.subtype(interfaceElement);
     return mask == mask.union(computeMask(compiler), compiler);
   }
 
@@ -280,8 +277,7 @@
   bool canBePrimitiveBoolean(Compiler compiler) => true;
 
   TypeMask computeMask(Compiler compiler) {
-    DartType base = compiler.objectClass.computeType(compiler);
-    return new TypeMask.subclass(base);
+    return new TypeMask.subclass(compiler.objectClass);
   }
 }
 
@@ -295,8 +291,7 @@
   bool canBePrimitiveBoolean(Compiler compiler) => true;
 
   TypeMask computeMask(Compiler compiler) {
-    DartType base = compiler.objectClass.computeType(compiler);
-    return new TypeMask.nonNullSubclass(base);
+    return new TypeMask.nonNullSubclass(compiler.objectClass);
   }
 }
 
@@ -344,8 +339,7 @@
 
   TypeMask computeMask(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType base = backend.jsBoolClass.computeType(compiler);
-    return new TypeMask.exact(base);
+    return new TypeMask.exact(backend.jsBoolClass);
   }
 }
 
@@ -359,8 +353,7 @@
 
   TypeMask computeMask(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType base = backend.jsBoolClass.computeType(compiler);
-    return new TypeMask.nonNullExact(base);
+    return new TypeMask.nonNullExact(backend.jsBoolClass);
   }
 }
 
@@ -372,8 +365,7 @@
 
   TypeMask computeMask(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType base = backend.jsNumberClass.computeType(compiler);
-    return new TypeMask.subclass(base);
+    return new TypeMask.subclass(backend.jsNumberClass);
   }
 }
 
@@ -386,8 +378,7 @@
 
   TypeMask computeMask(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType base = backend.jsNumberClass.computeType(compiler);
-    return new TypeMask.nonNullSubclass(base);
+    return new TypeMask.nonNullSubclass(backend.jsNumberClass);
   }
 }
 
@@ -398,8 +389,7 @@
 
   TypeMask computeMask(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType base = backend.jsIntClass.computeType(compiler);
-    return new TypeMask.exact(base);
+    return new TypeMask.exact(backend.jsIntClass);
   }
 }
 
@@ -412,8 +402,7 @@
 
   TypeMask computeMask(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType base = backend.jsIntClass.computeType(compiler);
-    return new TypeMask.nonNullExact(base);
+    return new TypeMask.nonNullExact(backend.jsIntClass);
   }
 }
 
@@ -424,8 +413,7 @@
 
   TypeMask computeMask(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType base = backend.jsDoubleClass.computeType(compiler);
-    return new TypeMask.exact(base);
+    return new TypeMask.exact(backend.jsDoubleClass);
   }
 }
 
@@ -438,8 +426,7 @@
 
   TypeMask computeMask(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType base = backend.jsDoubleClass.computeType(compiler);
-    return new TypeMask.nonNullExact(base);
+    return new TypeMask.nonNullExact(backend.jsDoubleClass);
   }
 }
 
@@ -460,28 +447,21 @@
 
   bool canBePrimitiveNumber(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType jsNumberType = backend.jsNumberClass.computeType(compiler);
-    DartType jsIntType = backend.jsIntClass.computeType(compiler);
-    DartType jsDoubleType = backend.jsDoubleClass.computeType(compiler);
-    return mask.contains(jsNumberType, compiler)
-        || mask.contains(jsIntType, compiler)
-        || mask.contains(jsDoubleType, compiler);
+    return mask.contains(backend.jsNumberClass, compiler)
+        || mask.contains(backend.jsIntClass, compiler)
+        || mask.contains(backend.jsDoubleClass, compiler);
   }
 
   bool canBePrimitiveBoolean(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType jsBoolType = backend.jsBoolClass.computeType(compiler);
-    return mask.contains(jsBoolType, compiler);
+    return mask.contains(backend.jsBoolClass, compiler);
   }
 
   bool canBePrimitiveArray(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType jsArrayType = backend.jsArrayClass.rawType;
-    DartType jsFixedArrayType = backend.jsFixedArrayClass.rawType;
-    DartType jsExtendableArrayType = backend.jsExtendableArrayClass.rawType;
-    return mask.contains(jsArrayType, compiler)
-        || mask.contains(jsFixedArrayType, compiler)
-        || mask.contains(jsExtendableArrayType, compiler);
+    return mask.contains(backend.jsArrayClass, compiler)
+        || mask.contains(backend.jsFixedArrayClass, compiler)
+        || mask.contains(backend.jsExtendableArrayClass, compiler);
   }
 
   bool isIndexablePrimitive(Compiler compiler) {
@@ -511,8 +491,7 @@
 
   bool canBePrimitiveString(Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    DartType jsStringType = backend.jsStringClass.computeType(compiler);
-    return mask.contains(jsStringType, compiler);
+    return mask.contains(backend.jsStringClass, compiler);
   }
 
   TypeMask computeMask(Compiler compiler) => mask;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
index 8271832..a1cf853 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
@@ -10,7 +10,7 @@
   final Map<int, HInstruction> workmap = new Map<int, HInstruction>();
   final List<int> worklist = new List<int>();
   final Map<HInstruction, Function> pendingOptimizations =
-      new Map<HInstruction, Function>();  
+      new Map<HInstruction, Function>();
 
   final Compiler compiler;
   String get name => 'type propagator';
@@ -176,7 +176,7 @@
     HTypeConversion converted = new HTypeConversion(
         null, kind, type, input, selector);
     instruction.block.addBefore(instruction, converted);
-    input.replaceAllUsersDominatedBy(instruction, converted);    
+    input.replaceAllUsersDominatedBy(instruction, converted);
   }
 
   bool isCheckEnoughForNsmOrAe(HInstruction instruction,
@@ -211,7 +211,7 @@
       if (targets.length == 1) {
         Element target = targets.first;
         ClassElement cls = target.getEnclosingClass();
-        HType type = new HType.nonNullSubclass(cls.rawType, compiler);
+        HType type = new HType.nonNullSubclass(cls, compiler);
         // TODO(ngeoffray): We currently only optimize on primitive
         // types.
         if (!type.isPrimitive(compiler)) return false;
@@ -439,7 +439,7 @@
     }
     return desiredType;
   }
-  
+
   bool hasBeenSpeculativelyOptimized(HInstruction instruction) {
     return savedTypes.containsKey(instruction);
   }
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index 1af2669..2b2a399 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -155,9 +155,7 @@
 
   final ClassElement currentClass;
 
-  /// The type of [:this:]. Can only be accessed if [currentClass] is not null.
   InterfaceType thisType;
-  /// The type of [:super:]. Can only be accessed if [currentClass] is not null.
   InterfaceType superType;
 
   Link<DartType> cascadeTypes = const Link<DartType>();
diff --git a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
index 622e1a2..fb77255 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -414,7 +414,7 @@
     Types types = inferrer.compiler.types;
     bool paramMatches(ConcreteType concrete, VariableElement parameter) {
       DartType parameterType = parameter.variables.type;
-      if (parameterType.treatAsDynamic || parameterType.isRaw) {
+      if (parameterType.treatAsDynamic || parameterType.treatAsRaw) {
         return true;
       }
       for (BaseType baseType in concrete.baseTypes) {
@@ -533,7 +533,7 @@
     throw new UnsupportedError("");
   }
 
-  bool contains(DartType type, Compiler compiler) {
+  bool contains(ClassElement type, Compiler compiler) {
     throw new UnsupportedError("");
   }
 
@@ -816,7 +816,7 @@
       Element enclosing = field.enclosingElement;
       if (enclosing.isClass()) {
         ClassElement cls = enclosing;
-        TypeMask receiverMask = new TypeMask.exact(cls.rawType);
+        TypeMask receiverMask = new TypeMask.exact(cls);
         TypeMask resultMask = concreteTypeToTypeMask(result);
         augmentInferredSelectorType(selector, receiverMask, resultMask);
       }
@@ -974,11 +974,11 @@
       assert(element != null);
       if (element == compiler.backend.numImplementation) {
         return new TypeMask.nonNullSubclass(
-            compiler.backend.numImplementation.rawType);
+            compiler.backend.numImplementation);
       } else if (element == compiler.dynamicClass) {
-        return new TypeMask.nonNullSubclass(compiler.objectClass.rawType);
+        return new TypeMask.nonNullSubclass(compiler.objectClass);
       } else {
-        return new TypeMask.nonNullExact(element.rawType);
+        return new TypeMask.nonNullExact(element);
       }
     }
   }
@@ -1104,8 +1104,8 @@
       // abstract classes than num.
       TypeMask receiverMask =
           (receiverType == compiler.backend.numImplementation)
-              ? new TypeMask.nonNullSubclass(receiverType.rawType)
-              : new TypeMask.nonNullExact(receiverType.rawType);
+              ? new TypeMask.nonNullSubclass(receiverType)
+              : new TypeMask.nonNullExact(receiverType);
       TypeMask resultMask = concreteTypeToTypeMask(result);
       augmentInferredSelectorType(selector, receiverMask, resultMask);
     }
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 03cd53a..cc17100 100644
--- a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
@@ -15,46 +15,31 @@
   static const int SUBCLASS = 2;
   static const int SUBTYPE  = 3;
 
-  final DartType base;
+  final ClassElement base;
   final int flags;
 
-  FlatTypeMask(DartType base, int kind, bool isNullable)
+  FlatTypeMask(ClassElement base, int kind, bool isNullable)
       : this.internal(base, (kind << 1) | (isNullable ? 1 : 0));
 
-  FlatTypeMask.exact(DartType base)
+  FlatTypeMask.exact(ClassElement base)
       : this.internal(base, (EXACT << 1) | 1);
-  FlatTypeMask.subclass(DartType base)
+  FlatTypeMask.subclass(ClassElement base)
       : this.internal(base, (SUBCLASS << 1) | 1);
-  FlatTypeMask.subtype(DartType base)
+  FlatTypeMask.subtype(ClassElement base)
       : this.internal(base, (SUBTYPE << 1) | 1);
 
   const FlatTypeMask.nonNullEmpty(): base = null, flags = 0;
   const FlatTypeMask.empty() : base = null, flags = 1;
 
-  FlatTypeMask.nonNullExact(DartType base)
+  FlatTypeMask.nonNullExact(ClassElement base)
       : this.internal(base, EXACT << 1);
-  FlatTypeMask.nonNullSubclass(DartType base)
+  FlatTypeMask.nonNullSubclass(ClassElement base)
       : this.internal(base, SUBCLASS << 1);
-  FlatTypeMask.nonNullSubtype(DartType base)
+  FlatTypeMask.nonNullSubtype(ClassElement base)
       : this.internal(base, SUBTYPE << 1);
 
-  FlatTypeMask.internal(DartType base, this.flags)
-      : this.base = transformBase(base) {
-    assert(base == null || !(isExact && base.treatAsDynamic));
-  }
-
-  // TODO(kasperl): We temporarily transform the base to be the raw
-  // variant of the type. Long term, we're going to keep the class
-  // element corresponding to the type in the mask instead.
-  static DartType transformBase(DartType base) {
-    if (base == null) {
-      return null;
-    } else if (base.kind != TypeKind.INTERFACE) {
-      assert(base.kind == TypeKind.INTERFACE);
-      return null;
-    } else {
-      return base.asRaw();
-    }
+  FlatTypeMask.internal(this.base, this.flags) {
+    assert(base == null || base.isDeclaration);
   }
 
   bool get isEmpty => (flags >> 1) == EMPTY;
@@ -81,10 +66,11 @@
 
   TypeMask simplify(Compiler compiler) => this;
 
-  bool contains(DartType type, Compiler compiler) {
+  bool contains(ClassElement type, Compiler compiler) {
+    assert(type.isDeclaration);
     if (isEmpty) {
       return false;
-    } else if (identical(base.element, type.element)) {
+    } else if (identical(base, type)) {
       return true;
     } else if (isExact) {
       return false;
@@ -97,43 +83,44 @@
   }
 
   bool containsOnlyInt(Compiler compiler) {
-    return base.element == compiler.intClass
-        || base.element == compiler.backend.intImplementation;
+    return base == compiler.intClass
+        || base == compiler.backend.intImplementation;
   }
 
   bool containsOnlyDouble(Compiler compiler) {
-    return base.element == compiler.doubleClass
-        || base.element == compiler.backend.doubleImplementation;
+    return base == compiler.doubleClass
+        || base == compiler.backend.doubleImplementation;
   }
 
   bool containsOnlyNum(Compiler compiler) {
-    return base.element == compiler.numClass
-        || base.element == compiler.backend.numImplementation;
+    return base == compiler.numClass
+        || base == compiler.backend.numImplementation;
   }
 
   bool containsOnlyNull(Compiler compiler) {
-    return base.element == compiler.nullClass
-        || base.element == compiler.backend.nullImplementation;
+    return base == compiler.nullClass
+        || base == compiler.backend.nullImplementation;
   }
 
   bool containsOnlyBool(Compiler compiler) {
-    return base.element == compiler.boolClass
-        || base.element == compiler.backend.boolImplementation;
+    return base == compiler.boolClass
+        || base == compiler.backend.boolImplementation;
   }
 
   bool containsOnlyString(Compiler compiler) {
-    return base.element == compiler.stringClass
-        || base.element == compiler.backend.stringImplementation;
+    return base == compiler.stringClass
+        || base == compiler.backend.stringImplementation;
   }
 
   bool containsOnly(ClassElement cls) {
-    return base.element == cls;
+    assert(cls.isDeclaration);
+    return base == cls;
   }
 
   bool satisfies(ClassElement cls, Compiler compiler) {
+    assert(cls.isDeclaration);
     if (isEmpty) return false;
-    return base.element == cls
-        || isSubtypeOf(base, cls.computeType(compiler).asRaw(), compiler);
+    return base == cls || isSubtypeOf(base, cls, compiler);
   }
 
   /**
@@ -143,11 +130,10 @@
   ClassElement singleClass(Compiler compiler) {
     if (isEmpty) return null;
     if (isNullable) return null;  // It is Null and some other class.
-    ClassElement element = base.element;
     if (isExact) {
-      return element;
+      return base;
     } else if (isSubclass) {
-      return compiler.world.hasAnySubclass(element) ? null : element;
+      return compiler.world.hasAnySubclass(base) ? null : base;
     } else {
       assert(isSubtype);
       return null;
@@ -159,8 +145,8 @@
    */
   bool containsAll(Compiler compiler) {
     if (isEmpty || isExact) return false;
-    return identical(base.element, compiler.objectClass)
-        || identical(base.element, compiler.dynamicClass);
+    return identical(base, compiler.objectClass)
+        || identical(base, compiler.dynamicClass);
   }
 
   TypeMask union(TypeMask other, Compiler compiler) {
@@ -348,7 +334,7 @@
     int combined = (kind << 1) | (flags & other.flags & 1);
     TypeMask result;
     for (ClassElement each in candidates) {
-      TypeMask mask = new FlatTypeMask.internal(each.rawType, combined);
+      TypeMask mask = new FlatTypeMask.internal(each, combined);
       result = (result == null) ? mask : result.union(mask, compiler);
     }
     return result;
@@ -359,7 +345,7 @@
   }
 
   Iterable<ClassElement> containedClasses(Compiler compiler) {
-    Iterable<ClassElement> self = [ base.element ];
+    Iterable<ClassElement> self = [ base ];
     if (isExact) {
       return self;
     } else {
@@ -408,7 +394,7 @@
 
     // TODO(kasperl): Can't we just avoid creating typed selectors
     // based of function types?
-    Element self = base.element;
+    Element self = base;
     if (self.isTypedef()) {
       // A typedef is a function type that doesn't have any
       // user-defined members.
@@ -468,7 +454,7 @@
       if (!isNullable) return false;
       cls = compiler.backend.nullImplementation;
     } else {
-      cls = base.element;
+      cls = base;
     }
 
     // Use [lookupMember] because finding abstract members is okay.
@@ -481,7 +467,7 @@
     // `null`.
     if (isEmpty) return false;
     // A call on an exact mask for an abstract class is dead code.
-    if (isExact && base.element.isAbstract(compiler)) return false;
+    if (isExact && base.isAbstract(compiler)) return false;
     // If the receiver is guaranteed to have a member that
     // matches what we're looking for, there's no need to
     // introduce a noSuchMethod handler. It will never be called.
@@ -524,17 +510,16 @@
     // handler because we may have to call B.noSuchMethod since B
     // does not implement bar.
 
-    Element cls = base.element;
-    bool hasMatch = hasConcreteMatch(cls, selector, compiler);
+    bool hasMatch = hasConcreteMatch(base, selector, compiler);
     if (isExact) return !hasMatch;
-    if (!cls.isAbstract(compiler) && !hasMatch) return true;
+    if (!base.isAbstract(compiler) && !hasMatch) return true;
 
     Set<ClassElement> subtypesToCheck;
     if (isSubtype) {
-      subtypesToCheck = compiler.world.subtypesOf(cls);
+      subtypesToCheck = compiler.world.subtypesOf(base);
     } else {
       assert(isSubclass);
-      subtypesToCheck = compiler.world.subclassesOf(cls);
+      subtypesToCheck = compiler.world.subclassesOf(base);
     }
 
     return subtypesToCheck != null
@@ -558,8 +543,7 @@
     // implemented on the exact receiver type. It could be found in a
     // subclass or in an inheritance-wise unrelated class in case of
     // subtype selectors.
-    ClassElement cls = base.element;
-    return (cls.isSubclassOf(enclosing)) ? result : null;
+    return (base.isSubclassOf(enclosing)) ? result : null;
   }
 
   bool operator ==(var other) {
@@ -579,22 +563,20 @@
     if (isExact) buffer.write('exact=');
     if (isSubclass) buffer.write('subclass=');
     if (isSubtype) buffer.write('subtype=');
-    buffer.write(base.element.name.slowToString());
+    buffer.write(base.name.slowToString());
     return "[$buffer]";
   }
 
-  static bool isSubclassOf(DartType x, DartType y, Compiler compiler) {
-    ClassElement xElement = x.element;
-    ClassElement yElement = y.element;
-    Set<ClassElement> subclasses = compiler.world.subclassesOf(yElement);
-    return (subclasses != null) ? subclasses.contains(xElement) : false;
+  static bool isSubclassOf(ClassElement x, ClassElement y, Compiler compiler) {
+    assert(x.isDeclaration && y.isDeclaration);
+    Set<ClassElement> subclasses = compiler.world.subclassesOf(y);
+    return (subclasses != null) ? subclasses.contains(x) : false;
   }
 
-  static bool isSubtypeOf(DartType x, DartType y, Compiler compiler) {
-    ClassElement xElement = x.element;
-    ClassElement yElement = y.element;
-    Set<ClassElement> subtypes = compiler.world.subtypesOf(yElement);
-    return (subtypes != null) ? subtypes.contains(xElement) : false;
+  static bool isSubtypeOf(ClassElement x, ClassElement y, Compiler compiler) {
+    assert(x.isDeclaration && y.isDeclaration);
+    Set<ClassElement> subtypes = compiler.world.subtypesOf(y);
+    return (subtypes != null) ? subtypes.contains(x) : false;
   }
 
   static Set<ClassElement> commonContainedClasses(FlatTypeMask x,
@@ -617,7 +599,7 @@
   }
 
   static Set<ClassElement> containedSubset(FlatTypeMask x, Compiler compiler) {
-    ClassElement element = x.base.element;
+    ClassElement element = x.base;
     if (x.isExact) {
       return null;
     } else if (x.isSubclass) {
diff --git a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
index c077d5f..8f4c05f 100644
--- a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
@@ -54,7 +54,7 @@
     return forwardTo.satisfies(cls, compiler);
   }
 
-  bool contains(DartType type, Compiler compiler) {
+  bool contains(ClassElement type, Compiler compiler) {
     return forwardTo.contains(type, compiler);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index a809af3..27e2df5 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -10,21 +10,24 @@
  * yield conservative answers that contain too many classes.
  */
 abstract class TypeMask {
-  factory TypeMask(DartType base, int kind, bool isNullable)
+  factory TypeMask(ClassElement base, int kind, bool isNullable)
       => new FlatTypeMask(base, kind, isNullable);
 
   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.exact(ClassElement base)
+      => new FlatTypeMask.exact(base);
+  factory TypeMask.subclass(ClassElement base)
+      => new FlatTypeMask.subclass(base);
+  factory TypeMask.subtype(ClassElement base)
+      => new FlatTypeMask.subtype(base);
 
   const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty;
-  factory TypeMask.nonNullExact(DartType base)
+  factory TypeMask.nonNullExact(ClassElement base)
       => new FlatTypeMask.nonNullExact(base);
-  factory TypeMask.nonNullSubclass(DartType base)
+  factory TypeMask.nonNullSubclass(ClassElement base)
       => new FlatTypeMask.nonNullSubclass(base);
-  factory TypeMask.nonNullSubtype(DartType base)
+  factory TypeMask.nonNullSubtype(ClassElement base)
       => new FlatTypeMask.nonNullSubtype(base);
 
   factory TypeMask.unionOf(Iterable<TypeMask> masks, Compiler compiler) {
@@ -58,7 +61,7 @@
   bool containsOnlyBool(Compiler compiler);
   bool containsOnlyString(Compiler compiler);
   bool containsOnly(ClassElement element);
-  
+
   /**
    * Returns whether this type mask is an instance of [cls].
    */
@@ -67,7 +70,7 @@
   /**
    * Returns whether or not this type mask contains the given type.
    */
-  bool contains(DartType type, Compiler compiler);
+  bool contains(ClassElement type, Compiler compiler);
 
   /**
    * Returns whether or not this type mask contains all types.
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index d4a83b98..1a47e3b 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -68,7 +68,7 @@
 
   TypeMask get dynamicType {
     if (dynamicTypeCache == null) {
-      dynamicTypeCache = new TypeMask.subclass(compiler.objectClass.rawType);
+      dynamicTypeCache = new TypeMask.subclass(compiler.objectClass);
     }
     return dynamicTypeCache;
   }
@@ -76,7 +76,7 @@
   TypeMask get intType {
     if (intTypeCache == null) {
       intTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.intImplementation.rawType);
+          compiler.backend.intImplementation);
     }
     return intTypeCache;
   }
@@ -84,7 +84,7 @@
   TypeMask get doubleType {
     if (doubleTypeCache == null) {
       doubleTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.doubleImplementation.rawType);
+          compiler.backend.doubleImplementation);
     }
     return doubleTypeCache;
   }
@@ -92,7 +92,7 @@
   TypeMask get numType {
     if (numTypeCache == null) {
       numTypeCache = new TypeMask.nonNullSubclass(
-          compiler.backend.numImplementation.rawType);
+          compiler.backend.numImplementation);
     }
     return numTypeCache;
   }
@@ -100,7 +100,7 @@
   TypeMask get boolType {
     if (boolTypeCache == null) {
       boolTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.boolImplementation.rawType);
+          compiler.backend.boolImplementation);
     }
     return boolTypeCache;
   }
@@ -108,7 +108,7 @@
   TypeMask get functionType {
     if (functionTypeCache == null) {
       functionTypeCache = new TypeMask.nonNullSubtype(
-          compiler.backend.functionImplementation.rawType);
+          compiler.backend.functionImplementation);
     }
     return functionTypeCache;
   }
@@ -116,7 +116,7 @@
   TypeMask get listType {
     if (listTypeCache == null) {
       listTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.listImplementation.rawType);
+          compiler.backend.listImplementation);
     }
     return listTypeCache;
   }
@@ -124,7 +124,7 @@
   TypeMask get constListType {
     if (constListTypeCache == null) {
       constListTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.constListImplementation.rawType);
+          compiler.backend.constListImplementation);
     }
     return constListTypeCache;
   }
@@ -132,7 +132,7 @@
   TypeMask get fixedListType {
     if (fixedListTypeCache == null) {
       fixedListTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.fixedListImplementation.rawType);
+          compiler.backend.fixedListImplementation);
     }
     return fixedListTypeCache;
   }
@@ -140,7 +140,7 @@
   TypeMask get growableListType {
     if (growableListTypeCache == null) {
       growableListTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.growableListImplementation.rawType);
+          compiler.backend.growableListImplementation);
     }
     return growableListTypeCache;
   }
@@ -148,7 +148,7 @@
   TypeMask get mapType {
     if (mapTypeCache == null) {
       mapTypeCache = new TypeMask.nonNullSubtype(
-          compiler.backend.mapImplementation.rawType);
+          compiler.backend.mapImplementation);
     }
     return mapTypeCache;
   }
@@ -156,7 +156,7 @@
   TypeMask get constMapType {
     if (constMapTypeCache == null) {
       constMapTypeCache = new TypeMask.nonNullSubtype(
-          compiler.backend.constMapImplementation.rawType);
+          compiler.backend.constMapImplementation);
     }
     return constMapTypeCache;
   }
@@ -164,7 +164,7 @@
   TypeMask get stringType {
     if (stringTypeCache == null) {
       stringTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.stringImplementation.rawType);
+          compiler.backend.stringImplementation);
     }
     return stringTypeCache;
   }
@@ -172,7 +172,7 @@
   TypeMask get typeType {
     if (typeTypeCache == null) {
       typeTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.typeImplementation.rawType);
+          compiler.backend.typeImplementation);
     }
     return typeTypeCache;
   }
@@ -209,18 +209,17 @@
     return cls;
   }
 
-  /// Checks that two [DartType]s are the same modulo normalization.
-  bool same(DartType type1, DartType type2) {
-    return (type1 == type2)
-        || normalize(type1.element) == normalize(type2.element);
+  /// Checks that two types are the same modulo normalization.
+  bool same(ClassElement type1, ClassElement type2) {
+    return (type1 == type2) || normalize(type1) == normalize(type2);
   }
 
   /**
    * Checks that one of [type1] and [type2] is a subtype of the other.
    */
-  bool related(DartType type1, DartType type2) {
-    return compiler.types.isSubtype(type1, type2)
-        || compiler.types.isSubtype(type2, type1);
+  bool related(ClassElement type1, ClassElement type2) {
+    return compiler.types.isSubtype(type1.rawType, type2.rawType)
+        || compiler.types.isSubtype(type2.rawType, type1.rawType);
   }
 
   /**
@@ -228,18 +227,20 @@
    * exactness, subclassing, subtyping and nullability. The [element] parameter
    * is for debugging purposes only and can be omitted.
    */
-  TypeMask best(var type1, var type2, [element]) {
+  FlatTypeMask best(TypeMask type1, TypeMask type2, [element]) {
     // TODO(polux): Handle [UnionTypeMask].
     if (type1 != null) type1 = type1.simplify(compiler);
     if (type2 != null) type2 = type2.simplify(compiler);
-    final result = _best(type1, type2);
+    FlatTypeMask result = _best(type1, type2);
     // Tests type1 and type2 for equality modulo normalization of native types.
     // Only called when DUMP_SURPRISING_RESULTS is true.
     bool similar() {
       if (type1 == null || type2 == null || type1.isEmpty || type2.isEmpty) {
         return type1 == type2;
       }
-      return same(type1.base, type2.base);
+      FlatTypeMask flat1 = type1;
+      FlatTypeMask flat2 = type2;
+      return same(flat1.base, flat2.base);
     }
     if (DUMP_SURPRISING_RESULTS && result == type1 && !similar()) {
       print("$type1 better than $type2 for $element");
@@ -248,54 +249,56 @@
   }
 
   /// Helper method for [best].
-  TypeMask _best(var type1, var type2) {
+  FlatTypeMask _best(var type1, var type2) {
     if (type1 == null) return type2;
     if (type2 == null) return type1;
-    if (type1.isContainer) type1 = type1.asFlat;
-    if (type2.isContainer) type2 = type2.asFlat;
-    if (type1.isExact) {
-      if (type2.isExact) {
+    FlatTypeMask flat1 = type1.isContainer ? type1.asFlat : type1;
+    FlatTypeMask flat2 = type2.isContainer ? type2.asFlat : type2;
+    if (flat1.isExact) {
+      if (flat2.isExact) {
         // TODO(polux): Update the code to not have this situation.
-        if (type1.base != type2.base) return type1;
-        assert(same(type1.base, type2.base));
-        return type1.isNullable ? type2 : type1;
+        if (flat1.base != flat2.base) return flat1;
+        assert(same(flat1.base, flat2.base));
+        return flat1.isNullable ? flat2 : flat1;
       } else {
-        return type1;
+        return flat1;
       }
-    } else if (type2.isExact) {
-      return type2;
-    } else if (type1.isSubclass) {
-      if (type2.isSubclass) {
-        assert(related(type1.base, type2.base));
-        if (same(type1.base, type2.base)) {
-          return type1.isNullable ? type2 : type1;
-        } else if (compiler.types.isSubtype(type1.base, type2.base)) {
-          return type1;
+    } else if (flat2.isExact) {
+      return flat2;
+    } else if (flat1.isSubclass) {
+      if (flat2.isSubclass) {
+        assert(related(flat1.base, flat2.base));
+        if (same(flat1.base, flat2.base)) {
+          return flat1.isNullable ? flat2 : flat1;
+        } else if (compiler.types.isSubtype(flat1.base.rawType,
+                                            flat2.base.rawType)) {
+          return flat1;
         } else {
-          return type2;
+          return flat2;
         }
       } else {
-        return type1;
+        return flat1;
       }
-    } else if (type2.isSubclass) {
-      return type2;
-    } else if (type1.isSubtype) {
-      if (type2.isSubtype) {
-        assert(related(type1.base, type2.base));
-        if (same(type1.base, type2.base)) {
-          return type1.isNullable ? type2 : type1;
-        } else if (compiler.types.isSubtype(type1.base, type2.base)) {
-          return type1;
+    } else if (flat2.isSubclass) {
+      return flat2;
+    } else if (flat1.isSubtype) {
+      if (flat2.isSubtype) {
+        assert(related(flat1.base, flat2.base));
+        if (same(flat1.base, flat2.base)) {
+          return flat1.isNullable ? flat2 : flat1;
+        } else if (compiler.types.isSubtype(flat1.base.rawType,
+                                            flat2.base.rawType)) {
+          return flat1;
         } else {
-          return type2;
+          return flat2;
         }
       } else {
-        return type1;
+        return flat1;
       }
-    } else if (type2.isSubtype) {
-      return type2;
+    } else if (flat2.isSubtype) {
+      return flat2;
     } else {
-      return type1.isNullable ? type2 : type1;
+      return flat1.isNullable ? flat2 : flat1;
     }
   }
 
@@ -315,7 +318,6 @@
         }
       }
     });
-    compiler.containerTracer.analyze();
     typesInferrer.clear();
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
index 6c40e56..269b1b5 100644
--- a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
@@ -37,8 +37,7 @@
         continue;
       } else {
         FlatTypeMask flatMask = mask;
-        assert(flatMask.base == null
-               || flatMask.base.element != compiler.dynamicClass);
+        assert(flatMask.base == null || flatMask.base != compiler.dynamicClass);
         int inListIndex = -1;
         bool covered = false;
 
@@ -87,13 +86,13 @@
     bool isNullable = masks.any((e) => e.isNullable);
 
     // Compute the common supertypes of the two types.
-    ClassElement firstElement = masks[0].base.element;
-    ClassElement secondElement = masks[1].base.element;
+    ClassElement firstElement = masks[0].base;
+    ClassElement secondElement = masks[1].base;
     Iterable<ClassElement> candidates =
         compiler.world.commonSupertypesOf(firstElement, secondElement);
     bool unseenType = false;
     for (int i = 2; i < masks.length; i++) {
-      ClassElement element = masks[i].base.element;
+      ClassElement element = masks[i].base;
       Set<ClassElement> supertypes = compiler.world.supertypesOf(element);
       if (supertypes == null) {
         unseenType = true;
@@ -105,7 +104,7 @@
     if (candidates.isEmpty || unseenType) {
       // TODO(kasperl): Get rid of this check. It can only happen when
       // at least one of the two base types is 'unseen'.
-      return new TypeMask(compiler.objectClass.rawType,
+      return new TypeMask(compiler.objectClass,
                           FlatTypeMask.SUBCLASS,
                           isNullable);
     }
@@ -120,7 +119,7 @@
       int size;
       int kind;
       if (subclasses != null
-          && masks.every((t) => subclasses.contains(t.base.element))) {
+          && masks.every((t) => subclasses.contains(t.base))) {
         // If both [this] and [other] are subclasses of the supertype,
         // then we prefer to construct a subclass type mask because it
         // will always be at least as small as the corresponding
@@ -140,9 +139,7 @@
       }
     }
     if (bestElement == compiler.objectClass) bestKind = FlatTypeMask.SUBCLASS;
-    return new TypeMask(bestElement.computeType(compiler),
-                        bestKind,
-                        isNullable);
+    return new TypeMask(bestElement, bestKind, isNullable);
   }
 
   TypeMask union(var other, Compiler compiler) {
@@ -217,7 +214,7 @@
     return disjointMasks.every((mask) => mask.satisfies(cls, compiler));
   }
 
-  bool contains(DartType type, Compiler compiler) {
+  bool contains(ClassElement type, Compiler compiler) {
     return disjointMasks.any((e) => e.contains(type, compiler));
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/universe/function_set.dart b/sdk/lib/_internal/compiler/implementation/universe/function_set.dart
index bae06cb..d5f8784 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/function_set.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/function_set.dart
@@ -146,7 +146,7 @@
     // to always be a subclass of Object.
     return selector.mask != null
         ? selector.mask
-        : new TypeMask.subclass(compiler.objectClass.rawType);
+        : new TypeMask.subclass(compiler.objectClass);
     }
 
   FunctionSetQuery query(Selector selector,
@@ -225,8 +225,8 @@
             return const TypeMask.empty();
           }
           return compiler.world.hasSubclasses(cls)
-              ? new TypeMask.nonNullSubclass(cls.rawType)
-              : new TypeMask.nonNullExact(cls.rawType);
+              ? new TypeMask.nonNullSubclass(cls)
+              : new TypeMask.nonNullExact(cls);
         }),
         compiler);
   }
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index 1bcf514..e0b1548 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -638,13 +638,13 @@
     return result;
   }
 
-  factory TypedSelector.exact(DartType base, Selector selector)
+  factory TypedSelector.exact(ClassElement base, Selector selector)
       => new TypedSelector(new TypeMask.exact(base), selector);
 
-  factory TypedSelector.subclass(DartType base, Selector selector)
+  factory TypedSelector.subclass(ClassElement base, Selector selector)
       => new TypedSelector(new TypeMask.subclass(base), selector);
 
-  factory TypedSelector.subtype(DartType base, Selector selector)
+  factory TypedSelector.subtype(ClassElement base, Selector selector)
       => new TypedSelector(new TypeMask.subtype(base), selector);
 
   bool appliesUnnamed(Element element, Compiler compiler) {
diff --git a/sdk/lib/_internal/compiler/implementation/util/util.dart b/sdk/lib/_internal/compiler/implementation/util/util.dart
index 2638fd8..c904cc1 100644
--- a/sdk/lib/_internal/compiler/implementation/util/util.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/util.dart
@@ -77,6 +77,11 @@
 
   _StackTraceLine(this.index, this.file, this.lineNo,
                   this.columnNo, this.method);
+
+  String toString() {
+    return 'index=$index, file=$file, '
+           'lineNo=$lineNo, columnNo=$columnNo, method=$method';
+  }
 }
 
 // TODO(johnniwinther): Use this format for --throw-on-error.
@@ -123,14 +128,31 @@
     int lastColon = line.lastIndexOf(':', rightParenPos);
     int nextToLastColon = line.lastIndexOf(':', lastColon-1);
 
-    String lineNo = line.substring(nextToLastColon+1, lastColon);
+    String lineNo;
+    String columnNo;
+    if (nextToLastColon != -1) {
+      lineNo = line.substring(nextToLastColon+1, lastColon);
+      columnNo = line.substring(lastColon+1, rightParenPos);
+      try {
+        int.parse(lineNo);
+      } on FormatException catch (e) {
+        lineNo = columnNo;
+        columnNo = '';
+        nextToLastColon = lastColon;
+      }
+    } else {
+      lineNo = line.substring(lastColon+1, rightParenPos);
+      columnNo = '';
+      nextToLastColon = lastColon;
+    }
+
     if (lineNo.length > maxLineNoLength) {
       maxLineNoLength = lineNo.length;
     }
-    String columnNo = line.substring(lastColon+1, rightParenPos);
     if (columnNo.length > maxColumnNoLength) {
       maxColumnNoLength = columnNo.length;
     }
+
     String file = line.substring(leftParenPos+1, nextToLastColon);
     if (filePrefix != null && file.startsWith(filePrefix)) {
       file = file.substring(filePrefix.length);
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index b44e3ec..3c3729e 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -599,6 +599,34 @@
 main() => foo(42);
 """]);
 
+  static const MessageKind FINAL_FUNCTION_TYPE_PARAMETER = const MessageKind(
+      "Error: A function type parameter can't be declared final.",
+      howToFix: "Try removing 'final'.",
+      examples: const ["""
+foo(final int x(int a)) {}
+main() => foo((y) => 42);
+""", """
+foo({final int x(int a)}) {}
+main() => foo((y) => 42);
+""", """
+foo([final int x(int a)]) {}
+main() => foo((y) => 42);
+"""]);
+
+  static const MessageKind VAR_FUNCTION_TYPE_PARAMETER = const MessageKind(
+      "Error: A function type parameter can't be declared with 'var'.",
+      howToFix: "Try removing 'var'.",
+      examples: const ["""
+foo(var int x(int a)) {}
+main() => foo((y) => 42);
+""", """
+foo({var int x(int a)}) {}
+main() => foo((y) => 42);
+""", """
+foo([var int x(int a)]) {}
+main() => foo((y) => 42);
+"""]);
+
   static const MessageKind CANNOT_INSTANTIATE_TYPE_VARIABLE = const MessageKind(
       "Error: Cannot instantiate type variable '#{typeVariableName}'.");
 
@@ -640,6 +668,19 @@
   static const MessageKind CANNOT_IMPLEMENT = const MessageKind(
       "Error: '#{type}' cannot be implemented.");
 
+  static const MessageKind CANNOT_MIXIN = const MessageKind(
+      "Error: The type '#{type}' can't be mixed in.",
+      howToFix: "Try removing '#{type}' from the 'with' clause.",
+      examples: const ["""
+class C extends Object with String {}
+
+main() => new C();                       
+""", """
+typedef C = Object with String;
+
+main() => new C();                       
+"""]);
+
   static const MessageKind DUPLICATE_EXTENDS_IMPLEMENTS = const MessageKind(
       "Error: '#{type}' can not be both extended and implemented.");
 
@@ -905,6 +946,13 @@
       "Error: '#{value}' is not a valid Symbol name because it starts with "
       "'_'.");
 
+  static const MessageKind PRIVATE_NAMED_PARAMETER = const MessageKind(
+      "Error: Named optional parameter can't have a library private name.",
+      howToFix: "Try removing the '_' or making the parameter positional or "
+        "required.",
+      examples: const ["""foo({int _p}) {} main() => foo();"""]
+      );
+
   static const MessageKind UNSUPPORTED_LITERAL_SYMBOL = const MessageKind(
       "Internal Error: Symbol literal '##{value}' is currently unsupported.");
 
diff --git a/sdk/lib/_internal/compiler/implementation/world.dart b/sdk/lib/_internal/compiler/implementation/world.dart
index 4d25945..17f3b7f 100644
--- a/sdk/lib/_internal/compiler/implementation/world.dart
+++ b/sdk/lib/_internal/compiler/implementation/world.dart
@@ -152,15 +152,17 @@
   }
 
   // Returns whether a subclass of [superclass] implements [type].
-  bool hasAnySubclassThatImplements(ClassElement superclass, DartType type) {
+  bool hasAnySubclassThatImplements(ClassElement superclass,
+                                    ClassElement type) {
     Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass);
     if (subclasses == null) return false;
-    return subclasses.contains(type.element);
+    return subclasses.contains(type);
   }
 
   // Returns whether a subclass of any mixin application of [cls] implements
   // [type].
-  bool hasAnySubclassOfMixinUseThatImplements(ClassElement cls, DartType type) {
+  bool hasAnySubclassOfMixinUseThatImplements(ClassElement cls,
+                                              ClassElement type) {
     Set<MixinApplicationElement> uses = mixinUses[cls];
     if (uses == null || uses.isEmpty) return false;
     return uses.any((use) => hasAnySubclassThatImplements(use, type));
@@ -192,7 +194,7 @@
 
   Element locateSingleElement(Selector selector) {
     ti.TypeMask mask = selector.mask == null
-        ? new ti.TypeMask.subclass(compiler.objectClass.rawType)
+        ? new ti.TypeMask.subclass(compiler.objectClass)
         : selector.mask;
     return mask.locateSingleElement(selector, compiler);
   }
diff --git a/sdk/lib/_internal/lib/io_patch.dart b/sdk/lib/_internal/lib/io_patch.dart
index 095c424..dd4444a 100644
--- a/sdk/lib/_internal/lib/io_patch.dart
+++ b/sdk/lib/_internal/lib/io_patch.dart
@@ -9,7 +9,7 @@
   patch static _setCurrent(path) {
     throw new UnsupportedError("Directory_SetCurrent");
   }
-  patch static _createTemp(String template) {
+  patch static _createTemp(String template, bool system) {
     throw new UnsupportedError("Directory._createTemp");
   }
   patch static int _exists(String path) {
diff --git a/sdk/lib/_internal/lib/isolate_helper.dart b/sdk/lib/_internal/lib/isolate_helper.dart
index ac4cc0f..8b0ad62 100644
--- a/sdk/lib/_internal/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/lib/isolate_helper.dart
@@ -411,7 +411,7 @@
 
 const String _SPAWNED_SIGNAL = "spawned";
 
-var globalThis = IsolateNatives.computeGlobalThis();
+var globalThis = Primitives.computeGlobalThis();
 var globalWindow = JS('', "#.window", globalThis);
 var globalWorker = JS('', "#.Worker", globalThis);
 bool globalPostMessageDefined =
@@ -480,8 +480,6 @@
     throw new UnsupportedError('Cannot extract URI from "$stack"');
   }
 
-  static computeGlobalThis() => JS('', 'function() { return this; }()');
-
   /**
    * Assume that [e] is a browser message event and extract its message data.
    * We don't import the dom explicitly so, when workers are disabled, this
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index ddeb666..0219440 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -279,6 +279,8 @@
     return JS('int', '#', hash);
   }
 
+  static computeGlobalThis() => JS('', 'function() { return this; }()');
+
   /**
    * This is the low-level method that is used to implement
    * [print]. It is possible to override this function from JavaScript
@@ -1498,13 +1500,19 @@
               var isolate,
               int numberOfArguments,
               var arg1,
-              var arg2) {
+              var arg2,
+              var arg3,
+              var arg4) {
   if (numberOfArguments == 0) {
     return JS_CALL_IN_ISOLATE(isolate, () => closure());
   } else if (numberOfArguments == 1) {
     return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1));
   } else if (numberOfArguments == 2) {
     return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2));
+  } else if (numberOfArguments == 3) {
+    return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2, arg3));
+  } else if (numberOfArguments == 4) {
+    return JS_CALL_IN_ISOLATE(isolate, () => closure(arg1, arg2, arg3, arg4));
   } else {
     throw new Exception(
         'Unsupported number of arguments for wrapped closure');
@@ -1523,9 +1531,11 @@
   // We use $0 and $1 to not clash with variable names used by the
   // compiler and/or minifier.
   function = JS('var',
-                r'(function ($2, $3) {'
-                    r' return function($0, $1) { '
-                        r'return $3(#, $2, #, $0, $1) }})(#, #)',
+                '(function(closure, arity, context, invoke) {'
+                '  return function(a1, a2, a3, a4) {'
+                '     return invoke(closure, context, arity, a1, a2, a3, a4);'
+                '  };'
+                '})(#,#,#,#)',
                 closure,
                 arity,
                 // Capture the current isolate now.  Remember that "#"
diff --git a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
index 557dbba..be6ef7c 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
@@ -46,11 +46,7 @@
 /// them (with [configuration] if it's non-null), and return them.
 Iterable<Transformer> initialize(Uri uri, Map configuration) {
   var mirrors = currentMirrorSystem();
-  // TODO(nweiz): look this up by name once issue 5897 is fixed.
-  var transformerUri = Uri.parse(
-      'http://<<HOST_AND_PORT>>/packages/barback/src/transformer.dart');
-  var transformerClass = mirrors.libraries[transformerUri]
-      .classes[const Symbol('Transformer')];
+  var transformerClass = reflectClass(Transformer);
 
   // TODO(nweiz): if no valid transformers are found, throw an error message
   // describing candidates and why they were rejected.
@@ -289,7 +285,7 @@
     TransformerId id) {
   var path = id.asset.path.replaceFirst('lib/', '');
   // TODO(nweiz): load from a "package:" URI when issue 12474 is fixed.
-  var hostAndPort = '${server.host}:${server.port}';
+  var hostAndPort = '${server.address.address}:${server.port}';
   var uri = 'http://$hostAndPort/packages/${id.asset.package}/$path';
   var code = 'import "$uri";' +
       _TRANSFORMER_ISOLATE.replaceAll('<<HOST_AND_PORT>>', hostAndPort);
diff --git a/sdk/lib/_internal/pub/lib/src/barback/server.dart b/sdk/lib/_internal/pub/lib/src/barback/server.dart
index a2ce379..3b8c154 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/server.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/server.dart
@@ -29,10 +29,8 @@
   /// The server's port.
   final int port;
 
-  /// The server's hostname.
-  final String host;
-  // TODO(whesse): replace this with the InternetAddress of the HttpServer, when
-  // that is exposed.
+  /// The server's address.
+  final InternetAddress address;
 
   /// The results of requests handled by the server.
   ///
@@ -50,12 +48,13 @@
   static Future<BarbackServer> bind(String host, int port, Barback barback,
       String rootPackage) {
     return HttpServer.bind(host, port)
-        .then((server) => new BarbackServer._(server, barback, rootPackage, host));
+        .then((server) => new BarbackServer._(server, barback, rootPackage));
   }
 
-  BarbackServer._(HttpServer server, this.barback, this._rootPackage, this.host)
+  BarbackServer._(HttpServer server, this.barback, this._rootPackage)
       : _server = server,
-        port = server.port {
+        port = server.port,
+        address = server.address {
     _server.listen(_handleRequest, onError: (error) {
       _resultsController.addError(error);
       close();
diff --git a/sdk/lib/_internal/pub/lib/src/exit_codes.dart b/sdk/lib/_internal/pub/lib/src/exit_codes.dart
index 028fd1c..156e49e 100644
--- a/sdk/lib/_internal/pub/lib/src/exit_codes.dart
+++ b/sdk/lib/_internal/pub/lib/src/exit_codes.dart
@@ -10,46 +10,46 @@
 library pub.exit_codes;
 
 /// The command was used incorrectly.
-final USAGE = 64;
+const USAGE = 64;
 
 /// The input data was incorrect.
-final DATA = 65;
+const DATA = 65;
 
 /// An input file did not exist or was unreadable.
-final NO_INPUT = 66;
+const NO_INPUT = 66;
 
 /// The user specified did not exist.
-final NO_USER = 67;
+const NO_USER = 67;
 
 /// The host specified did not exist.
-final NO_HOST = 68;
+const NO_HOST = 68;
 
 /// A service is unavailable.
-final UNAVAILABLE = 69;
+const UNAVAILABLE = 69;
 
 /// An internal software error has been detected.
-final SOFTWARE = 70;
+const SOFTWARE = 70;
 
 /// An operating system error has been detected.
-final OS = 71;
+const OS = 71;
 
 /// Some system file did not exist or was unreadable.
-final OS_FILE = 72;
+const OS_FILE = 72;
 
 /// A user-specified output file cannot be created.
-final CANT_CREATE = 73;
+const CANT_CREATE = 73;
 
 /// An error occurred while doing I/O on some file.
-final IO = 74;
+const IO = 74;
 
 /// Temporary failure, indicating something that is not really an error.
-final TEMP_FAIL = 75;
+const TEMP_FAIL = 75;
 
 /// The remote system returned something invalid during a protocol exchange.
-final PROTOCOL = 76;
+const PROTOCOL = 76;
 
 /// The user did not have sufficient permissions.
-final NO_PERM = 77;
+const NO_PERM = 77;
 
 /// Something was unconfigured or mis-configured.
-final CONFIG = 78;
+const CONFIG = 78;
diff --git a/sdk/lib/_internal/pub/lib/src/io.dart b/sdk/lib/_internal/pub/lib/src/io.dart
index 41a2543..af8168e 100644
--- a/sdk/lib/_internal/pub/lib/src/io.dart
+++ b/sdk/lib/_internal/pub/lib/src/io.dart
@@ -232,12 +232,19 @@
 /// suffix appended to it. If [dir] is not provided, a temp directory will be
 /// created in a platform-dependent temporary location. Returns the path of the
 /// created directory.
-String createTempDir([dir = '']) {
-  var tempDir = new Directory(dir).createTempSync();
+String createTempDir(String base, String prefix) {
+  var tempDir = new Directory(base).createTempSync(prefix);
   log.io("Created temp directory ${tempDir.path}");
   return tempDir.path;
 }
 
+String createSystemTempDir() {
+  var tempDir = Directory.createSystemTempSync('pub_');
+  log.io("Created temp directory ${tempDir.path}");
+  return tempDir.path;
+}
+
+
 /// Lists the contents of [dir]. If [recursive] is `true`, lists subdirectory
 /// contents (defaults to `false`). If [includeHidden] is `true`, includes files
 /// and directories beginning with `.` (defaults to `false`).
@@ -648,7 +655,7 @@
 /// [fn] completes to.
 Future withTempDir(Future fn(String path)) {
   return new Future.sync(() {
-    var tempDir = createTempDir();
+    var tempDir = createSystemTempDir();
     return new Future.sync(() => fn(tempDir))
         .whenComplete(() => deleteEntry(tempDir));
   });
diff --git a/sdk/lib/_internal/pub/lib/src/system_cache.dart b/sdk/lib/_internal/pub/lib/src/system_cache.dart
index 7dafb8c..63b9817 100644
--- a/sdk/lib/_internal/pub/lib/src/system_cache.dart
+++ b/sdk/lib/_internal/pub/lib/src/system_cache.dart
@@ -96,7 +96,7 @@
   /// cache so that it can move the directory from it.
   String createTempDir() {
     var temp = ensureDir(tempDir);
-    return io.createTempDir(path.join(temp, 'dir'));
+    return io.createTempDir(temp, 'dir');
   }
 
   /// Deletes the system cache's internal temp directory.
diff --git a/sdk/lib/_internal/pub/test/test_pub.dart b/sdk/lib/_internal/pub/test/test_pub.dart
index 1f79116..fc449c2 100644
--- a/sdk/lib/_internal/pub/test/test_pub.dart
+++ b/sdk/lib/_internal/pub/test/test_pub.dart
@@ -337,7 +337,7 @@
       d.file('version', '0.1.2.3')
     ]).create();
 
-    _sandboxDir = createTempDir();
+    _sandboxDir = createSystemTempDir();
     d.defaultRoot = sandboxDir;
     currentSchedule.onComplete.schedule(() => deleteEntry(_sandboxDir),
         'deleting the sandbox directory');
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index ac6bacd..4f067dd 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -251,23 +251,44 @@
    */
   dynamic runUnaryGuarded(f(arg), var arg);
 
-  ZoneCallback registerCallback(f());
-  ZoneUnaryCallback registerUnaryCallback(f(arg));
+  /**
+   * Registers the given callback in this zone.
+   *
+   * It is good practice to register asynchronous or delayed callbacks before
+   * invoking [run]. This gives the zone a chance to wrap the callback and
+   * to store information with the callback. For example, a zone may decide
+   * to store the stack trace (at the time of the registration) with the
+   * callback.
+   *
+   * Returns a potentially new callback that should be used in place of the
+   * given [callback].
+   */
+  ZoneCallback registerCallback(callback());
+
+  /**
+   * Registers the given callback in this zone.
+   *
+   * Similar to [registerCallback] but with a unary callback.
+   */
+  ZoneUnaryCallback registerUnaryCallback(callback(arg));
 
   /**
    *  Equivalent to:
    *
    *      ZoneCallback registered = registerCallback(f);
+   *      if (runGuarded) return () => this.runGuarded(registered);
    *      return () => this.run(registered);
+   *
    */
-  ZoneCallback bindCallback(f(), { bool runGuarded });
+  ZoneCallback bindCallback(f(), { bool runGuarded: true });
   /**
    *  Equivalent to:
    *
    *      ZoneCallback registered = registerCallback1(f);
-   *      return (arg) => this.run1(registered, arg);
+   *      if (runGuarded) return (arg) => this.runUnaryGuarded(registered, arg);
+   *      return (arg) => thin.runUnary(registered, arg);
    */
-  ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded });
+  ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded: true });
 
   /**
    * Runs [f] asynchronously.
@@ -427,7 +448,7 @@
     }
   }
 
-  ZoneCallback bindCallback(f(), { bool runGuarded }) {
+  ZoneCallback bindCallback(f(), { bool runGuarded: true }) {
     ZoneCallback registered = registerCallback(f);
     if (runGuarded) {
       return () => this.runGuarded(registered);
@@ -436,7 +457,7 @@
     }
   }
 
-  ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded }) {
+  ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded: true }) {
     ZoneUnaryCallback registered = registerUnaryCallback(f);
     if (runGuarded) {
       return (arg) => this.runUnaryGuarded(registered, arg);
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index 6abaa05..3562085 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -7,6 +7,9 @@
 /** The Unicode Replacement character `U+FFFD` (�). */
 const UNICODE_REPLACEMENT_CHARACTER_RUNE = 0xFFFD;
 
+/** The Unicode Byte Order Marker (BOM) character `U+FEFF`. */
+const UNICODE_BOM_CHARACTER_RUNE = 0xFEFF;
+
 /**
  * An instance of the default implementation of the [Utf8Codec].
  *
@@ -48,6 +51,9 @@
    * Decodes the UTF-8 [codeUnits] (a list of unsigned 8-bit integers) to the
    * corresponding string.
    *
+   * If the [codeUnits] start with a leading [UNICODE_BOM_CHARACTER_RUNE] this
+   * character is discarded.
+   *
    * If [allowMalformed] is `true` the decoder replaces invalid (or
    * unterminated) character sequences with the Unicode Replacement character
    * `U+FFFD` (�). Otherwise it throws a [FormatException].
@@ -303,6 +309,9 @@
   /**
    * Converts the UTF-8 [codeUnits] (a list of unsigned 8-bit integers) to the
    * corresponding string.
+   *
+   * If the [codeUnits] start with a leading [UNICODE_BOM_CHARACTER_RUNE] this
+   * character is discarded.
    */
   String convert(List<int> codeUnits) {
     StringBuffer buffer = new StringBuffer();
@@ -346,9 +355,6 @@
 const int _LEAD_SURROGATE_MIN = 0xD800;
 const int _TAIL_SURROGATE_MIN = 0xDC00;
 
-const int _REPLACEMENT_CHARACTER = 0xFFFD;
-const int _BOM_CHARACTER = 0xFEFF;
-
 bool _isSurrogate(int codeUnit) =>
     (codeUnit & _SURROGATE_MASK) == _LEAD_SURROGATE_MIN;
 bool _isLeadSurrogate(int codeUnit) =>
@@ -356,7 +362,7 @@
 bool _isTailSurrogate(int codeUnit) =>
     (codeUnit & _SURROGATE_TAG_MASK) == _TAIL_SURROGATE_MIN;
 int _combineSurrogatePair(int lead, int tail) =>
-    0x10000 | ((lead & _SURROGATE_VALUE_MASK) << 10)
+    0x10000 + ((lead & _SURROGATE_VALUE_MASK) << 10)
             | (tail & _SURROGATE_VALUE_MASK);
 
 
@@ -400,7 +406,7 @@
       if (!_allowMalformed) {
         throw new FormatException("Unfinished UTF-8 octet sequence");
       }
-      _stringSink.writeCharCode(_REPLACEMENT_CHARACTER);
+      _stringSink.writeCharCode(UNICODE_REPLACEMENT_CHARACTER_RUNE);
       _value = 0;
       _expectedUnits = 0;
       _extraUnits = 0;
@@ -430,7 +436,7 @@
                   "Bad UTF-8 encoding 0x${unit.toRadixString(16)}");
             }
             _isFirstCharacter = false;
-            _stringSink.writeCharCode(_REPLACEMENT_CHARACTER);
+            _stringSink.writeCharCode(UNICODE_REPLACEMENT_CHARACTER_RUNE);
             break multibyte;
           } else {
             value = (value << 6) | (unit & 0x3f);
@@ -446,16 +452,16 @@
                 "Overlong encoding of 0x${value.toRadixString(16)}");
           }
           expectedUnits = extraUnits = 0;
-          value = _REPLACEMENT_CHARACTER;
+          value = UNICODE_REPLACEMENT_CHARACTER_RUNE;
         }
         if (value > _FOUR_BYTE_LIMIT) {
           if (!_allowMalformed) {
             throw new FormatException("Character outside valid Unicode range: "
                                       "0x${value.toRadixString(16)}");
           }
-          value = _REPLACEMENT_CHARACTER;
+          value = UNICODE_REPLACEMENT_CHARACTER_RUNE;
         }
-        if (!_isFirstCharacter || value != _BOM_CHARACTER) {
+        if (!_isFirstCharacter || value != UNICODE_BOM_CHARACTER_RUNE) {
           _stringSink.writeCharCode(value);
         }
         _isFirstCharacter = false;
@@ -474,7 +480,7 @@
             throw new FormatException(
                 "Negative UTF-8 code unit: -0x${(-unit).toRadixString(16)}");
           }
-          _stringSink.writeCharCode(_REPLACEMENT_CHARACTER);
+          _stringSink.writeCharCode(UNICODE_REPLACEMENT_CHARACTER_RUNE);
         } else if (unit <= _ONE_BYTE_LIMIT) {
           _isFirstCharacter = false;
           _stringSink.writeCharCode(unit);
@@ -499,7 +505,7 @@
             throw new FormatException(
                 "Bad UTF-8 encoding 0x${unit.toRadixString(16)}");
           }
-          value = _REPLACEMENT_CHARACTER;
+          value = UNICODE_REPLACEMENT_CHARACTER_RUNE;
           expectedUnits = extraUnits = 0;
           _isFirstCharacter = false;
           _stringSink.writeCharCode(value);
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index d311785..a0473cb 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -19,42 +19,49 @@
  * The following code illustrates that some List implementations support
  * only a subset of the API.
  *
- *     var fixedLengthList = new List(5);
- *     fixedLengthList.length = 0;  // Error.
- *     fixedLengthList.add(499);    // Error.
+ *     List<int> fixedLengthList = new List(5);
+ *     fixedLengthList.length = 0;  // Error
+ *     fixedLengthList.add(499);    // Error
  *     fixedLengthList[0] = 87;
- *
- *     var growableList = [1, 2];
+ *     List<int> growableList = [1, 2];
  *     growableList.length = 0;
  *     growableList.add(499);
  *     growableList[0] = 87;
  *
- * Lists are [Iterable].
- * 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 does not detect it.
+ * Lists are [Iterable]. 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
+ * 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 created list is fixed-length if _length_ is provided.
-   * The list has length 0 and is growable if _length_ is omitted.
+   * The created list is fixed-length if [length] is provided.
    *
-   * An error occurs if _length_ is negative.
+   *     List fixedLengthList = new List(3);
+   *     fixedLengthList.length;     // 3
+         fixedLengthList.length = 1; // Error
+   *
+   *
+   * The list has length 0 and is growable if [length] is omitted.
+   *
+   *     List growableList = new List();
+   *     growableList.length; // 0;
+   *     growableList.length = 3;
+   *
+   * An error occurs if [length] is negative.
    */
   external factory List([int length]);
 
   /**
-   * Creates a fixed-length list of the given _length_
-   * and initializes the value at each position with [fill].
+   * Creates a fixed-length list of the given length, and initializes the
+   * value at each position with [fill]:
+   *
+   *     new List<int>.filled(3, 0); // [0, 0, 0]
    */
   external factory List.filled(int length, E fill);
 
@@ -83,11 +90,12 @@
   /**
    * Generates a list of values.
    *
-   * Creates a list with _length_ positions
-   * and fills it with 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.
    *
+   *     new List<int>.generate(3, (int index) => index * index); // [0, 1, 4]
+   *
    * The created list is fixed-length unless [growable] is true.
    */
   factory List.generate(int length, E generator(int index),
@@ -127,7 +135,7 @@
    * Changes the length of this list.
    *
    * If [newLength] is greater than
-   * the current [length], entries are initialized to [:null:].
+   * the current length, entries are initialized to [:null:].
    *
    * Throws an [UnsupportedError] if the list is fixed-length.
    */
@@ -158,19 +166,35 @@
    * Sorts this list according to the order specified by the [compare] function.
    *
    * The [compare] function must act as a [Comparator].
+
+   *     List<String> numbers = ['one', 'two', 'three', 'four'];
+   *     // Sort from shortest to longest.
+   *     numbers.sort((x, y) => x.length.compareTo(y.length));
+   *     numbers.join(', '); // 'one, two, four, three'
    *
    * The default List implementations use [Comparable.compare] if
    * [compare] is omitted.
+   *
+   *     List<int> nums = [13, 2, -11];
+   *     nums.sort();
+         nums.join(', '); // '-11, 2, 13'
    */
   void sort([int compare(E a, E b)]);
 
   /**
    * Returns the first index of [element] in this list.
    *
-   * Searches the list from index [start] to the length of the list.
+   * Searches the list from index [start] to the end of the list.
    * The first time an object [:o:] is encountered so that [:o == element:],
    * the index of [:o:] is returned.
+   *
+   *     List<String> notes = ['do', 're', 'mi', 're'];
+   *     notes.indexOf('re');    // 1
+   *     notes.indexOf('re', 2); // 3
+   *
    * Returns -1 if [element] is not found.
+   *
+   *     notes.indexOf('fa');    // -1
    */
   int indexOf(E element, [int start = 0]);
 
@@ -182,9 +206,17 @@
    * 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:].
+   *     List<String> notes = ['do', 're', 'mi', 're'];
+   *     notes.lastIndexOf('re', 2); // 1
+   *
+   * If [start] is not provided, this method searches from the end of the
+   * list./Returns
+   *
+   *     notes.lastIndexOf('re');  // 3
    *
    * Returns -1 if [element] is not found.
+   *
+   *     notes.lastIndexOf('fa');  // -1
    */
   int lastIndexOf(E element, [int start]);
 
@@ -223,6 +255,10 @@
    * Overwrites objects of `this` with the objects of [iterable], starting
    * at position [index] in this list.
    *
+   *     List<String> list = ['a', 'b', 'c'];
+   *     list.setAll(1, ['bee', 'sea']);
+   *     list.join(', '); // 'a, bee, sea'
+   *
    * This operation does not increase the length of `this`.
    *
    * An error occurs if the [index] is less than 0 or greater than length.
@@ -233,11 +269,18 @@
   /**
    * Removes the first occurence of [value] from this list.
    *
-   * Returns true if [value] was in the list.
-   * Returns false otherwise.
+   * Returns true if [value] was in the list, false otherwise.
+   *
+   *     List<String> parts = ['head', 'shoulders', 'knees', 'toes'];
+   *     parts.remove('head'); // true
+   *     parts.join(', ');     // 'shoulders, knees, toes'
    *
    * The method has no effect if [value] was not in the list.
    *
+   *     // Note: 'head' has already been removed.
+   *     parts.remove('head'); // false
+   *     parts.join(', ');     // 'shoulders, knees, toes'
+   *
    * An [UnsupportedError] occurs if the list is fixed-length.
    */
   bool remove(Object value);
@@ -269,6 +312,10 @@
    *
    * An object [:o:] satisfies [test] if [:test(o):] is true.
    *
+   *     List<String> numbers = ['one', 'two', 'three', 'four'];
+   *     numbers.removeWhere((item) => item.length == 3);
+   *     numbers.join(', '); // 'three, four'
+   *
    * Throws an [UnsupportedError] if this is a fixed-length list.
    */
   void removeWhere(bool test(E element));
@@ -278,16 +325,25 @@
    *
    * An object [:o:] satisfies [test] if [:test(o):] is true.
    *
+   *     List<String> numbers = ['one', 'two', 'three', 'four'];
+   *     numbers.retainWhere((item) => item.length == 3);
+   *     numbers.join(', '); // 'one, two'
+   *
    * Throws an [UnsupportedError] if this is a fixed-length list.
    */
   void retainWhere(bool test(E element));
 
   /**
-   * Returns a new list containing the objects
-   * from [start] inclusive to [end] exclusive.
+   * Returns a new list containing the objects from [start] inclusive to [end]
+   * exclusive.
+   *
+   *     List<String> colors = ['red', 'green', 'blue', 'orange', 'pink'];
+   *     colors.sublist(1, 3); // ['green', 'blue']
    *
    * If [end] is omitted, the [length] of `this` is used.
    *
+   *     colors.sublist(1);  // ['green', 'blue', 'orange', 'pink']
+   *
    * An error occurs if [start] is outside the range `0` .. `length` or if
    * [end] is outside the range `start` .. `length`.
    */
@@ -304,13 +360,11 @@
    * `skip(start).take(end - start)`. That is, it does not throw exceptions
    * if `this` changes size.
    *
-   * Example:
-   *
-   *     var list = [1, 2, 3, 4, 5];
-   *     var range = list.getRange(1, 4);
-   *     print(range.join(', '));  // => 2, 3, 4
-   *     list.length = 3;
-   *     print(range.join(', '));  // => 2, 3
+   *     List<String> colors = ['red', 'green', 'blue', 'orange', 'pink'];
+   *     Iterable<String> range = colors.getRange(1, 4);
+   *     range.join(', ');  // 'green, blue, orange'
+   *     colors.length = 3;
+   *     range.join(', ');  // 'green, blue'
    */
   Iterable<E> getRange(int start, int end);
 
@@ -318,6 +372,13 @@
    * Copies the objects of [iterable], skipping [skipCount] objects first,
    * into the range [start] inclusive to [end] exclusive of `this`.
    *
+   *     List<int> list1 = [1, 2, 3, 4];
+   *     List<int> list2 = [5, 6, 7, 8, 9];
+   *     // Copies the 4th and 5th items in list2 as the 2nd and 3rd items
+   *     // of list1.
+   *     list1.setRange(1, 3, list2, 3);
+   *     list1.join(', '); // '1, 8, 9, 4'
+   *
    * If [start] equals [end] and [start]..[end] represents a legal range, this
    * method has no effect.
    *
@@ -325,12 +386,6 @@
    * An error occurs if the [iterable] does not have enough objects after
    * skipping [skipCount] objects.
    *
-   * Example:
-   *
-   *     var list = [1, 2, 3, 4];
-   *     var list2 = [5, 6, 7, 8, 9];
-   *     list.setRange(1, 3, list2, 3);
-   *     print(list);  // => [1, 8, 9, 4]
    */
   void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]);
 
@@ -354,13 +409,11 @@
    * Removes the objects in the range [start] inclusive to [end] exclusive
    * and replaces them with the contents of the [iterable].
    *
+   *     List<int> list = [1, 2, 3, 4];
+   *     list.replaceRange(1, 3, [6, 7]);
+   *     list.join(', '); // '1, 6, 7, 4'
+   *
    * An error occurs if [start]..[end] is not a valid range for `this`.
-   *
-   * Example:
-   *
-   *     var list = [1, 2, 3, 4, 5];
-   *     list.replaceRange(1, 3, [6, 7, 8, 9]);
-   *     print(list);  // [1, 6, 7, 8, 9, 4, 5]
    */
   void replaceRange(int start, int end, Iterable<E> iterable);
 
@@ -370,6 +423,11 @@
    * 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.
+   *
+   *     List<String> words = ['fee', 'fi', 'fo', 'fum'];
+   *     Map<int, String> map = words.asMap();
+   *     map[0] + map[1];   // 'feefi';
+   *     map.keys.toList(); // [0, 1, 2, 3]
    */
   Map<int, E> asMap();
 }
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index db187f5..38cb7cf 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.dart
@@ -5,8 +5,8 @@
 part of dart.core;
 
 /**
- * An unordered collection of key-value pairs,
- * from which you retrieve a value by using its associated key.
+ * An unordered collection of key-value pairs, from which you retrieve a value
+ * by using its associated key.
  *
  * Each key can occur at most once in a map.
  */
@@ -27,18 +27,36 @@
   factory Map.identity() = LinkedHashMap<K, V>.identity;
 
   /**
-   * Creates a Map instance
-   * where the keys and values are computed from the [iterable].
+   * Creates a Map instance in which the keys and values are computed from the
+   * [iterable].
    *
    * For each element of the [iterable] this constructor computes a key-value
    * pair, by applying [key] and [value] respectively.
    *
-   * The keys computed by the source [iterable]
-   * do not need to be unique. The last
-   * occurrence of a key will simply overwrite any previous value.
+   * The example below creates a new Map from a List. The keys of `map` are
+   * `list` values converted to strings, and the values of the `map` are the
+   * squares of the `list` values:
+   *
+   *     List<int> list = [1, 2, 3];
+   *     Map<String, int> map = new Map.fromIterable(list,
+   *         key: (item) => item.toString(),
+   *         value: (item) => item * item));
+   *
+   *     map['1'] + map['2']; // 1 + 4
+   *     map['3'] - map['2']; // 9 - 4
    *
    * If no values are specified for [key] and [value] the default is the
    * identity function.
+   *
+   * In the following example, the keys and corresponding values of `map`
+   * are `list` values:
+   *
+   *     map = new Map.fromIterable(list);
+   *     map[1] + map[2]; // 1 + 2
+   *     map[3] - map[2]; // 3 - 2
+   *
+   * The keys computed by the source [iterable] do not need to be unique. The
+   * last occurrence of a key will simply overwrite any previous value.
    */
   factory Map.fromIterable(Iterable iterable,
       {K key(element), V value(element)}) = LinkedHashMap<K, V>.fromIterable;
@@ -49,6 +67,11 @@
    * This constructor iterates over [keys] and [values] and maps each element of
    * [keys] to the corresponding element of [values].
    *
+   *     List<String> letters = ['b', 'c'];
+   *     List<String> words = ['bad', 'cat'];
+   *     Map<String, String> map = new Map.fromIterables(letters, words);
+   *     map['b'] + map['c'];  // badcat
+   *
    * If [keys] contains the same object multiple times, the last occurrence
    * overwrites the previous value.
    *
@@ -85,8 +108,15 @@
    * updates the map by mapping [key] to the value returned by
    * [ifAbsent]. Returns the value in the map.
    *
-   * It is an error to add or remove keys from the map during the call to
-   * [ifAbsent].
+   *     Map<String, int> scores = {'Bob': 36};
+   *     for (var key in ['Bob', 'Rohan', 'Sophena']) {
+   *       scores.putIfAbsent(key, () => key.length);
+   *     }
+   *     scores['Bob'];      // 36
+   *     scores['Rohan'];    //  5
+   *     scores['Sophena'];  //  7
+   *
+   * The code that [ifAbsent] executes must not add or remove keys.
    */
   V putIfAbsent(K key, V ifAbsent());
 
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index f1199d0..6c9cfd9 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -88,8 +88,20 @@
 // Dart issue 1990.
 class HtmlElement extends Element native "HTMLElement" {
   factory HtmlElement() { throw new UnsupportedError("Not supported"); }
+
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HtmlElement.created() : super.created();
 }
 
+// EntryArray type was removed, so explicitly adding it to allow support for
+// older Chrome versions.
+// Issue #12573.
+abstract class _EntryArray implements List<Entry> native "EntryArray" {}
+
 // Support for Send/ReceivePortSync.
 int _getNewIsolateId() {
   if (JS('bool', r'!window.$dart$isolate$counter')) {
@@ -186,6 +198,12 @@
     if (href != null) e.href = href;
     return e;
   }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnchorElement.created() : super.created();
 
   @DomName('HTMLAnchorElement.download')
   @DocsEditable()
@@ -431,6 +449,12 @@
   @DomName('HTMLAreaElement.HTMLAreaElement')
   @DocsEditable()
   factory AreaElement() => document.createElement("area");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AreaElement.created() : super.created();
 
   @DomName('HTMLAreaElement.alt')
   @DocsEditable()
@@ -507,6 +531,12 @@
   }
   static AudioElement _create_1(src) => JS('AudioElement', 'new Audio(#)', src);
   static AudioElement _create_2() => JS('AudioElement', 'new Audio()');
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AudioElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -539,6 +569,12 @@
   @DomName('HTMLBRElement.HTMLBRElement')
   @DocsEditable()
   factory BRElement() => document.createElement("br");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  BRElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -569,6 +605,12 @@
   @DomName('HTMLBaseElement.HTMLBaseElement')
   @DocsEditable()
   factory BaseElement() => document.createElement("base");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  BaseElement.created() : super.created();
 
   @DomName('HTMLBaseElement.href')
   @DocsEditable()
@@ -696,6 +738,12 @@
   @DomName('HTMLBodyElement.HTMLBodyElement')
   @DocsEditable()
   factory BodyElement() => document.createElement("body");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  BodyElement.created() : super.created();
 
   @DomName('HTMLBodyElement.onblur')
   @DocsEditable()
@@ -759,6 +807,12 @@
   @DomName('HTMLButtonElement.HTMLButtonElement')
   @DocsEditable()
   factory ButtonElement() => document.createElement("button");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ButtonElement.created() : super.created();
 
   @DomName('HTMLButtonElement.autofocus')
   @DocsEditable()
@@ -885,6 +939,12 @@
     if (height != null) e.height = height;
     return e;
   }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  CanvasElement.created() : super.created();
 
   /// The height of this canvas element in CSS pixels.
   @DomName('HTMLCanvasElement.height')
@@ -1974,6 +2034,12 @@
   @DomName('HTMLContentElement.HTMLContentElement')
   @DocsEditable()
   factory ContentElement() => document.createElement("content");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ContentElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => Element.isTagSupported('content');
@@ -6316,6 +6382,12 @@
   @DomName('HTMLDListElement.HTMLDListElement')
   @DocsEditable()
   factory DListElement() => document.createElement("dl");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DListElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -6335,6 +6407,12 @@
   @DomName('HTMLDataListElement.HTMLDataListElement')
   @DocsEditable()
   factory DataListElement() => document.createElement("datalist");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DataListElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => Element.isTagSupported('datalist');
@@ -6550,6 +6628,12 @@
   @DomName('HTMLDetailsElement.HTMLDetailsElement')
   @DocsEditable()
   factory DetailsElement() => document.createElement("details");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DetailsElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => Element.isTagSupported('details');
@@ -6687,6 +6771,12 @@
 class DialogElement extends HtmlElement native "HTMLDialogElement" {
   // To suppress missing implicit constructor warnings.
   factory DialogElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DialogElement.created() : super.created();
 
   @DomName('HTMLDialogElement.open')
   @DocsEditable()
@@ -6941,6 +7031,12 @@
   @DomName('HTMLDivElement.HTMLDivElement')
   @DocsEditable()
   factory DivElement() => document.createElement("div");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DivElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -7603,7 +7699,6 @@
   @Experimental()
   Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);
 
-
   /**
    * Finds all descendant elements of this document that match the specified
    * group of selectors.
@@ -8805,6 +8900,30 @@
   }
 
   /**
+   * Custom element creation constructor.
+   *
+   * This constructor is used by the DOM when a custom element has been
+   * created. It can only be invoked by subclasses of Element from
+   * that classes created constructor.
+   *
+   *     class CustomElement extends Element {
+   *       factory CustomElement() => new Element.tag('x-custom');
+   *
+   *       CustomElement.created() : super.created() {
+   *          // Perform any element initialization.
+   *       }
+   *     }
+   *     document.register('x-custom', CustomElement);
+   */
+  Element.created() : super._created() {
+    // Validate that this is a custom element & perform any additional
+    // initialization.
+    _initializeCustomElement(this);
+
+    createdCallback();
+  }
+
+  /**
    * Creates the HTML element specified by the tag name.
    *
    * This is similar to [Document.createElement].
@@ -9147,9 +9266,12 @@
 
   /**
    * Called by the DOM when this element has been instantiated.
+   *
+   * Will be replaced by created constructor.
    */
   @Experimental()
-  void created() {}
+  @deprecated
+  void createdCallback() {}
 
   /**
    * Called by the DOM when this element has been inserted into the live
@@ -9165,6 +9287,11 @@
   @Experimental()
   void leftView() {}
 
+  /**
+   * Called by the DOM whenever an attribute on this has been changed.
+   */
+  void attributeChanged(String name, String oldValue, String newValue) {}
+
   // Hooks to support custom WebComponents.
 
   @Creates('Null')  // Set from Dart code; does not instantiate a native type.
@@ -10658,6 +10785,12 @@
   @DomName('HTMLEmbedElement.HTMLEmbedElement')
   @DocsEditable()
   factory EmbedElement() => document.createElement("embed");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  EmbedElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => Element.isTagSupported('embed');
@@ -11259,6 +11392,9 @@
 @DomName('EventTarget')
 class EventTarget extends Interceptor native "EventTarget" {
 
+  // Custom element created callback.
+  EventTarget._created();
+
   /**
    * This is an ease-of-use accessor for event streams which should only be
    * used when an explicit accessor is not available.
@@ -11297,6 +11433,12 @@
   @DomName('HTMLFieldSetElement.HTMLFieldSetElement')
   @DocsEditable()
   factory FieldSetElement() => document.createElement("fieldset");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FieldSetElement.created() : super.created();
 
   @DomName('HTMLFieldSetElement.disabled')
   @DocsEditable()
@@ -11991,6 +12133,12 @@
   @DomName('HTMLFormElement.HTMLFormElement')
   @DocsEditable()
   factory FormElement() => document.createElement("form");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FormElement.created() : super.created();
 
   @DomName('HTMLFormElement.acceptCharset')
   @DocsEditable()
@@ -12251,6 +12399,12 @@
   @DomName('HTMLHRElement.HTMLHRElement')
   @DocsEditable()
   factory HRElement() => document.createElement("hr");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HRElement.created() : super.created();
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -12307,6 +12461,12 @@
   @DomName('HTMLHeadElement.HTMLHeadElement')
   @DocsEditable()
   factory HeadElement() => document.createElement("head");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HeadElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -12342,6 +12502,12 @@
   @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable()
   factory HeadingElement.h6() => document.createElement("h6");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HeadingElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -12900,6 +13066,12 @@
   @DomName('HTMLHtmlElement.HTMLHtmlElement')
   @DocsEditable()
   factory HtmlHtmlElement() => document.createElement("html");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HtmlHtmlElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -13001,7 +13173,7 @@
   }
 
   /**
-   * Creates a URL request for the specified [url].
+   * Creates and sends a URL request for the specified [url].
    *
    * By default `request` will perform an HTTP GET request, but a different
    * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the 
@@ -13485,6 +13657,12 @@
   @DomName('HTMLIFrameElement.HTMLIFrameElement')
   @DocsEditable()
   factory IFrameElement() => document.createElement("iframe");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  IFrameElement.created() : super.created();
 
   @DomName('HTMLIFrameElement.contentWindow')
   @DocsEditable()
@@ -13584,6 +13762,12 @@
     if (height != null) e.height = height;
     return e;
   }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ImageElement.created() : super.created();
 
   @DomName('HTMLImageElement.alt')
   @DocsEditable()
@@ -13697,6 +13881,12 @@
   @Experimental()
   // http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#extending_html_elements
   static const EventStreamProvider<Event> speechChangeEvent = const EventStreamProvider<Event>('webkitSpeechChange');
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  InputElement.created() : super.created();
 
   @DomName('HTMLInputElement.accept')
   @DocsEditable()
@@ -14718,6 +14908,12 @@
   @DomName('HTMLKeygenElement.HTMLKeygenElement')
   @DocsEditable()
   factory KeygenElement() => document.createElement("keygen");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  KeygenElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => Element.isTagSupported('keygen') && (new Element.tag('keygen') is KeygenElement);
@@ -14791,6 +14987,12 @@
   @DomName('HTMLLIElement.HTMLLIElement')
   @DocsEditable()
   factory LIElement() => document.createElement("li");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LIElement.created() : super.created();
 
   @DomName('HTMLLIElement.type')
   @DocsEditable()
@@ -14816,6 +15018,12 @@
   @DomName('HTMLLabelElement.HTMLLabelElement')
   @DocsEditable()
   factory LabelElement() => document.createElement("label");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LabelElement.created() : super.created();
 
   @DomName('HTMLLabelElement.control')
   @DocsEditable()
@@ -14843,6 +15051,12 @@
   @DomName('HTMLLegendElement.HTMLLegendElement')
   @DocsEditable()
   factory LegendElement() => document.createElement("legend");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LegendElement.created() : super.created();
 
   @DomName('HTMLLegendElement.form')
   @DocsEditable()
@@ -14862,6 +15076,12 @@
   @DomName('HTMLLinkElement.HTMLLinkElement')
   @DocsEditable()
   factory LinkElement() => document.createElement("link");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LinkElement.created() : super.created();
 
   @DomName('HTMLLinkElement.disabled')
   @DocsEditable()
@@ -15009,6 +15229,12 @@
   @DomName('HTMLMapElement.HTMLMapElement')
   @DocsEditable()
   factory MapElement() => document.createElement("map");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MapElement.created() : super.created();
 
   @DomName('HTMLMapElement.areas')
   @DocsEditable()
@@ -15223,6 +15449,12 @@
   @Experimental()
   // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
   static const EventStreamProvider<MediaKeyEvent> needKeyEvent = const EventStreamProvider<MediaKeyEvent>('webkitneedkey');
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MediaElement.created() : super.created();
 
   @DomName('HTMLMediaElement.HAVE_CURRENT_DATA')
   @DocsEditable()
@@ -16226,6 +16458,12 @@
   @DomName('HTMLMenuElement.HTMLMenuElement')
   @DocsEditable()
   factory MenuElement() => document.createElement("menu");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MenuElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -16373,6 +16611,12 @@
   @DomName('HTMLMetaElement.HTMLMetaElement')
   @DocsEditable()
   factory MetaElement() => document.createElement("meta");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MetaElement.created() : super.created();
 
   @DomName('HTMLMetaElement.content')
   @DocsEditable()
@@ -16439,6 +16683,12 @@
   @DomName('HTMLMeterElement.HTMLMeterElement')
   @DocsEditable()
   factory MeterElement() => document.createElement("meter");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MeterElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => Element.isTagSupported('meter');
@@ -16750,6 +17000,12 @@
 class ModElement extends HtmlElement native "HTMLModElement" {
   // To suppress missing implicit constructor warnings.
   factory ModElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ModElement.created() : super.created();
 
   @DomName('HTMLModElement.cite')
   @DocsEditable()
@@ -17708,6 +17964,10 @@
 
 @DomName('Node')
 class Node extends EventTarget native "Node" {
+
+  // Custom element created callback.
+  Node._created() : super._created();
+
   List<Node> get nodes {
     return new _ChildNodeListLazy(this);
   }
@@ -18387,6 +18647,12 @@
   @DomName('HTMLOListElement.HTMLOListElement')
   @DocsEditable()
   factory OListElement() => document.createElement("ol");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  OListElement.created() : super.created();
 
   @DomName('HTMLOListElement.reversed')
   @DocsEditable()
@@ -18418,6 +18684,12 @@
   @DomName('HTMLObjectElement.HTMLObjectElement')
   @DocsEditable()
   factory ObjectElement() => document.createElement("object");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ObjectElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => Element.isTagSupported('object');
@@ -18498,6 +18770,12 @@
   @DomName('HTMLOptGroupElement.HTMLOptGroupElement')
   @DocsEditable()
   factory OptGroupElement() => document.createElement("optgroup");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  OptGroupElement.created() : super.created();
 
   @DomName('HTMLOptGroupElement.disabled')
   @DocsEditable()
@@ -18507,20 +18785,21 @@
   @DocsEditable()
   String label;
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 
-@DocsEditable()
 @DomName('HTMLOptionElement')
 class OptionElement extends HtmlElement native "HTMLOptionElement" {
-  // To suppress missing implicit constructor warnings.
-  factory OptionElement._() { throw new UnsupportedError("Not supported"); }
+  factory OptionElement({String data, String value, bool defaultSelected, 
+      bool selected}) {
+    return new OptionElement._(data, value, defaultSelected, selected);
+  }
 
   @DomName('HTMLOptionElement.HTMLOptionElement')
   @DocsEditable()
-  factory OptionElement([String data, String value, bool defaultSelected, bool selected]) {
+  factory OptionElement._([String data, String value, bool defaultSelected, bool selected]) {
     if (selected != null) {
       return OptionElement._create_1(data, value, defaultSelected, selected);
     }
@@ -18540,6 +18819,12 @@
   static OptionElement _create_3(data, value) => JS('OptionElement', 'new Option(#,#)', data, value);
   static OptionElement _create_4(data) => JS('OptionElement', 'new Option(#)', data);
   static OptionElement _create_5() => JS('OptionElement', 'new Option()');
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  OptionElement.created() : super.created();
 
   @DomName('HTMLOptionElement.defaultSelected')
   @DocsEditable()
@@ -18568,6 +18853,7 @@
   @DomName('HTMLOptionElement.value')
   @DocsEditable()
   String value;
+
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -18586,6 +18872,12 @@
   @DomName('HTMLOutputElement.HTMLOutputElement')
   @DocsEditable()
   factory OutputElement() => document.createElement("output");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  OutputElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => Element.isTagSupported('output');
@@ -18708,6 +19000,12 @@
   @DomName('HTMLParagraphElement.HTMLParagraphElement')
   @DocsEditable()
   factory ParagraphElement() => document.createElement("p");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ParagraphElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -18724,6 +19022,12 @@
   @DomName('HTMLParamElement.HTMLParamElement')
   @DocsEditable()
   factory ParamElement() => document.createElement("param");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ParamElement.created() : super.created();
 
   @DomName('HTMLParamElement.name')
   @DocsEditable()
@@ -19366,6 +19670,12 @@
   @DomName('HTMLPreElement.HTMLPreElement')
   @DocsEditable()
   factory PreElement() => document.createElement("pre");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PreElement.created() : super.created();
 
   @DomName('HTMLPreElement.wrap')
   @DocsEditable()
@@ -19411,6 +19721,12 @@
   @DomName('HTMLProgressElement.HTMLProgressElement')
   @DocsEditable()
   factory ProgressElement() => document.createElement("progress");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ProgressElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => Element.isTagSupported('progress');
@@ -19536,6 +19852,12 @@
   @DomName('HTMLQuoteElement.HTMLQuoteElement')
   @DocsEditable()
   factory QuoteElement() => document.createElement("q");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  QuoteElement.created() : super.created();
 
   @DomName('HTMLQuoteElement.cite')
   @DocsEditable()
@@ -20558,6 +20880,12 @@
   @DomName('HTMLScriptElement.HTMLScriptElement')
   @DocsEditable()
   factory ScriptElement() => document.createElement("script");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ScriptElement.created() : super.created();
 
   @DomName('HTMLScriptElement.async')
   @DocsEditable()
@@ -20745,6 +21073,12 @@
   @DomName('HTMLSelectElement.HTMLSelectElement')
   @DocsEditable()
   factory SelectElement() => document.createElement("select");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SelectElement.created() : super.created();
 
   @DomName('HTMLSelectElement.autofocus')
   @DocsEditable()
@@ -20988,6 +21322,12 @@
   @DomName('HTMLShadowElement.HTMLShadowElement')
   @DocsEditable()
   factory ShadowElement() => document.createElement("shadow");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ShadowElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => Element.isTagSupported('shadow');
@@ -21231,6 +21571,12 @@
   @DomName('HTMLSourceElement.HTMLSourceElement')
   @DocsEditable()
   factory SourceElement() => document.createElement("source");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SourceElement.created() : super.created();
 
   @DomName('HTMLSourceElement.media')
   @DocsEditable()
@@ -21288,6 +21634,12 @@
   @DomName('HTMLSpanElement.HTMLSpanElement')
   @DocsEditable()
   factory SpanElement() => document.createElement("span");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SpanElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -22187,6 +22539,12 @@
   @DomName('HTMLStyleElement.HTMLStyleElement')
   @DocsEditable()
   factory StyleElement() => document.createElement("style");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  StyleElement.created() : super.created();
 
   @DomName('HTMLStyleElement.disabled')
   @DocsEditable()
@@ -22278,6 +22636,12 @@
   @DomName('HTMLTableCaptionElement.HTMLTableCaptionElement')
   @DocsEditable()
   factory TableCaptionElement() => document.createElement("caption");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableCaptionElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -22293,6 +22657,12 @@
   @DomName('HTMLTableCellElement.HTMLTableCellElement')
   @DocsEditable()
   factory TableCellElement() => document.createElement("td");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableCellElement.created() : super.created();
 
   @DomName('HTMLTableCellElement.cellIndex')
   @DocsEditable()
@@ -22324,6 +22694,12 @@
   @DomName('HTMLTableColElement.HTMLTableColElement')
   @DocsEditable()
   factory TableColElement() => document.createElement("col");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableColElement.created() : super.created();
 
   @DomName('HTMLTableColElement.span')
   @DocsEditable()
@@ -22390,6 +22766,12 @@
   @DomName('HTMLTableElement.HTMLTableElement')
   @DocsEditable()
   factory TableElement() => document.createElement("table");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableElement.created() : super.created();
 
   @DomName('HTMLTableElement.border')
   @DocsEditable()
@@ -22495,6 +22877,12 @@
   @DomName('HTMLTableRowElement.HTMLTableRowElement')
   @DocsEditable()
   factory TableRowElement() => document.createElement("tr");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableRowElement.created() : super.created();
 
   @JSName('cells')
   @DomName('HTMLTableRowElement.cells')
@@ -22553,6 +22941,12 @@
 
   // To suppress missing implicit constructor warnings.
   factory TableSectionElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableSectionElement.created() : super.created();
 
   @JSName('rows')
   @DomName('HTMLTableSectionElement.rows')
@@ -22669,6 +23063,12 @@
   @DomName('HTMLTemplateElement.HTMLTemplateElement')
   @DocsEditable()
   factory TemplateElement() => document.createElement("template");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TemplateElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => Element.isTagSupported('template');
@@ -22942,6 +23342,12 @@
   @DomName('HTMLTextAreaElement.HTMLTextAreaElement')
   @DocsEditable()
   factory TextAreaElement() => document.createElement("textarea");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextAreaElement.created() : super.created();
 
   @DomName('HTMLTextAreaElement.autofocus')
   @DocsEditable()
@@ -23447,6 +23853,12 @@
   @DomName('HTMLTitleElement.HTMLTitleElement')
   @DocsEditable()
   factory TitleElement() => document.createElement("title");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TitleElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -23713,6 +24125,12 @@
   @DomName('HTMLTrackElement.HTMLTrackElement')
   @DocsEditable()
   factory TrackElement() => document.createElement("track");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TrackElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => Element.isTagSupported('track');
@@ -23990,6 +24408,12 @@
   @DomName('HTMLUListElement.HTMLUListElement')
   @DocsEditable()
   factory UListElement() => document.createElement("ul");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  UListElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -24001,6 +24425,12 @@
 class UnknownElement extends HtmlElement native "HTMLUnknownElement" {
   // To suppress missing implicit constructor warnings.
   factory UnknownElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  UnknownElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -24096,6 +24526,12 @@
   @DomName('HTMLVideoElement.HTMLVideoElement')
   @DocsEditable()
   factory VideoElement() => document.createElement("video");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  VideoElement.created() : super.created();
 
   @DomName('HTMLVideoElement.height')
   @DocsEditable()
@@ -27068,6 +27504,12 @@
 abstract class _HTMLAppletElement extends HtmlElement native "HTMLAppletElement" {
   // To suppress missing implicit constructor warnings.
   factory _HTMLAppletElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLAppletElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -27081,6 +27523,12 @@
 abstract class _HTMLBaseFontElement extends HtmlElement native "HTMLBaseFontElement" {
   // To suppress missing implicit constructor warnings.
   factory _HTMLBaseFontElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLBaseFontElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -27094,6 +27542,12 @@
 abstract class _HTMLDirectoryElement extends HtmlElement native "HTMLDirectoryElement" {
   // To suppress missing implicit constructor warnings.
   factory _HTMLDirectoryElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLDirectoryElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -27107,6 +27561,12 @@
 abstract class _HTMLFontElement extends HtmlElement native "HTMLFontElement" {
   // To suppress missing implicit constructor warnings.
   factory _HTMLFontElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLFontElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -27120,6 +27580,12 @@
 abstract class _HTMLFrameElement extends HtmlElement native "HTMLFrameElement" {
   // To suppress missing implicit constructor warnings.
   factory _HTMLFrameElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLFrameElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -27133,6 +27599,12 @@
 abstract class _HTMLFrameSetElement extends HtmlElement native "HTMLFrameSetElement" {
   // To suppress missing implicit constructor warnings.
   factory _HTMLFrameSetElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLFrameSetElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -27146,6 +27618,12 @@
 abstract class _HTMLMarqueeElement extends HtmlElement native "HTMLMarqueeElement" {
   // To suppress missing implicit constructor warnings.
   factory _HTMLMarqueeElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLMarqueeElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -32060,7 +32538,7 @@
 
 
 _callCreated(receiver) {
-  return receiver.created();
+  return receiver.createdCallback();
 }
 
 _callEnteredView(receiver) {
@@ -32070,6 +32548,9 @@
 _callLeftView(receiver) {
   return receiver.leftView();
 }
+ _callAttributeChanged(receiver, name, oldValue, newValue) {
+  return receiver.attributeChanged(name, oldValue, newValue);
+}
 
 _makeCallbackMethod(callback) {
   return JS('',
@@ -32081,6 +32562,16 @@
       convertDartClosureToJS(callback, 1));
 }
 
+_makeCallbackMethod3(callback) {
+  return JS('',
+      '''((function(invokeCallback) {
+             return function(arg1, arg2, arg3) {
+               return invokeCallback(this, arg1, arg2, arg3);
+             };
+          })(#))''',
+      convertDartClosureToJS(callback, 4));
+}
+
 const _typeNameToTag = const {
   'HTMLAnchorElement': 'a',
   'HTMLAudioElement': 'audio',
@@ -32146,6 +32637,8 @@
       JS('=Object', '{value: #}', _makeCallbackMethod(_callEnteredView)));
   JS('void', '#.leftViewCallback = #', properties,
       JS('=Object', '{value: #}', _makeCallbackMethod(_callLeftView)));
+  JS('void', '#.attributeChangedCallback = #', properties,
+      JS('=Object', '{value: #}', _makeCallbackMethod3(_callAttributeChanged)));
 
   // TODO(blois): Bug 13220- remove once transition is complete
   JS('void', '#.enteredDocumentCallback = #', properties,
@@ -32172,6 +32665,11 @@
 
   JS('void', '#.register(#, #)', document, tag, options);
 }
+
+//// Called by Element.created to do validation & initialization.
+void _initializeCustomElement(Element e) {
+  // TODO(blois): Add validation that this is only in response to an upgrade.
+}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 106ac6c..c9879ea 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -208,6 +208,12 @@
     if (href != null) e.href = href;
     return e;
   }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnchorElement.created() : super.created();
 
   @DomName('HTMLAnchorElement.download')
   @DocsEditable()
@@ -538,6 +544,12 @@
   @DomName('HTMLAreaElement.HTMLAreaElement')
   @DocsEditable()
   factory AreaElement() => document.createElement("area");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AreaElement.created() : super.created();
 
   @DomName('HTMLAreaElement.alt')
   @DocsEditable()
@@ -641,6 +653,12 @@
 
   @DocsEditable()
   static AudioElement _create_1(src) native "HTMLAudioElement__create_1constructorCallback";
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AudioElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -679,6 +697,12 @@
   @DomName('HTMLBRElement.HTMLBRElement')
   @DocsEditable()
   factory BRElement() => document.createElement("br");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  BRElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -715,6 +739,12 @@
   @DomName('HTMLBaseElement.HTMLBaseElement')
   @DocsEditable()
   factory BaseElement() => document.createElement("base");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  BaseElement.created() : super.created();
 
   @DomName('HTMLBaseElement.href')
   @DocsEditable()
@@ -862,6 +892,12 @@
   @DomName('HTMLBodyElement.HTMLBodyElement')
   @DocsEditable()
   factory BodyElement() => document.createElement("body");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  BodyElement.created() : super.created();
 
   @DomName('HTMLBodyElement.onblur')
   @DocsEditable()
@@ -928,6 +964,12 @@
   @DomName('HTMLButtonElement.HTMLButtonElement')
   @DocsEditable()
   factory ButtonElement() => document.createElement("button");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ButtonElement.created() : super.created();
 
   @DomName('HTMLButtonElement.autofocus')
   @DocsEditable()
@@ -1103,6 +1145,12 @@
     if (height != null) e.height = height;
     return e;
   }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  CanvasElement.created() : super.created();
 
   /// The height of this canvas element in CSS pixels.
   @DomName('HTMLCanvasElement.height')
@@ -2370,6 +2418,12 @@
   @DomName('HTMLContentElement.HTMLContentElement')
   @DocsEditable()
   factory ContentElement() => document.createElement("content");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ContentElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -6885,6 +6939,12 @@
   @DomName('HTMLDListElement.HTMLDListElement')
   @DocsEditable()
   factory DListElement() => document.createElement("dl");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DListElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6907,6 +6967,12 @@
   @DomName('HTMLDataListElement.HTMLDataListElement')
   @DocsEditable()
   factory DataListElement() => document.createElement("datalist");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DataListElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -7146,6 +7212,12 @@
   @DomName('HTMLDetailsElement.HTMLDetailsElement')
   @DocsEditable()
   factory DetailsElement() => document.createElement("details");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DetailsElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -7298,6 +7370,12 @@
 class DialogElement extends HtmlElement {
   // To suppress missing implicit constructor warnings.
   factory DialogElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DialogElement.created() : super.created();
 
   @DomName('HTMLDialogElement.open')
   @DocsEditable()
@@ -7485,6 +7563,12 @@
   @DomName('HTMLDivElement.HTMLDivElement')
   @DocsEditable()
   factory DivElement() => document.createElement("div");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DivElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -8144,7 +8228,6 @@
   @Experimental()
   Stream<Event> get onPointerLockError => pointerLockErrorEvent.forTarget(this);
 
-
   /**
    * Finds all descendant elements of this document that match the specified
    * group of selectors.
@@ -9373,6 +9456,30 @@
   }
 
   /**
+   * Custom element creation constructor.
+   *
+   * This constructor is used by the DOM when a custom element has been
+   * created. It can only be invoked by subclasses of Element from
+   * that classes created constructor.
+   *
+   *     class CustomElement extends Element {
+   *       factory CustomElement() => new Element.tag('x-custom');
+   *
+   *       CustomElement.created() : super.created() {
+   *          // Perform any element initialization.
+   *       }
+   *     }
+   *     document.register('x-custom', CustomElement);
+   */
+  Element.created() : super._created() {
+    // Validate that this is a custom element & perform any additional
+    // initialization.
+    _initializeCustomElement(this);
+
+    createdCallback();
+  }
+
+  /**
    * Creates the HTML element specified by the tag name.
    *
    * This is similar to [Document.createElement].
@@ -9715,9 +9822,12 @@
 
   /**
    * Called by the DOM when this element has been instantiated.
+   *
+   * Will be replaced by created constructor.
    */
   @Experimental()
-  void created() {}
+  @deprecated
+  void createdCallback() {}
 
   /**
    * Called by the DOM when this element has been inserted into the live
@@ -9733,6 +9843,11 @@
   @Experimental()
   void leftView() {}
 
+  /**
+   * Called by the DOM whenever an attribute on this has been changed.
+   */
+  void attributeChanged(String name, String oldValue, String newValue) {}
+
   // Hooks to support custom WebComponents.
 
   Element _xtag;
@@ -11056,6 +11171,12 @@
   @DomName('HTMLEmbedElement.HTMLEmbedElement')
   @DocsEditable()
   factory EmbedElement() => document.createElement("embed");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  EmbedElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -11687,6 +11808,9 @@
 @DomName('EventTarget')
 class EventTarget extends NativeFieldWrapperClass1 {
 
+  // Custom element created callback.
+  EventTarget._created();
+
   /**
    * This is an ease-of-use accessor for event streams which should only be
    * used when an explicit accessor is not available.
@@ -11725,6 +11849,12 @@
   @DomName('HTMLFieldSetElement.HTMLFieldSetElement')
   @DocsEditable()
   factory FieldSetElement() => document.createElement("fieldset");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FieldSetElement.created() : super.created();
 
   @DomName('HTMLFieldSetElement.disabled')
   @DocsEditable()
@@ -12477,6 +12607,12 @@
   @DomName('HTMLFormElement.HTMLFormElement')
   @DocsEditable()
   factory FormElement() => document.createElement("form");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FormElement.created() : super.created();
 
   @DomName('HTMLFormElement.acceptCharset')
   @DocsEditable()
@@ -12763,6 +12899,12 @@
   @DomName('HTMLHRElement.HTMLHRElement')
   @DocsEditable()
   factory HRElement() => document.createElement("hr");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HRElement.created() : super.created();
 
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
@@ -12819,6 +12961,12 @@
   @DomName('HTMLHeadElement.HTMLHeadElement')
   @DocsEditable()
   factory HeadElement() => document.createElement("head");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HeadElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -12857,6 +13005,12 @@
   @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable()
   factory HeadingElement.h6() => document.createElement("h6");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HeadingElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -13395,6 +13549,12 @@
 class HtmlElement extends Element {
   // To suppress missing implicit constructor warnings.
   factory HtmlElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HtmlElement.created() : super.created();
 
   @DomName('HTMLElement.contentEditable')
   @DocsEditable()
@@ -13566,6 +13726,12 @@
   @DomName('HTMLHtmlElement.HTMLHtmlElement')
   @DocsEditable()
   factory HtmlHtmlElement() => document.createElement("html");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HtmlHtmlElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -13671,7 +13837,7 @@
   }
 
   /**
-   * Creates a URL request for the specified [url].
+   * Creates and sends a URL request for the specified [url].
    *
    * By default `request` will perform an HTTP GET request, but a different
    * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the 
@@ -14140,6 +14306,12 @@
   @DomName('HTMLIFrameElement.HTMLIFrameElement')
   @DocsEditable()
   factory IFrameElement() => document.createElement("iframe");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  IFrameElement.created() : super.created();
 
   @DomName('HTMLIFrameElement.contentWindow')
   @DocsEditable()
@@ -14273,6 +14445,12 @@
     if (height != null) e.height = height;
     return e;
   }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ImageElement.created() : super.created();
 
   @DomName('HTMLImageElement.alt')
   @DocsEditable()
@@ -14424,6 +14602,12 @@
   @Experimental()
   // http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html#extending_html_elements
   static const EventStreamProvider<Event> speechChangeEvent = const EventStreamProvider<Event>('webkitSpeechChange');
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  InputElement.created() : super.created();
 
   @DomName('HTMLInputElement.accept')
   @DocsEditable()
@@ -15620,6 +15804,12 @@
   @DomName('HTMLKeygenElement.HTMLKeygenElement')
   @DocsEditable()
   factory KeygenElement() => document.createElement("keygen");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  KeygenElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -15714,6 +15904,12 @@
   @DomName('HTMLLIElement.HTMLLIElement')
   @DocsEditable()
   factory LIElement() => document.createElement("li");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LIElement.created() : super.created();
 
   @DomName('HTMLLIElement.type')
   @DocsEditable()
@@ -15752,6 +15948,12 @@
   @DomName('HTMLLabelElement.HTMLLabelElement')
   @DocsEditable()
   factory LabelElement() => document.createElement("label");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LabelElement.created() : super.created();
 
   @DomName('HTMLLabelElement.control')
   @DocsEditable()
@@ -15786,6 +15988,12 @@
   @DomName('HTMLLegendElement.HTMLLegendElement')
   @DocsEditable()
   factory LegendElement() => document.createElement("legend");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LegendElement.created() : super.created();
 
   @DomName('HTMLLegendElement.form')
   @DocsEditable()
@@ -15808,6 +16016,12 @@
   @DomName('HTMLLinkElement.HTMLLinkElement')
   @DocsEditable()
   factory LinkElement() => document.createElement("link");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LinkElement.created() : super.created();
 
   @DomName('HTMLLinkElement.disabled')
   @DocsEditable()
@@ -16015,6 +16229,12 @@
   @DomName('HTMLMapElement.HTMLMapElement')
   @DocsEditable()
   factory MapElement() => document.createElement("map");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MapElement.created() : super.created();
 
   @DomName('HTMLMapElement.areas')
   @DocsEditable()
@@ -16273,6 +16493,12 @@
   @Experimental()
   // https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1/encrypted-media/encrypted-media.html#dom-keyadded
   static const EventStreamProvider<MediaKeyEvent> needKeyEvent = const EventStreamProvider<MediaKeyEvent>('webkitneedkey');
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MediaElement.created() : super.created();
 
   @DomName('HTMLMediaElement.HAVE_CURRENT_DATA')
   @DocsEditable()
@@ -17474,6 +17700,12 @@
   @DomName('HTMLMenuElement.HTMLMenuElement')
   @DocsEditable()
   factory MenuElement() => document.createElement("menu");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MenuElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -17611,6 +17843,12 @@
   @DomName('HTMLMetaElement.HTMLMetaElement')
   @DocsEditable()
   factory MetaElement() => document.createElement("meta");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MetaElement.created() : super.created();
 
   @DomName('HTMLMetaElement.content')
   @DocsEditable()
@@ -17690,6 +17928,12 @@
   @DomName('HTMLMeterElement.HTMLMeterElement')
   @DocsEditable()
   factory MeterElement() => document.createElement("meter");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MeterElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -18087,6 +18331,12 @@
 class ModElement extends HtmlElement {
   // To suppress missing implicit constructor warnings.
   factory ModElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ModElement.created() : super.created();
 
   @DomName('HTMLModElement.cite')
   @DocsEditable()
@@ -19024,6 +19274,10 @@
 
 @DomName('Node')
 class Node extends EventTarget {
+
+  // Custom element created callback.
+  Node._created() : super._created();
+
   List<Node> get nodes {
     return new _ChildNodeListLazy(this);
   }
@@ -19736,6 +19990,12 @@
   @DomName('HTMLOListElement.HTMLOListElement')
   @DocsEditable()
   factory OListElement() => document.createElement("ol");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  OListElement.created() : super.created();
 
   @DomName('HTMLOListElement.reversed')
   @DocsEditable()
@@ -19782,6 +20042,12 @@
   @DomName('HTMLObjectElement.HTMLObjectElement')
   @DocsEditable()
   factory ObjectElement() => document.createElement("object");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ObjectElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -19895,6 +20161,12 @@
   @DomName('HTMLOptGroupElement.HTMLOptGroupElement')
   @DocsEditable()
   factory OptGroupElement() => document.createElement("optgroup");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  OptGroupElement.created() : super.created();
 
   @DomName('HTMLOptGroupElement.disabled')
   @DocsEditable()
@@ -19913,27 +20185,32 @@
   void set label(String value) native "HTMLOptGroupElement_label_Setter";
 
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// WARNING: Do not edit - generated code.
 
-
-@DocsEditable()
 @DomName('HTMLOptionElement')
 class OptionElement extends HtmlElement {
-  // To suppress missing implicit constructor warnings.
-  factory OptionElement._() { throw new UnsupportedError("Not supported"); }
+  factory OptionElement({String data, String value, bool defaultSelected, 
+      bool selected}) {
+    return new OptionElement._(data, value, defaultSelected, selected);
+  }
 
   @DomName('HTMLOptionElement.HTMLOptionElement')
   @DocsEditable()
-  factory OptionElement([String data, String value, bool defaultSelected, bool selected]) {
+  factory OptionElement._([String data, String value, bool defaultSelected, bool selected]) {
     return OptionElement._create_1(data, value, defaultSelected, selected);
   }
 
   @DocsEditable()
   static OptionElement _create_1(data, value, defaultSelected, selected) native "HTMLOptionElement__create_1constructorCallback";
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  OptionElement.created() : super.created();
 
   @DomName('HTMLOptionElement.defaultSelected')
   @DocsEditable()
@@ -20003,6 +20280,12 @@
   @DomName('HTMLOutputElement.HTMLOutputElement')
   @DocsEditable()
   factory OutputElement() => document.createElement("output");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  OutputElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -20144,6 +20427,12 @@
   @DomName('HTMLParagraphElement.HTMLParagraphElement')
   @DocsEditable()
   factory ParagraphElement() => document.createElement("p");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ParagraphElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -20163,6 +20452,12 @@
   @DomName('HTMLParamElement.HTMLParamElement')
   @DocsEditable()
   factory ParamElement() => document.createElement("param");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ParamElement.created() : super.created();
 
   @DomName('HTMLParamElement.name')
   @DocsEditable()
@@ -20881,6 +21176,12 @@
   @DomName('HTMLPreElement.HTMLPreElement')
   @DocsEditable()
   factory PreElement() => document.createElement("pre");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PreElement.created() : super.created();
 
   @DomName('HTMLPreElement.wrap')
   @DocsEditable()
@@ -20937,6 +21238,12 @@
   @DomName('HTMLProgressElement.HTMLProgressElement')
   @DocsEditable()
   factory ProgressElement() => document.createElement("progress");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ProgressElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -21080,6 +21387,12 @@
   @DomName('HTMLQuoteElement.HTMLQuoteElement')
   @DocsEditable()
   factory QuoteElement() => document.createElement("q");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  QuoteElement.created() : super.created();
 
   @DomName('HTMLQuoteElement.cite')
   @DocsEditable()
@@ -22100,6 +22413,12 @@
   @DomName('HTMLScriptElement.HTMLScriptElement')
   @DocsEditable()
   factory ScriptElement() => document.createElement("script");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ScriptElement.created() : super.created();
 
   @DomName('HTMLScriptElement.async')
   @DocsEditable()
@@ -22334,6 +22653,12 @@
   @DomName('HTMLSelectElement.HTMLSelectElement')
   @DocsEditable()
   factory SelectElement() => document.createElement("select");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SelectElement.created() : super.created();
 
   @DomName('HTMLSelectElement.autofocus')
   @DocsEditable()
@@ -22616,6 +22941,12 @@
   @DomName('HTMLShadowElement.HTMLShadowElement')
   @DocsEditable()
   factory ShadowElement() => document.createElement("shadow");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ShadowElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -22921,6 +23252,12 @@
   @DomName('HTMLSourceElement.HTMLSourceElement')
   @DocsEditable()
   factory SourceElement() => document.createElement("source");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SourceElement.created() : super.created();
 
   @DomName('HTMLSourceElement.media')
   @DocsEditable()
@@ -22996,6 +23333,12 @@
   @DomName('HTMLSpanElement.HTMLSpanElement')
   @DocsEditable()
   factory SpanElement() => document.createElement("span");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SpanElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -24059,6 +24402,12 @@
   @DomName('HTMLStyleElement.HTMLStyleElement')
   @DocsEditable()
   factory StyleElement() => document.createElement("style");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  StyleElement.created() : super.created();
 
   @DomName('HTMLStyleElement.disabled')
   @DocsEditable()
@@ -24179,6 +24528,12 @@
   @DomName('HTMLTableCaptionElement.HTMLTableCaptionElement')
   @DocsEditable()
   factory TableCaptionElement() => document.createElement("caption");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableCaptionElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -24197,6 +24552,12 @@
   @DomName('HTMLTableCellElement.HTMLTableCellElement')
   @DocsEditable()
   factory TableCellElement() => document.createElement("td");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableCellElement.created() : super.created();
 
   @DomName('HTMLTableCellElement.cellIndex')
   @DocsEditable()
@@ -24243,6 +24604,12 @@
   @DomName('HTMLTableColElement.HTMLTableColElement')
   @DocsEditable()
   factory TableColElement() => document.createElement("col");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableColElement.created() : super.created();
 
   @DomName('HTMLTableColElement.span')
   @DocsEditable()
@@ -24287,6 +24654,12 @@
   @DomName('HTMLTableElement.HTMLTableElement')
   @DocsEditable()
   factory TableElement() => document.createElement("table");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableElement.created() : super.created();
 
   @DomName('HTMLTableElement.border')
   @DocsEditable()
@@ -24394,6 +24767,12 @@
   @DomName('HTMLTableRowElement.HTMLTableRowElement')
   @DocsEditable()
   factory TableRowElement() => document.createElement("tr");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableRowElement.created() : super.created();
 
   @DomName('HTMLTableRowElement.cells')
   @DocsEditable()
@@ -24437,6 +24816,12 @@
 
   // To suppress missing implicit constructor warnings.
   factory TableSectionElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TableSectionElement.created() : super.created();
 
   @DomName('HTMLTableSectionElement.rows')
   @DocsEditable()
@@ -24551,6 +24936,12 @@
   @DomName('HTMLTemplateElement.HTMLTemplateElement')
   @DocsEditable()
   factory TemplateElement() => document.createElement("template");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TemplateElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -24823,6 +25214,12 @@
   @DomName('HTMLTextAreaElement.HTMLTextAreaElement')
   @DocsEditable()
   factory TextAreaElement() => document.createElement("textarea");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextAreaElement.created() : super.created();
 
   @DomName('HTMLTextAreaElement.autofocus')
   @DocsEditable()
@@ -25530,6 +25927,12 @@
   @DomName('HTMLTitleElement.HTMLTitleElement')
   @DocsEditable()
   factory TitleElement() => document.createElement("title");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TitleElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -25783,6 +26186,12 @@
   @DomName('HTMLTrackElement.HTMLTrackElement')
   @DocsEditable()
   factory TrackElement() => document.createElement("track");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TrackElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -26078,6 +26487,12 @@
   @DomName('HTMLUListElement.HTMLUListElement')
   @DocsEditable()
   factory UListElement() => document.createElement("ul");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  UListElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -26092,6 +26507,12 @@
 class UnknownElement extends HtmlElement {
   // To suppress missing implicit constructor warnings.
   factory UnknownElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  UnknownElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -26114,13 +26535,13 @@
     if ((blob_OR_source_OR_stream is Blob || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_1(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is MediaSource || blob_OR_source_OR_stream == null)) {
+    if ((blob_OR_source_OR_stream is MediaStream || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_2(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is _WebKitMediaSource || blob_OR_source_OR_stream == null)) {
+    if ((blob_OR_source_OR_stream is MediaSource || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_3(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is MediaStream || blob_OR_source_OR_stream == null)) {
+    if ((blob_OR_source_OR_stream is _WebKitMediaSource || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_4(blob_OR_source_OR_stream);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
@@ -26216,6 +26637,12 @@
   @DomName('HTMLVideoElement.HTMLVideoElement')
   @DocsEditable()
   factory VideoElement() => document.createElement("video");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  VideoElement.created() : super.created();
 
   @DomName('HTMLVideoElement.height')
   @DocsEditable()
@@ -29094,6 +29521,12 @@
 abstract class _HTMLAppletElement extends HtmlElement {
   // To suppress missing implicit constructor warnings.
   factory _HTMLAppletElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLAppletElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -29110,6 +29543,12 @@
 abstract class _HTMLBaseFontElement extends HtmlElement {
   // To suppress missing implicit constructor warnings.
   factory _HTMLBaseFontElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLBaseFontElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -29126,6 +29565,12 @@
 abstract class _HTMLDirectoryElement extends HtmlElement {
   // To suppress missing implicit constructor warnings.
   factory _HTMLDirectoryElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLDirectoryElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -29142,6 +29587,12 @@
 abstract class _HTMLFontElement extends HtmlElement {
   // To suppress missing implicit constructor warnings.
   factory _HTMLFontElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLFontElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -29158,6 +29609,12 @@
 abstract class _HTMLFrameElement extends HtmlElement {
   // To suppress missing implicit constructor warnings.
   factory _HTMLFrameElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLFrameElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -29174,6 +29631,12 @@
 abstract class _HTMLFrameSetElement extends HtmlElement {
   // To suppress missing implicit constructor warnings.
   factory _HTMLFrameSetElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLFrameSetElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -29190,6 +29653,12 @@
 abstract class _HTMLMarqueeElement extends HtmlElement {
   // To suppress missing implicit constructor warnings.
   factory _HTMLMarqueeElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _HTMLMarqueeElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -34446,33 +34915,6 @@
     }
   }
 }
-// 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.
-
-
-// testRunner implementation.
-// FIXME: provide a separate lib for testRunner.
-
-var _testRunner;
-
-TestRunner get testRunner {
-  if (_testRunner == null)
-    _testRunner = new TestRunner._(_NPObject.retrieve("testRunner"));
-  return _testRunner;
-}
-
-class TestRunner {
-  final _NPObject _npObject;
-
-  TestRunner._(this._npObject);
-
-  display() => _npObject.invoke('display');
-  dumpAsText() => _npObject.invoke('dumpAsText');
-  notifyDone() => _npObject.invoke('notifyDone');
-  setCanOpenWindows() => _npObject.invoke('setCanOpenWindows');
-  waitUntilDone() => _npObject.invoke('waitUntilDone');
-}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -34763,6 +35205,10 @@
     if (_isBuiltinType(cls)) {
       throw new UnsupportedError("Invalid custom element from $libName.");
     }
+    var className = MirrorSystem.getName(cls.simpleName);
+    if (!cls.constructors.containsKey(new Symbol('$className.created'))) {
+      throw new UnsupportedError('Class is missing constructor $className.created');
+    }
     _register(document, tag, type, extendsTagName);
   }
 
@@ -34770,13 +35216,8 @@
       String extendsTagName) native "Utils_register";
 
   static Element createElement(Document document, String tagName) native "Utils_createElement";
-}
 
-class _NPObject extends NativeFieldWrapperClass1 {
-  _NPObject.internal();
-  static _NPObject retrieve(String key) native "NPObject_retrieve";
-  property(String propertyName) native "NPObject_property";
-  invoke(String methodName, [List args = null]) native "NPObject_invoke";
+  static void initializeCustomElement(HtmlElement element) native "Utils_initializeCustomElement";
 }
 
 class _DOMWindowCrossFrame extends NativeFieldWrapperClass1 implements
@@ -34991,3 +35432,7 @@
 get _pureIsolateTimerFactoryClosure =>
     ((int milliSeconds, void callback(Timer time), bool repeating) =>
         new _PureIsolateTimer(milliSeconds, callback, repeating));
+
+void _initializeCustomElement(Element e) {
+  _Utils.initializeCustomElement(e);
+}
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 671064c..6aa18f8 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -68,25 +68,59 @@
   void createSync({bool recursive: false});
 
   /**
-   * Creates a temporary directory with a name based on the current
-   * path.  The path is used as a template, and additional
-   * characters are appended to it to make a unique temporary
-   * directory name.  If the path is the empty string, a default
-   * system temp directory and name are used for the template.
+   * Creates a temporary directory in this directory.  Additional random
+   * characters are appended to [template] to produce a unique directory
+   * name.
+   *
+   * Returns a [:Future<Directory>:] that completes with the newly
+   * created temporary directory.
+   *
+   * Deprecated behavior, to be removed Oct 18, 2013: If the path is the
+   * empty string, the directory is created in the default system temp
+   * directory.  This capability has been moved to the static function
+   * [createSystemTemp].
+   */
+  Future<Directory> createTemp([String template]);
+
+  /**
+   * Synchronously creates a temporary directory in this directory.
+   * Additional random characters are appended to [template] to produce
+   * a unique directory name.
+   *
+   * Returns the newly created temporary directory.
+   *
+   * Deprecated behavior, to be removed Oct 18, 2013: If the path is the
+   * empty string, the directory is created in the default system temp
+   * directory.  This capability has been moved to the static function
+   * [createSystemTemp].
+   */
+ Directory createTempSync([String template]);
+
+  /**
+   * Creates a temporary directory in the system temp directory.
+   * The location of the system temp directory is platform-dependent,
+   * and may be set by an environment variable.
+   * Additional random characters are appended to [template] to produce
+   * a unique directory name.
    *
    * Returns a [:Future<Directory>:] that completes with the newly
    * created temporary directory.
    */
-  Future<Directory> createTemp();
+  static Future<Directory> createSystemTemp([String template]) =>
+      _Directory.createSystemTemp(template);
 
   /**
-   * Synchronously creates a temporary directory with a name based on the
-   * current path. The path is used as a template, and additional
-   * characters are appended to it to make a unique temporary directory name.
-   * If the path is the empty string, a default system temp directory and name
-   * are used for the template. Returns the newly created temporary directory.
+   * Synchronously creates a temporary directory in the system temp directory.
+   * The location of the system temp directory is platform-dependent,
+   * and may be set by an environment variable.
+   * Additional random characters are appended to [template] to produce
+   * a unique directory name.
+   *
+   * Returns a [:Future<Directory>:] that completes with the newly
+   * created temporary directory.
    */
-  Directory createTempSync();
+  static Directory createSystemTempSync([String template]) =>
+      _Directory.createSystemTempSync(template);
 
   Future<String> resolveSymbolicLinks();
 
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index d1258fb..ac048de 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -5,15 +5,6 @@
 part of dart.io;
 
 class _Directory extends FileSystemEntity implements Directory {
-  static const CREATE_REQUEST = 0;
-  static const DELETE_REQUEST = 1;
-  static const EXISTS_REQUEST = 2;
-  static const CREATE_TEMP_REQUEST = 3;
-  static const LIST_START_REQUEST = 4;
-  static const LIST_NEXT_REQUEST = 5;
-  static const LIST_STOP_REQUEST = 6;
-  static const RENAME_REQUEST = 7;
-
   final String path;
 
   _Directory(String this.path) {
@@ -25,7 +16,7 @@
 
   external static _current();
   external static _setCurrent(path);
-  external static _createTemp(String template);
+  external static _createTemp(String template, bool system);
   external static int _exists(String path);
   external static _create(String path);
   external static _deleteNative(String path, bool recursive);
@@ -158,8 +149,18 @@
     }
   }
 
-  Future<Directory> createTemp() {
-    return _IOService.dispatch(_DIRECTORY_CREATE_TEMP, [path]).then((response) {
+  // TODO(13720): Make template argument mandatory on Oct 18, 2013.
+  Future<Directory> createTemp([String template]) {
+    if (path == '') {
+      if (template == null) template = '';
+      return createSystemTemp(template);
+      // TODO(13720): On Oct 18, 2013, replace this with
+      // an error.  createTemp cannot be called on a Directory with empty path.
+    }
+    String fullTemplate = "$path${Platform.pathSeparator}";
+    if (template != null) fullTemplate = "$fullTemplate$template";
+    return _IOService.dispatch(_DIRECTORY_CREATE_TEMP, [fullTemplate])
+        .then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionOrErrorFromResponse(
             response, "Creation of temporary directory failed");
@@ -168,11 +169,41 @@
     });
   }
 
-  Directory createTempSync() {
-    var result = _createTemp(path);
+  // TODO(13720): Make template argument mandatory on Oct 18, 2013.
+  Directory createTempSync([String template]) {
+    if (path == '') {
+      if (template == null) template = '';
+      return createSystemTempSync(template);
+      // TODO(13720): On Oct 18, 2013, replace this with
+      // an error.  createTemp cannot be called on a Directory with empty path.
+    }
+    String fullTemplate = "$path${Platform.pathSeparator}";
+    if (template != null) fullTemplate = "$fullTemplate$template";
+    var result = _createTemp(fullTemplate, false);
     if (result is OSError) {
       throw new DirectoryException("Creation of temporary directory failed",
-                                   path,
+                                   fullTemplate,
+                                   result);
+    }
+    return new Directory(result);
+  }
+
+  static Future<Directory> createSystemTemp(String template) {
+    return _IOService.dispatch(_DIRECTORY_CREATE_SYSTEM_TEMP,
+                               [template]).then((response) {
+      if (response is List && response[0] != _SUCCESS_RESPONSE) {
+        throw new _Directory(template)._exceptionOrErrorFromResponse(
+            response, "Creation of temporary directory failed");
+      }
+      return new Directory(response);
+    });
+  }
+
+  static Directory createSystemTempSync(String template) {
+    var result = _createTemp(template, true);
+    if (result is OSError) {
+      throw new DirectoryException("Creation of temporary directory failed",
+                                   template,
                                    result);
     }
     return new Directory(result);
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 1dce796..4df878a 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -531,17 +531,13 @@
 class _RandomAccessFile implements RandomAccessFile {
   final String path;
   int _id;
+  bool _asyncDispatched = false;
   SendPort _fileService;
 
   _RandomAccessFile(int this._id, String this.path);
 
   Future<RandomAccessFile> close() {
-    if (closed) return _closedException();
-    // Set the id_ to 0 (NULL) to ensure the no more async requests
-    // can be issued for this file.
-    int id = _id;
-    _id = 0;
-    return _IOService.dispatch(_FILE_CLOSE, [id]).then((result) {
+    return _dispatch(_FILE_CLOSE, [_id], markClosed: true).then((result) {
       if (result != -1) {
         _id = result;
         return this;
@@ -554,7 +550,7 @@
   external static int _close(int id);
 
   void closeSync() {
-    _checkNotClosed();
+    _checkAvailable();
     var id = _close(_id);
     if (id == -1) {
       throw new FileException("Cannot close file", path);
@@ -563,8 +559,7 @@
   }
 
   Future<int> readByte() {
-    if (closed) return _closedException();
-    return _IOService.dispatch(_FILE_READ_BYTE, [_id]).then((response) {
+    return _dispatch(_FILE_READ_BYTE, [_id]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "readByte failed", path);
       }
@@ -575,7 +570,7 @@
   external static _readByte(int id);
 
   int readByteSync() {
-    _checkNotClosed();
+    _checkAvailable();
     var result = _readByte(_id);
     if (result is OSError) {
       throw new FileException("readByte failed", path, result);
@@ -587,8 +582,7 @@
     if (bytes is !int) {
       throw new ArgumentError(bytes);
     }
-    if (closed) return _closedException();
-    return _IOService.dispatch(_FILE_READ, [_id, bytes]).then((response) {
+    return _dispatch(_FILE_READ, [_id, bytes]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "read failed", path);
       }
@@ -599,7 +593,7 @@
   external static _read(int id, int bytes);
 
   List<int> readSync(int bytes) {
-    _checkNotClosed();
+    _checkAvailable();
     if (bytes is !int) {
       throw new ArgumentError(bytes);
     }
@@ -616,11 +610,10 @@
         (end != null && end is !int)) {
       throw new ArgumentError();
     }
-    if (closed) return _closedException();
     if (start == null) start = 0;
     if (end == null) end = buffer.length;
     int length = end - start;
-    return _IOService.dispatch(_FILE_READ_INTO, [_id, length]).then((response) {
+    return _dispatch(_FILE_READ_INTO, [_id, length]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "readInto failed", path);
       }
@@ -642,7 +635,7 @@
   external static _readInto(int id, List<int> buffer, int start, int end);
 
   int readIntoSync(List<int> buffer, [int start, int end]) {
-    _checkNotClosed();
+    _checkAvailable();
     if (buffer is !List ||
         (start != null && start is !int) ||
         (end != null && end is !int)) {
@@ -663,8 +656,7 @@
     if (value is !int) {
       throw new ArgumentError(value);
     }
-    if (closed) return _closedException();
-    return _IOService.dispatch(_FILE_WRITE_BYTE, [_id, value]).then((response) {
+    return _dispatch(_FILE_WRITE_BYTE, [_id, value]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "writeByte failed", path);
       }
@@ -675,7 +667,7 @@
   external static _writeByte(int id, int value);
 
   int writeByteSync(int value) {
-    _checkNotClosed();
+    _checkAvailable();
     if (value is !int) {
       throw new ArgumentError(value);
     }
@@ -693,8 +685,6 @@
       throw new ArgumentError("Invalid arguments to writeFrom");
     }
 
-    if (closed) return _closedException();
-
     _BufferAndStart result;
     try {
       result = _ensureFastAndSerializableByteData(buffer, start, end);
@@ -707,7 +697,7 @@
     request[1] = result.buffer;
     request[2] = result.start;
     request[3] = end - (start - result.start);
-    return _IOService.dispatch(_FILE_WRITE_FROM, request).then((response) {
+    return _dispatch(_FILE_WRITE_FROM, request).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "writeFrom failed", path);
       }
@@ -718,7 +708,7 @@
   external static _writeFrom(int id, List<int> buffer, int start, int end);
 
   void writeFromSync(List<int> buffer, [int start, int end]) {
-    _checkNotClosed();
+    _checkAvailable();
     if (buffer is !List ||
         (start != null && start is !int) ||
         (end != null && end is !int)) {
@@ -757,8 +747,7 @@
   }
 
   Future<int> position() {
-    if (closed) return _closedException();
-    return _IOService.dispatch(_FILE_POSITION, [_id]).then((response) {
+    return _dispatch(_FILE_POSITION, [_id]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "position failed", path);
       }
@@ -769,7 +758,7 @@
   external static _position(int id);
 
   int positionSync() {
-    _checkNotClosed();
+    _checkAvailable();
     var result = _position(_id);
     if (result is OSError) {
       throw new FileException("position failed", path, result);
@@ -778,8 +767,7 @@
   }
 
   Future<RandomAccessFile> setPosition(int position) {
-    if (closed) return _closedException();
-    return _IOService.dispatch(_FILE_SET_POSITION, [_id, position])
+    return _dispatch(_FILE_SET_POSITION, [_id, position])
         .then((response) {
           if (_isErrorResponse(response)) {
             throw _exceptionFromResponse(response, "setPosition failed", path);
@@ -791,7 +779,7 @@
   external static _setPosition(int id, int position);
 
   void setPositionSync(int position) {
-    _checkNotClosed();
+    _checkAvailable();
     var result = _setPosition(_id, position);
     if (result is OSError) {
       throw new FileException("setPosition failed", path, result);
@@ -799,8 +787,7 @@
   }
 
   Future<RandomAccessFile> truncate(int length) {
-    if (closed) return _closedException();
-    return _IOService.dispatch(_FILE_TRUNCATE, [_id, length]).then((response) {
+    return _dispatch(_FILE_TRUNCATE, [_id, length]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "truncate failed", path);
       }
@@ -811,7 +798,7 @@
   external static _truncate(int id, int length);
 
   void truncateSync(int length) {
-    _checkNotClosed();
+    _checkAvailable();
     var result = _truncate(_id, length);
     if (result is OSError) {
       throw new FileException("truncate failed", path, result);
@@ -819,8 +806,7 @@
   }
 
   Future<int> length() {
-    if (closed) return _closedException();
-    return _IOService.dispatch(_FILE_LENGTH, [_id]).then((response) {
+    return _dispatch(_FILE_LENGTH, [_id]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "length failed", path);
       }
@@ -831,7 +817,7 @@
   external static _length(int id);
 
   int lengthSync() {
-    _checkNotClosed();
+    _checkAvailable();
     var result = _length(_id);
     if (result is OSError) {
       throw new FileException("length failed", path, result);
@@ -840,8 +826,7 @@
   }
 
   Future<RandomAccessFile> flush() {
-    if (closed) return _closedException();
-    return _IOService.dispatch(_FILE_FLUSH, [_id]).then((response) {
+    return _dispatch(_FILE_FLUSH, [_id]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response,
                                      "flush failed",
@@ -854,7 +839,7 @@
   external static _flush(int id);
 
   void flushSync() {
-    _checkNotClosed();
+    _checkAvailable();
     var result = _flush(_id);
     if (result is OSError) {
       throw new FileException("flush failed", path, result);
@@ -863,13 +848,32 @@
 
   bool get closed => _id == 0;
 
-  void _checkNotClosed() {
+  Future _dispatch(int request, List data, { bool markClosed: false }) {
+    if (closed) {
+      return new Future.error(new FileException("File closed", path));
+    }
+    if (_asyncDispatched) {
+      var msg = "An async operation is currently pending";
+      return new Future.error(new FileException(msg, path));
+    }
+    if (markClosed) {
+      // Set the id_ to 0 (NULL) to ensure the no more async requests
+      // can be issued for this file.
+      _id = 0;
+    }
+    _asyncDispatched = true;
+    return _IOService.dispatch(request, data)
+        .whenComplete(() {
+          _asyncDispatched = false;
+        });
+  }
+
+  void _checkAvailable() {
+    if (_asyncDispatched) {
+      throw new FileException("An async operation is currently pending", path);
+    }
     if (closed) {
       throw new FileException("File closed", path);
     }
   }
-
-  Future _closedException() {
-    return new Future.error(new FileException("File closed", path));
-  }
 }
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 31f6b97..ee63d1a 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -186,6 +186,13 @@
   int get port;
 
   /**
+   * Returns the address that the server is listening on. This can be
+   * used to get the actual address used, when the address is fetched by
+   * a lookup from a hostname.
+   */
+  InternetAddress get address;
+
+  /**
    * Sets the timeout, in seconds, for sessions of this [HttpServer].
    * The default timeout is 20 minutes.
    */
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index 99c2806..fcaf191 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -2012,6 +2012,11 @@
     return _serverSocket.port;
   }
 
+  InternetAddress get address {
+    if (closed) throw new HttpException("HttpServer is not bound to a socket");
+    return _serverSocket.address;
+  }
+
   set sessionTimeout(int timeout) {
     _sessionManager.sessionTimeout = timeout;
   }
diff --git a/sdk/lib/io/io_service.dart b/sdk/lib/io/io_service.dart
index 760d022..037cdd1 100644
--- a/sdk/lib/io/io_service.dart
+++ b/sdk/lib/io/io_service.dart
@@ -4,6 +4,7 @@
 
 part of dart.io;
 
+// This list must be kept in sync with the list in runtime/bin/io_service.h
 const int _FILE_EXISTS = 0;
 const int _FILE_CREATE = 1;
 const int _FILE_DELETE = 2;
@@ -37,11 +38,12 @@
 const int _DIRECTORY_DELETE = 30;
 const int _DIRECTORY_EXISTS = 31;
 const int _DIRECTORY_CREATE_TEMP = 32;
-const int _DIRECTORY_LIST_START = 33;
-const int _DIRECTORY_LIST_NEXT = 34;
-const int _DIRECTORY_LIST_STOP = 35;
-const int _DIRECTORY_RENAME = 36;
-const int _SSL_PROCESS_FILTER = 37;
+const int _DIRECTORY_CREATE_SYSTEM_TEMP = 33;
+const int _DIRECTORY_LIST_START = 34;
+const int _DIRECTORY_LIST_NEXT = 35;
+const int _DIRECTORY_LIST_STOP = 36;
+const int _DIRECTORY_RENAME = 37;
+const int _SSL_PROCESS_FILTER = 38;
 
 class _IOService {
   external static Future dispatch(int request, List data);
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index c5b4b8d..ce8ace5 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -202,6 +202,11 @@
   int get port;
 
   /**
+   * Returns the address used by this socket.
+   */
+  InternetAddress get address;
+
+  /**
    * Closes the socket. The returned future completes when the socket
    * is fully closed and is no longer bound.
    */
@@ -258,6 +263,11 @@
   int get port;
 
   /**
+   * Returns the address used by this socket.
+   */
+  InternetAddress get address;
+
+  /**
    * Closes the socket. The returned future completes when the socket
    * is fully closed and is no longer bound.
    */
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index 3725526..766eee0 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.dart
@@ -29,17 +29,6 @@
 }
 
 
-class _StdinEventSink implements EventSink<String> {
-  Function _add;
-  Function _addError;
-  Function _close;
-  _StdinEventSink(this._add, this._addError, this._close);
-
-  void add(String string) => _add(string);
-  void addError(errorEvent) => _addError(errorEvent);
-  void close() => _close();
-}
-
 /**
  * [Stdin] allows both synchronous and asynchronous reads from the standard
  * input stream.
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index b13709c..e2bc326 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -572,9 +572,7 @@
   StreamController _controller;
   StreamSubscription _subscription;
   bool _issuedPause = false;
-  // Only report error if the last message was a user-provided message and not a
-  // ping or pong message.
-  bool _reportError = false;
+  bool _closed = false;
   Completer _closeCompleter = new Completer();
   Completer _completer;
 
@@ -602,6 +600,14 @@
     }
   }
 
+  void _cancel() {
+    if (_subscription != null) {
+      var subscription = _subscription;
+      _subscription = null;
+      subscription.cancel();
+    }
+  }
+
   _ensureController() {
     if (_controller != null) return;
     _controller = new StreamController(sync: true,
@@ -612,19 +618,20 @@
         new _WebSocketOutgoingTransformer(webSocket));
     socket.addStream(stream)
         .then((_) {
-                _done();
-                _closeCompleter.complete(webSocket);
-              },
-              onError: (error) {
-                if (_reportError) {
-                  if (!_done(error)) {
-                    _closeCompleter.completeError(error);
-                  }
-                } else {
-                  _done();
-                  _closeCompleter.complete(webSocket);
-                }
-              });
+          _done();
+          _closeCompleter.complete(webSocket);
+        }, onError: (error) {
+          _closed = true;
+          _cancel();
+          if (error is ArgumentError) {
+            if (!_done(error)) {
+              _closeCompleter.completeError(error);
+            }
+          } else {
+            _done();
+            _closeCompleter.complete(webSocket);
+          }
+        });
   }
 
   bool _done([error]) {
@@ -639,11 +646,14 @@
   }
 
   Future addStream(var stream) {
+    if (_closed) {
+      stream.listen(null).cancel();
+      return new Future.value(webSocket);
+    }
     _ensureController();
     _completer = new Completer();
     _subscription = stream.listen(
         (data) {
-          _reportError = true;
           _controller.add(data);
         },
         onDone: () {
@@ -663,17 +673,23 @@
   Future close() {
     _ensureController();
     Future closeSocket() {
-      return socket.close().then((_) => webSocket);
+      return socket.close().catchError((_) {}).then((_) => webSocket);
     }
     _controller.close();
     return _closeCompleter.future.then((_) => closeSocket());
   }
 
   void add(data) {
+    if (_closed) return;
     _ensureController();
-    _reportError = false;
     _controller.add(data);
   }
+
+  void closeSocket() {
+    _closed = true;
+    _cancel();
+    close();
+  }
 }
 
 
@@ -786,21 +802,20 @@
           }
         },
         onError: (error) {
-          if (error is ArgumentError) {
-            close(WebSocketStatus.INVALID_FRAME_PAYLOAD_DATA);
+          if (error is FormatException) {
+            _close(WebSocketStatus.INVALID_FRAME_PAYLOAD_DATA);
           } else {
-            close(WebSocketStatus.PROTOCOL_ERROR);
+            _close(WebSocketStatus.PROTOCOL_ERROR);
           }
-          _controller.addError(error);
           _controller.close();
         },
         onDone: () {
           if (_readyState == WebSocket.OPEN) {
             _readyState = WebSocket.CLOSING;
             if (!_isReservedStatusCode(transformer.closeCode)) {
-              close(transformer.closeCode);
+              _close(transformer.closeCode);
             } else {
-              close();
+              _close();
             }
             _readyState = WebSocket.CLOSED;
           }
@@ -840,7 +855,7 @@
       _consumer.add(new _WebSocketPing());
       _pingTimer = new Timer(_pingInterval, () {
         // No pong received.
-        close(WebSocketStatus.GOING_AWAY);
+        _close(WebSocketStatus.GOING_AWAY);
       });
     });
   }
@@ -858,16 +873,24 @@
   Future get done => _sink.done;
 
   Future close([int code, String reason]) {
-    if (!_writeClosed) {
-      if (_isReservedStatusCode(code)) {
-        throw new WebSocketException("Reserved status code $code");
-      }
+    if (_isReservedStatusCode(code)) {
+      throw new WebSocketException("Reserved status code $code");
+    }
+    if (_outCloseCode == null) {
       _outCloseCode = code;
       _outCloseReason = reason;
-      _writeClosed = true;
     }
-    if (!(_sink as _StreamSinkImpl)._isBound) _sink.close();
-    return _sink.done;
+    return _sink.close();
+  }
+
+  void _close([int code, String reason]) {
+    if (_writeClosed) return;
+    if (_outCloseCode == null) {
+      _outCloseCode = code;
+      _outCloseReason = reason;
+    }
+    _writeClosed = true;
+    _consumer.closeSocket();
   }
 
   static bool _isReservedStatusCode(int code) {
diff --git a/sdk/lib/js/dart2js/js_dart2js.dart b/sdk/lib/js/dart2js/js_dart2js.dart
index 7f806b7..64b4af0 100644
--- a/sdk/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/js/dart2js/js_dart2js.dart
@@ -5,11 +5,9 @@
 library dart.js;
 
 import 'dart:_foreign_helper' show JS;
-import 'dart:_js_helper' show convertDartClosureToJS;
+import 'dart:_js_helper' show Primitives, convertDartClosureToJS;
 
-JsObject get context {
-  return new JsObject._fromJs(JS('=Object', 'window'));
-}
+final JsObject context = new JsObject._fromJs(Primitives.computeGlobalThis());
 
 JsObject jsify(dynamic data) => data == null ? null : new JsObject._json(data);
 
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index 2ec2c0e..a0c48ea 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -76,15 +76,21 @@
 SendPortSync _jsPortDeleteProperty = window.lookupPort('dart-js-delete-property');
 SendPortSync _jsPortConvert = window.lookupPort('dart-js-convert');
 
+
+JsObject _context;
+
 /**
  * Returns a proxy to the global JavaScript context for this page.
  */
 JsObject get context {
-  var port = _jsPortSync;
-  if (port == null) {
-    return null;
+  if (_context == null) {
+    var port = _jsPortSync;
+    if (port == null) {
+      return null;
+    }
+    _context = _deserialize(_jsPortSync.callSync([]));
   }
-  return _deserialize(_jsPortSync.callSync([]));
+  return _context;
 }
 
 /**
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index be59cd9..0f88099 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -51,6 +51,12 @@
   @DomName('SVGAElement.SVGAElement')
   @DocsEditable()
   factory AElement() => _SvgElementFactoryProvider.createSvgElement_tag("a");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AElement.created() : super.created();
 
   @DomName('SVGAElement.target')
   @DocsEditable()
@@ -86,6 +92,12 @@
   @DomName('SVGAltGlyphElement.SVGAltGlyphElement')
   @DocsEditable()
   factory AltGlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("altGlyph");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AltGlyphElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('altGlyph') && (new SvgElement.tag('altGlyph') is AltGlyphElement);
@@ -176,6 +188,12 @@
   @DomName('SVGAnimateElement.SVGAnimateElement')
   @DocsEditable()
   factory AnimateElement() => _SvgElementFactoryProvider.createSvgElement_tag("animate");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnimateElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('animate') && (new SvgElement.tag('animate') is AnimateElement);
@@ -198,6 +216,12 @@
   @DomName('SVGAnimateMotionElement.SVGAnimateMotionElement')
   @DocsEditable()
   factory AnimateMotionElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateMotion");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnimateMotionElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('animateMotion') && (new SvgElement.tag('animateMotion') is AnimateMotionElement);
@@ -220,6 +244,12 @@
   @DomName('SVGAnimateTransformElement.SVGAnimateTransformElement')
   @DocsEditable()
   factory AnimateTransformElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateTransform");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnimateTransformElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('animateTransform') && (new SvgElement.tag('animateTransform') is AnimateTransformElement);
@@ -455,6 +485,12 @@
   @DomName('SVGAnimationElement.SVGAnimationElement')
   @DocsEditable()
   factory AnimationElement() => _SvgElementFactoryProvider.createSvgElement_tag("animation");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnimationElement.created() : super.created();
 
   @DomName('SVGAnimationElement.targetElement')
   @DocsEditable()
@@ -527,6 +563,12 @@
   @DomName('SVGCircleElement.SVGCircleElement')
   @DocsEditable()
   factory CircleElement() => _SvgElementFactoryProvider.createSvgElement_tag("circle");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  CircleElement.created() : super.created();
 
   @DomName('SVGCircleElement.cx')
   @DocsEditable()
@@ -561,6 +603,12 @@
   @DomName('SVGClipPathElement.SVGClipPathElement')
   @DocsEditable()
   factory ClipPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("clipPath");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ClipPathElement.created() : super.created();
 
   @DomName('SVGClipPathElement.clipPathUnits')
   @DocsEditable()
@@ -587,6 +635,12 @@
   @DomName('SVGDefsElement.SVGDefsElement')
   @DocsEditable()
   factory DefsElement() => _SvgElementFactoryProvider.createSvgElement_tag("defs");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DefsElement.created() : super.created();
 
   // From SVGExternalResourcesRequired
 
@@ -609,6 +663,12 @@
   @DomName('SVGDescElement.SVGDescElement')
   @DocsEditable()
   factory DescElement() => _SvgElementFactoryProvider.createSvgElement_tag("desc");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DescElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -1015,6 +1075,12 @@
   @DomName('SVGEllipseElement.SVGEllipseElement')
   @DocsEditable()
   factory EllipseElement() => _SvgElementFactoryProvider.createSvgElement_tag("ellipse");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  EllipseElement.created() : super.created();
 
   @DomName('SVGEllipseElement.cx')
   @DocsEditable()
@@ -1072,6 +1138,12 @@
   @DomName('SVGFEBlendElement.SVGFEBlendElement')
   @DocsEditable()
   factory FEBlendElement() => _SvgElementFactoryProvider.createSvgElement_tag("feBlend");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEBlendElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feBlend') && (new SvgElement.tag('feBlend') is FEBlendElement);
@@ -1153,6 +1225,12 @@
   @DomName('SVGFEColorMatrixElement.SVGFEColorMatrixElement')
   @DocsEditable()
   factory FEColorMatrixElement() => _SvgElementFactoryProvider.createSvgElement_tag("feColorMatrix");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEColorMatrixElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feColorMatrix') && (new SvgElement.tag('feColorMatrix') is FEColorMatrixElement);
@@ -1230,6 +1308,12 @@
   @DomName('SVGFEComponentTransferElement.SVGFEComponentTransferElement')
   @DocsEditable()
   factory FEComponentTransferElement() => _SvgElementFactoryProvider.createSvgElement_tag("feComponentTransfer");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEComponentTransferElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feComponentTransfer') && (new SvgElement.tag('feComponentTransfer') is FEComponentTransferElement);
@@ -1271,6 +1355,12 @@
 class FECompositeElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFECompositeElement" {
   // To suppress missing implicit constructor warnings.
   factory FECompositeElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FECompositeElement.created() : super.created();
 
   @DomName('SVGFECompositeElement.SVG_FECOMPOSITE_OPERATOR_ARITHMETIC')
   @DocsEditable()
@@ -1369,6 +1459,12 @@
   @DomName('SVGFEConvolveMatrixElement.SVGFEConvolveMatrixElement')
   @DocsEditable()
   factory FEConvolveMatrixElement() => _SvgElementFactoryProvider.createSvgElement_tag("feConvolveMatrix");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEConvolveMatrixElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feConvolveMatrix') && (new SvgElement.tag('feConvolveMatrix') is FEConvolveMatrixElement);
@@ -1478,6 +1574,12 @@
   @DomName('SVGFEDiffuseLightingElement.SVGFEDiffuseLightingElement')
   @DocsEditable()
   factory FEDiffuseLightingElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDiffuseLighting");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEDiffuseLightingElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feDiffuseLighting') && (new SvgElement.tag('feDiffuseLighting') is FEDiffuseLightingElement);
@@ -1543,6 +1645,12 @@
   @DomName('SVGFEDisplacementMapElement.SVGFEDisplacementMapElement')
   @DocsEditable()
   factory FEDisplacementMapElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDisplacementMap");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEDisplacementMapElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feDisplacementMap') && (new SvgElement.tag('feDisplacementMap') is FEDisplacementMapElement);
@@ -1628,6 +1736,12 @@
   @DomName('SVGFEDistantLightElement.SVGFEDistantLightElement')
   @DocsEditable()
   factory FEDistantLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDistantLight");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEDistantLightElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feDistantLight') && (new SvgElement.tag('feDistantLight') is FEDistantLightElement);
@@ -1659,6 +1773,12 @@
   @DomName('SVGFEFloodElement.SVGFEFloodElement')
   @DocsEditable()
   factory FEFloodElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFlood");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFloodElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feFlood') && (new SvgElement.tag('feFlood') is FEFloodElement);
@@ -1704,6 +1824,12 @@
   @DomName('SVGFEFuncAElement.SVGFEFuncAElement')
   @DocsEditable()
   factory FEFuncAElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncA");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFuncAElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feFuncA') && (new SvgElement.tag('feFuncA') is FEFuncAElement);
@@ -1727,6 +1853,12 @@
   @DomName('SVGFEFuncBElement.SVGFEFuncBElement')
   @DocsEditable()
   factory FEFuncBElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncB");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFuncBElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feFuncB') && (new SvgElement.tag('feFuncB') is FEFuncBElement);
@@ -1750,6 +1882,12 @@
   @DomName('SVGFEFuncGElement.SVGFEFuncGElement')
   @DocsEditable()
   factory FEFuncGElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncG");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFuncGElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feFuncG') && (new SvgElement.tag('feFuncG') is FEFuncGElement);
@@ -1773,6 +1911,12 @@
   @DomName('SVGFEFuncRElement.SVGFEFuncRElement')
   @DocsEditable()
   factory FEFuncRElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncR");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFuncRElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feFuncR') && (new SvgElement.tag('feFuncR') is FEFuncRElement);
@@ -1796,6 +1940,12 @@
   @DomName('SVGFEGaussianBlurElement.SVGFEGaussianBlurElement')
   @DocsEditable()
   factory FEGaussianBlurElement() => _SvgElementFactoryProvider.createSvgElement_tag("feGaussianBlur");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEGaussianBlurElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feGaussianBlur') && (new SvgElement.tag('feGaussianBlur') is FEGaussianBlurElement);
@@ -1857,6 +2007,12 @@
   @DomName('SVGFEImageElement.SVGFEImageElement')
   @DocsEditable()
   factory FEImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("feImage");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEImageElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feImage') && (new SvgElement.tag('feImage') is FEImageElement);
@@ -1918,6 +2074,12 @@
   @DomName('SVGFEMergeElement.SVGFEMergeElement')
   @DocsEditable()
   factory FEMergeElement() => _SvgElementFactoryProvider.createSvgElement_tag("feMerge");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEMergeElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feMerge') && (new SvgElement.tag('feMerge') is FEMergeElement);
@@ -1963,6 +2125,12 @@
   @DomName('SVGFEMergeNodeElement.SVGFEMergeNodeElement')
   @DocsEditable()
   factory FEMergeNodeElement() => _SvgElementFactoryProvider.createSvgElement_tag("feMergeNode");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEMergeNodeElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feMergeNode') && (new SvgElement.tag('feMergeNode') is FEMergeNodeElement);
@@ -1986,6 +2154,12 @@
 class FEMorphologyElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEMorphologyElement" {
   // To suppress missing implicit constructor warnings.
   factory FEMorphologyElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEMorphologyElement.created() : super.created();
 
   @DomName('SVGFEMorphologyElement.SVG_MORPHOLOGY_OPERATOR_DILATE')
   @DocsEditable()
@@ -2060,6 +2234,12 @@
   @DomName('SVGFEOffsetElement.SVGFEOffsetElement')
   @DocsEditable()
   factory FEOffsetElement() => _SvgElementFactoryProvider.createSvgElement_tag("feOffset");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEOffsetElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feOffset') && (new SvgElement.tag('feOffset') is FEOffsetElement);
@@ -2117,6 +2297,12 @@
   @DomName('SVGFEPointLightElement.SVGFEPointLightElement')
   @DocsEditable()
   factory FEPointLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("fePointLight");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEPointLightElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('fePointLight') && (new SvgElement.tag('fePointLight') is FEPointLightElement);
@@ -2152,6 +2338,12 @@
   @DomName('SVGFESpecularLightingElement.SVGFESpecularLightingElement')
   @DocsEditable()
   factory FESpecularLightingElement() => _SvgElementFactoryProvider.createSvgElement_tag("feSpecularLighting");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FESpecularLightingElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feSpecularLighting') && (new SvgElement.tag('feSpecularLighting') is FESpecularLightingElement);
@@ -2213,6 +2405,12 @@
   @DomName('SVGFESpotLightElement.SVGFESpotLightElement')
   @DocsEditable()
   factory FESpotLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("feSpotLight");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FESpotLightElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feSpotLight') && (new SvgElement.tag('feSpotLight') is FESpotLightElement);
@@ -2268,6 +2466,12 @@
   @DomName('SVGFETileElement.SVGFETileElement')
   @DocsEditable()
   factory FETileElement() => _SvgElementFactoryProvider.createSvgElement_tag("feTile");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FETileElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feTile') && (new SvgElement.tag('feTile') is FETileElement);
@@ -2317,6 +2521,12 @@
   @DomName('SVGFETurbulenceElement.SVGFETurbulenceElement')
   @DocsEditable()
   factory FETurbulenceElement() => _SvgElementFactoryProvider.createSvgElement_tag("feTurbulence");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FETurbulenceElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('feTurbulence') && (new SvgElement.tag('feTurbulence') is FETurbulenceElement);
@@ -2410,6 +2620,12 @@
   @DomName('SVGFilterElement.SVGFilterElement')
   @DocsEditable()
   factory FilterElement() => _SvgElementFactoryProvider.createSvgElement_tag("filter");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FilterElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('filter') && (new SvgElement.tag('filter') is FilterElement);
@@ -2514,6 +2730,12 @@
   @DomName('SVGForeignObjectElement.SVGForeignObjectElement')
   @DocsEditable()
   factory ForeignObjectElement() => _SvgElementFactoryProvider.createSvgElement_tag("foreignObject");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ForeignObjectElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('foreignObject') && (new SvgElement.tag('foreignObject') is ForeignObjectElement);
@@ -2555,6 +2777,12 @@
   @DomName('SVGGElement.SVGGElement')
   @DocsEditable()
   factory GElement() => _SvgElementFactoryProvider.createSvgElement_tag("g");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  GElement.created() : super.created();
 
   // From SVGExternalResourcesRequired
 
@@ -2573,6 +2801,12 @@
 class GraphicsElement extends SvgElement implements Tests native "SVGGraphicsElement" {
   // To suppress missing implicit constructor warnings.
   factory GraphicsElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  GraphicsElement.created() : super.created();
 
   @DomName('SVGGraphicsElement.farthestViewportElement')
   @DocsEditable()
@@ -2648,6 +2882,12 @@
   @DomName('SVGImageElement.SVGImageElement')
   @DocsEditable()
   factory ImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("image");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ImageElement.created() : super.created();
 
   @DomName('SVGImageElement.height')
   @DocsEditable()
@@ -2862,6 +3102,12 @@
   @DomName('SVGLineElement.SVGLineElement')
   @DocsEditable()
   factory LineElement() => _SvgElementFactoryProvider.createSvgElement_tag("line");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LineElement.created() : super.created();
 
   @DomName('SVGLineElement.x1')
   @DocsEditable()
@@ -2900,6 +3146,12 @@
   @DomName('SVGLinearGradientElement.SVGLinearGradientElement')
   @DocsEditable()
   factory LinearGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("linearGradient");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LinearGradientElement.created() : super.created();
 
   @DomName('SVGLinearGradientElement.x1')
   @DocsEditable()
@@ -2932,6 +3184,12 @@
   @DomName('SVGMarkerElement.SVGMarkerElement')
   @DocsEditable()
   factory MarkerElement() => _SvgElementFactoryProvider.createSvgElement_tag("marker");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MarkerElement.created() : super.created();
 
   @DomName('SVGMarkerElement.SVG_MARKERUNITS_STROKEWIDTH')
   @DocsEditable()
@@ -3024,6 +3282,12 @@
   @DomName('SVGMaskElement.SVGMaskElement')
   @DocsEditable()
   factory MaskElement() => _SvgElementFactoryProvider.createSvgElement_tag("mask");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MaskElement.created() : super.created();
 
   @DomName('SVGMaskElement.height')
   @DocsEditable()
@@ -3162,6 +3426,12 @@
 class MetadataElement extends SvgElement native "SVGMetadataElement" {
   // To suppress missing implicit constructor warnings.
   factory MetadataElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MetadataElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -3280,6 +3550,12 @@
   @DomName('SVGPathElement.SVGPathElement')
   @DocsEditable()
   factory PathElement() => _SvgElementFactoryProvider.createSvgElement_tag("path");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PathElement.created() : super.created();
 
   @DomName('SVGPathElement.animatedNormalizedPathSegList')
   @DocsEditable()
@@ -4075,6 +4351,12 @@
   @DomName('SVGPatternElement.SVGPatternElement')
   @DocsEditable()
   factory PatternElement() => _SvgElementFactoryProvider.createSvgElement_tag("pattern");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PatternElement.created() : super.created();
 
   @DomName('SVGPatternElement.height')
   @DocsEditable()
@@ -4223,6 +4505,12 @@
   @DomName('SVGPolygonElement.SVGPolygonElement')
   @DocsEditable()
   factory PolygonElement() => _SvgElementFactoryProvider.createSvgElement_tag("polygon");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PolygonElement.created() : super.created();
 
   @DomName('SVGPolygonElement.animatedPoints')
   @DocsEditable()
@@ -4253,6 +4541,12 @@
   @DomName('SVGPolylineElement.SVGPolylineElement')
   @DocsEditable()
   factory PolylineElement() => _SvgElementFactoryProvider.createSvgElement_tag("polyline");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PolylineElement.created() : super.created();
 
   @DomName('SVGPolylineElement.animatedPoints')
   @DocsEditable()
@@ -4357,6 +4651,12 @@
   @DomName('SVGRadialGradientElement.SVGRadialGradientElement')
   @DocsEditable()
   factory RadialGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("radialGradient");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  RadialGradientElement.created() : super.created();
 
   @DomName('SVGRadialGradientElement.cx')
   @DocsEditable()
@@ -4423,6 +4723,12 @@
   @DomName('SVGRectElement.SVGRectElement')
   @DocsEditable()
   factory RectElement() => _SvgElementFactoryProvider.createSvgElement_tag("rect");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  RectElement.created() : super.created();
 
   @DomName('SVGRectElement.height')
   @DocsEditable()
@@ -4503,6 +4809,12 @@
   @DomName('SVGScriptElement.SVGScriptElement')
   @DocsEditable()
   factory ScriptElement() => _SvgElementFactoryProvider.createSvgElement_tag("script");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ScriptElement.created() : super.created();
 
   @DomName('SVGScriptElement.type')
   @DocsEditable()
@@ -4538,6 +4850,12 @@
   @DomName('SVGSetElement.SVGSetElement')
   @DocsEditable()
   factory SetElement() => _SvgElementFactoryProvider.createSvgElement_tag("set");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SetElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('set') && (new SvgElement.tag('set') is SetElement);
@@ -4557,6 +4875,12 @@
   @DomName('SVGStopElement.SVGStopElement')
   @DocsEditable()
   factory StopElement() => _SvgElementFactoryProvider.createSvgElement_tag("stop");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  StopElement.created() : super.created();
 
   @JSName('offset')
   @DomName('SVGStopElement.offset')
@@ -4667,6 +4991,12 @@
   @DomName('SVGStyleElement.SVGStyleElement')
   @DocsEditable()
   factory StyleElement() => _SvgElementFactoryProvider.createSvgElement_tag("style");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  StyleElement.created() : super.created();
 
   @DomName('SVGStyleElement.disabled')
   @DocsEditable()
@@ -4856,6 +5186,12 @@
   }
   // To suppress missing implicit constructor warnings.
   factory SvgElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SvgElement.created() : super.created();
 
   // Shadowing definition.
   AnimatedString get _svgClassName => JS("AnimatedString", "#.className", this);
@@ -4904,6 +5240,12 @@
 
   // To suppress missing implicit constructor warnings.
   factory SvgSvgElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SvgSvgElement.created() : super.created();
 
   @DomName('SVGSVGElement.contentScriptType')
   @DocsEditable()
@@ -5107,6 +5449,12 @@
   @DomName('SVGSwitchElement.SVGSwitchElement')
   @DocsEditable()
   factory SwitchElement() => _SvgElementFactoryProvider.createSvgElement_tag("switch");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SwitchElement.created() : super.created();
 
   // From SVGExternalResourcesRequired
 
@@ -5129,6 +5477,12 @@
   @DomName('SVGSymbolElement.SVGSymbolElement')
   @DocsEditable()
   factory SymbolElement() => _SvgElementFactoryProvider.createSvgElement_tag("symbol");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SymbolElement.created() : super.created();
 
   // From SVGExternalResourcesRequired
 
@@ -5161,6 +5515,12 @@
   @DomName('SVGTSpanElement.SVGTSpanElement')
   @DocsEditable()
   factory TSpanElement() => _SvgElementFactoryProvider.createSvgElement_tag("tspan");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TSpanElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -5191,6 +5551,12 @@
 class TextContentElement extends GraphicsElement implements ExternalResourcesRequired native "SVGTextContentElement" {
   // To suppress missing implicit constructor warnings.
   factory TextContentElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextContentElement.created() : super.created();
 
   @DomName('SVGTextContentElement.LENGTHADJUST_SPACING')
   @DocsEditable()
@@ -5269,6 +5635,12 @@
   @DomName('SVGTextElement.SVGTextElement')
   @DocsEditable()
   factory TextElement() => _SvgElementFactoryProvider.createSvgElement_tag("text");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -5281,6 +5653,12 @@
 class TextPathElement extends TextContentElement implements UriReference native "SVGTextPathElement" {
   // To suppress missing implicit constructor warnings.
   factory TextPathElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextPathElement.created() : super.created();
 
   @DomName('SVGTextPathElement.TEXTPATH_METHODTYPE_ALIGN')
   @DocsEditable()
@@ -5335,6 +5713,12 @@
 class TextPositioningElement extends TextContentElement native "SVGTextPositioningElement" {
   // To suppress missing implicit constructor warnings.
   factory TextPositioningElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextPositioningElement.created() : super.created();
 
   @DomName('SVGTextPositioningElement.dx')
   @DocsEditable()
@@ -5371,6 +5755,12 @@
   @DomName('SVGTitleElement.SVGTitleElement')
   @DocsEditable()
   factory TitleElement() => _SvgElementFactoryProvider.createSvgElement_tag("title");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TitleElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -5592,6 +5982,12 @@
   @DomName('SVGUseElement.SVGUseElement')
   @DocsEditable()
   factory UseElement() => _SvgElementFactoryProvider.createSvgElement_tag("use");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  UseElement.created() : super.created();
 
   @DomName('SVGUseElement.animatedInstanceRoot')
   @DocsEditable()
@@ -5662,6 +6058,12 @@
   @DomName('SVGViewElement.SVGViewElement')
   @DocsEditable()
   factory ViewElement() => _SvgElementFactoryProvider.createSvgElement_tag("view");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ViewElement.created() : super.created();
 
   @DomName('SVGViewElement.viewTarget')
   @DocsEditable()
@@ -5869,6 +6271,12 @@
 class _GradientElement extends SvgElement implements UriReference, ExternalResourcesRequired native "SVGGradientElement" {
   // To suppress missing implicit constructor warnings.
   factory _GradientElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _GradientElement.created() : super.created();
 
   @DomName('SVGGradientElement.SVG_SPREADMETHOD_PAD')
   @DocsEditable()
@@ -5921,6 +6329,12 @@
 abstract class _SVGAltGlyphDefElement extends SvgElement native "SVGAltGlyphDefElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGAltGlyphDefElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGAltGlyphDefElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -5933,6 +6347,12 @@
 abstract class _SVGAltGlyphItemElement extends SvgElement native "SVGAltGlyphItemElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGAltGlyphItemElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGAltGlyphItemElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -5945,6 +6365,12 @@
 abstract class _SVGAnimateColorElement extends AnimationElement native "SVGAnimateColorElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGAnimateColorElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGAnimateColorElement.created() : super.created();
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -5970,6 +6396,12 @@
 abstract class _SVGComponentTransferFunctionElement extends SvgElement native "SVGComponentTransferFunctionElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGComponentTransferFunctionElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGComponentTransferFunctionElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -5986,6 +6418,12 @@
   @DomName('SVGCursorElement.SVGCursorElement')
   @DocsEditable()
   factory _SVGCursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGCursorElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => SvgElement.isTagSupported('cursor') && (new SvgElement.tag('cursor') is _SVGCursorElement);
@@ -6007,6 +6445,12 @@
 abstract class _SVGFEDropShadowElement extends SvgElement implements FilterPrimitiveStandardAttributes native "SVGFEDropShadowElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGFEDropShadowElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFEDropShadowElement.created() : super.created();
 
   // From SVGFilterPrimitiveStandardAttributes
 }
@@ -6021,6 +6465,12 @@
 abstract class _SVGFontElement extends SvgElement native "SVGFontElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGFontElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFontElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -6033,6 +6483,12 @@
 abstract class _SVGFontFaceElement extends SvgElement native "SVGFontFaceElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGFontFaceElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFontFaceElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -6045,6 +6501,12 @@
 abstract class _SVGFontFaceFormatElement extends SvgElement native "SVGFontFaceFormatElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGFontFaceFormatElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFontFaceFormatElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -6057,6 +6519,12 @@
 abstract class _SVGFontFaceNameElement extends SvgElement native "SVGFontFaceNameElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGFontFaceNameElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFontFaceNameElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -6069,6 +6537,12 @@
 abstract class _SVGFontFaceSrcElement extends SvgElement native "SVGFontFaceSrcElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGFontFaceSrcElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFontFaceSrcElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -6081,6 +6555,12 @@
 abstract class _SVGFontFaceUriElement extends SvgElement native "SVGFontFaceUriElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGFontFaceUriElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFontFaceUriElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -6097,6 +6577,12 @@
   @DomName('SVGGlyphElement.SVGGlyphElement')
   @DocsEditable()
   factory _SVGGlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGGlyphElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -6109,6 +6595,12 @@
 abstract class _SVGGlyphRefElement extends SvgElement implements UriReference native "SVGGlyphRefElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGGlyphRefElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGGlyphRefElement.created() : super.created();
 
   // From SVGURIReference
 }
@@ -6127,6 +6619,12 @@
   @DomName('SVGHKernElement.SVGHKernElement')
   @DocsEditable()
   factory _SVGHKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGHKernElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -6142,6 +6640,12 @@
   @DomName('SVGMPathElement.SVGMPathElement')
   @DocsEditable()
   factory _SVGMPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGMPathElement.created() : super.created();
 
   // From SVGExternalResourcesRequired
 
@@ -6158,6 +6662,12 @@
 abstract class _SVGMissingGlyphElement extends SvgElement native "SVGMissingGlyphElement" {
   // To suppress missing implicit constructor warnings.
   factory _SVGMissingGlyphElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGMissingGlyphElement.created() : super.created();
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -6186,6 +6696,12 @@
   @DomName('SVGTRefElement.SVGTRefElement')
   @DocsEditable()
   factory _SVGTRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGTRefElement.created() : super.created();
 
   // From SVGURIReference
 }
@@ -6204,4 +6720,10 @@
   @DomName('SVGVKernElement.SVGVKernElement')
   @DocsEditable()
   factory _SVGVKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGVKernElement.created() : super.created();
 }
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index 2201493..785f717 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -42,6 +42,12 @@
   @DomName('SVGAElement.SVGAElement')
   @DocsEditable()
   factory AElement() => _SvgElementFactoryProvider.createSvgElement_tag("a");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AElement.created() : super.created();
 
   @DomName('SVGAElement.target')
   @DocsEditable()
@@ -76,6 +82,12 @@
   @DomName('SVGAltGlyphElement.SVGAltGlyphElement')
   @DocsEditable()
   factory AltGlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("altGlyph");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AltGlyphElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -190,6 +202,12 @@
   @DomName('SVGAnimateElement.SVGAnimateElement')
   @DocsEditable()
   factory AnimateElement() => _SvgElementFactoryProvider.createSvgElement_tag("animate");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnimateElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -215,6 +233,12 @@
   @DomName('SVGAnimateMotionElement.SVGAnimateMotionElement')
   @DocsEditable()
   factory AnimateMotionElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateMotion");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnimateMotionElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -240,6 +264,12 @@
   @DomName('SVGAnimateTransformElement.SVGAnimateTransformElement')
   @DocsEditable()
   factory AnimateTransformElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateTransform");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnimateTransformElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -534,6 +564,12 @@
   @DomName('SVGAnimationElement.SVGAnimationElement')
   @DocsEditable()
   factory AnimationElement() => _SvgElementFactoryProvider.createSvgElement_tag("animation");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  AnimationElement.created() : super.created();
 
   @DomName('SVGAnimationElement.targetElement')
   @DocsEditable()
@@ -605,6 +641,12 @@
   @DomName('SVGCircleElement.SVGCircleElement')
   @DocsEditable()
   factory CircleElement() => _SvgElementFactoryProvider.createSvgElement_tag("circle");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  CircleElement.created() : super.created();
 
   @DomName('SVGCircleElement.cx')
   @DocsEditable()
@@ -640,6 +682,12 @@
   @DomName('SVGClipPathElement.SVGClipPathElement')
   @DocsEditable()
   factory ClipPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("clipPath");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ClipPathElement.created() : super.created();
 
   @DomName('SVGClipPathElement.clipPathUnits')
   @DocsEditable()
@@ -667,6 +715,12 @@
   @DomName('SVGDefsElement.SVGDefsElement')
   @DocsEditable()
   factory DefsElement() => _SvgElementFactoryProvider.createSvgElement_tag("defs");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DefsElement.created() : super.created();
 
   @DomName('SVGDefsElement.externalResourcesRequired')
   @DocsEditable()
@@ -690,6 +744,12 @@
   @DomName('SVGDescElement.SVGDescElement')
   @DocsEditable()
   factory DescElement() => _SvgElementFactoryProvider.createSvgElement_tag("desc");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  DescElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -1115,6 +1175,12 @@
   @DomName('SVGEllipseElement.SVGEllipseElement')
   @DocsEditable()
   factory EllipseElement() => _SvgElementFactoryProvider.createSvgElement_tag("ellipse");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  EllipseElement.created() : super.created();
 
   @DomName('SVGEllipseElement.cx')
   @DocsEditable()
@@ -1178,6 +1244,12 @@
   @DomName('SVGFEBlendElement.SVGFEBlendElement')
   @DocsEditable()
   factory FEBlendElement() => _SvgElementFactoryProvider.createSvgElement_tag("feBlend");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEBlendElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1260,6 +1332,12 @@
   @DomName('SVGFEColorMatrixElement.SVGFEColorMatrixElement')
   @DocsEditable()
   factory FEColorMatrixElement() => _SvgElementFactoryProvider.createSvgElement_tag("feColorMatrix");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEColorMatrixElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1338,6 +1416,12 @@
   @DomName('SVGFEComponentTransferElement.SVGFEComponentTransferElement')
   @DocsEditable()
   factory FEComponentTransferElement() => _SvgElementFactoryProvider.createSvgElement_tag("feComponentTransfer");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEComponentTransferElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1380,6 +1464,12 @@
 class FECompositeElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FECompositeElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FECompositeElement.created() : super.created();
 
   @DomName('SVGFECompositeElement.SVG_FECOMPOSITE_OPERATOR_ARITHMETIC')
   @DocsEditable()
@@ -1479,6 +1569,12 @@
   @DomName('SVGFEConvolveMatrixElement.SVGFEConvolveMatrixElement')
   @DocsEditable()
   factory FEConvolveMatrixElement() => _SvgElementFactoryProvider.createSvgElement_tag("feConvolveMatrix");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEConvolveMatrixElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1589,6 +1685,12 @@
   @DomName('SVGFEDiffuseLightingElement.SVGFEDiffuseLightingElement')
   @DocsEditable()
   factory FEDiffuseLightingElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDiffuseLighting");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEDiffuseLightingElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1655,6 +1757,12 @@
   @DomName('SVGFEDisplacementMapElement.SVGFEDisplacementMapElement')
   @DocsEditable()
   factory FEDisplacementMapElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDisplacementMap");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEDisplacementMapElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1741,6 +1849,12 @@
   @DomName('SVGFEDistantLightElement.SVGFEDistantLightElement')
   @DocsEditable()
   factory FEDistantLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("feDistantLight");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEDistantLightElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1775,6 +1889,12 @@
   @DomName('SVGFEFloodElement.SVGFEFloodElement')
   @DocsEditable()
   factory FEFloodElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFlood");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFloodElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1821,6 +1941,12 @@
   @DomName('SVGFEFuncAElement.SVGFEFuncAElement')
   @DocsEditable()
   factory FEFuncAElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncA");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFuncAElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1847,6 +1973,12 @@
   @DomName('SVGFEFuncBElement.SVGFEFuncBElement')
   @DocsEditable()
   factory FEFuncBElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncB");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFuncBElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1873,6 +2005,12 @@
   @DomName('SVGFEFuncGElement.SVGFEFuncGElement')
   @DocsEditable()
   factory FEFuncGElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncG");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFuncGElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1899,6 +2037,12 @@
   @DomName('SVGFEFuncRElement.SVGFEFuncRElement')
   @DocsEditable()
   factory FEFuncRElement() => _SvgElementFactoryProvider.createSvgElement_tag("feFuncR");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEFuncRElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1925,6 +2069,12 @@
   @DomName('SVGFEGaussianBlurElement.SVGFEGaussianBlurElement')
   @DocsEditable()
   factory FEGaussianBlurElement() => _SvgElementFactoryProvider.createSvgElement_tag("feGaussianBlur");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEGaussianBlurElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -1987,6 +2137,12 @@
   @DomName('SVGFEImageElement.SVGFEImageElement')
   @DocsEditable()
   factory FEImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("feImage");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEImageElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -2045,6 +2201,12 @@
   @DomName('SVGFEMergeElement.SVGFEMergeElement')
   @DocsEditable()
   factory FEMergeElement() => _SvgElementFactoryProvider.createSvgElement_tag("feMerge");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEMergeElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -2091,6 +2253,12 @@
   @DomName('SVGFEMergeNodeElement.SVGFEMergeNodeElement')
   @DocsEditable()
   factory FEMergeNodeElement() => _SvgElementFactoryProvider.createSvgElement_tag("feMergeNode");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEMergeNodeElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -2117,6 +2285,12 @@
 class FEMorphologyElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory FEMorphologyElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEMorphologyElement.created() : super.created();
 
   @DomName('SVGFEMorphologyElement.SVG_MORPHOLOGY_OPERATOR_DILATE')
   @DocsEditable()
@@ -2192,6 +2366,12 @@
   @DomName('SVGFEOffsetElement.SVGFEOffsetElement')
   @DocsEditable()
   factory FEOffsetElement() => _SvgElementFactoryProvider.createSvgElement_tag("feOffset");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEOffsetElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -2250,6 +2430,12 @@
   @DomName('SVGFEPointLightElement.SVGFEPointLightElement')
   @DocsEditable()
   factory FEPointLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("fePointLight");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FEPointLightElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -2288,6 +2474,12 @@
   @DomName('SVGFESpecularLightingElement.SVGFESpecularLightingElement')
   @DocsEditable()
   factory FESpecularLightingElement() => _SvgElementFactoryProvider.createSvgElement_tag("feSpecularLighting");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FESpecularLightingElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -2350,6 +2542,12 @@
   @DomName('SVGFESpotLightElement.SVGFESpotLightElement')
   @DocsEditable()
   factory FESpotLightElement() => _SvgElementFactoryProvider.createSvgElement_tag("feSpotLight");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FESpotLightElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -2408,6 +2606,12 @@
   @DomName('SVGFETileElement.SVGFETileElement')
   @DocsEditable()
   factory FETileElement() => _SvgElementFactoryProvider.createSvgElement_tag("feTile");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FETileElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -2458,6 +2662,12 @@
   @DomName('SVGFETurbulenceElement.SVGFETurbulenceElement')
   @DocsEditable()
   factory FETurbulenceElement() => _SvgElementFactoryProvider.createSvgElement_tag("feTurbulence");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FETurbulenceElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -2552,6 +2762,12 @@
   @DomName('SVGFilterElement.SVGFilterElement')
   @DocsEditable()
   factory FilterElement() => _SvgElementFactoryProvider.createSvgElement_tag("filter");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  FilterElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -2675,6 +2891,12 @@
   @DomName('SVGForeignObjectElement.SVGForeignObjectElement')
   @DocsEditable()
   factory ForeignObjectElement() => _SvgElementFactoryProvider.createSvgElement_tag("foreignObject");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ForeignObjectElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -2717,6 +2939,12 @@
   @DomName('SVGGElement.SVGGElement')
   @DocsEditable()
   factory GElement() => _SvgElementFactoryProvider.createSvgElement_tag("g");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  GElement.created() : super.created();
 
   @DomName('SVGGElement.externalResourcesRequired')
   @DocsEditable()
@@ -2736,6 +2964,12 @@
 class GraphicsElement extends SvgElement implements Tests {
   // To suppress missing implicit constructor warnings.
   factory GraphicsElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  GraphicsElement.created() : super.created();
 
   @DomName('SVGGraphicsElement.farthestViewportElement')
   @DocsEditable()
@@ -2810,6 +3044,12 @@
   @DomName('SVGImageElement.SVGImageElement')
   @DocsEditable()
   factory ImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("image");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ImageElement.created() : super.created();
 
   @DomName('SVGImageElement.height')
   @DocsEditable()
@@ -3041,6 +3281,12 @@
   @DomName('SVGLineElement.SVGLineElement')
   @DocsEditable()
   factory LineElement() => _SvgElementFactoryProvider.createSvgElement_tag("line");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LineElement.created() : super.created();
 
   @DomName('SVGLineElement.x1')
   @DocsEditable()
@@ -3080,6 +3326,12 @@
   @DomName('SVGLinearGradientElement.SVGLinearGradientElement')
   @DocsEditable()
   factory LinearGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("linearGradient");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  LinearGradientElement.created() : super.created();
 
   @DomName('SVGLinearGradientElement.x1')
   @DocsEditable()
@@ -3115,6 +3367,12 @@
   @DomName('SVGMarkerElement.SVGMarkerElement')
   @DocsEditable()
   factory MarkerElement() => _SvgElementFactoryProvider.createSvgElement_tag("marker");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MarkerElement.created() : super.created();
 
   @DomName('SVGMarkerElement.SVG_MARKERUNITS_STROKEWIDTH')
   @DocsEditable()
@@ -3206,6 +3464,12 @@
   @DomName('SVGMaskElement.SVGMaskElement')
   @DocsEditable()
   factory MaskElement() => _SvgElementFactoryProvider.createSvgElement_tag("mask");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MaskElement.created() : super.created();
 
   @DomName('SVGMaskElement.height')
   @DocsEditable()
@@ -3370,6 +3634,12 @@
 class MetadataElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory MetadataElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  MetadataElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -3501,6 +3771,12 @@
   @DomName('SVGPathElement.SVGPathElement')
   @DocsEditable()
   factory PathElement() => _SvgElementFactoryProvider.createSvgElement_tag("path");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PathElement.created() : super.created();
 
   @DomName('SVGPathElement.animatedNormalizedPathSegList')
   @DocsEditable()
@@ -4573,6 +4849,12 @@
   @DomName('SVGPatternElement.SVGPatternElement')
   @DocsEditable()
   factory PatternElement() => _SvgElementFactoryProvider.createSvgElement_tag("pattern");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PatternElement.created() : super.created();
 
   @DomName('SVGPatternElement.height')
   @DocsEditable()
@@ -4730,6 +5012,12 @@
   @DomName('SVGPolygonElement.SVGPolygonElement')
   @DocsEditable()
   factory PolygonElement() => _SvgElementFactoryProvider.createSvgElement_tag("polygon");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PolygonElement.created() : super.created();
 
   @DomName('SVGPolygonElement.animatedPoints')
   @DocsEditable()
@@ -4761,6 +5049,12 @@
   @DomName('SVGPolylineElement.SVGPolylineElement')
   @DocsEditable()
   factory PolylineElement() => _SvgElementFactoryProvider.createSvgElement_tag("polyline");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  PolylineElement.created() : super.created();
 
   @DomName('SVGPolylineElement.animatedPoints')
   @DocsEditable()
@@ -4877,6 +5171,12 @@
   @DomName('SVGRadialGradientElement.SVGRadialGradientElement')
   @DocsEditable()
   factory RadialGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("radialGradient");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  RadialGradientElement.created() : super.created();
 
   @DomName('SVGRadialGradientElement.cx')
   @DocsEditable()
@@ -4965,6 +5265,12 @@
   @DomName('SVGRectElement.SVGRectElement')
   @DocsEditable()
   factory RectElement() => _SvgElementFactoryProvider.createSvgElement_tag("rect");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  RectElement.created() : super.created();
 
   @DomName('SVGRectElement.height')
   @DocsEditable()
@@ -5049,6 +5355,12 @@
   @DomName('SVGScriptElement.SVGScriptElement')
   @DocsEditable()
   factory ScriptElement() => _SvgElementFactoryProvider.createSvgElement_tag("script");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ScriptElement.created() : super.created();
 
   @DomName('SVGScriptElement.type')
   @DocsEditable()
@@ -5087,6 +5399,12 @@
   @DomName('SVGSetElement.SVGSetElement')
   @DocsEditable()
   factory SetElement() => _SvgElementFactoryProvider.createSvgElement_tag("set");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SetElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -5109,6 +5427,12 @@
   @DomName('SVGStopElement.SVGStopElement')
   @DocsEditable()
   factory StopElement() => _SvgElementFactoryProvider.createSvgElement_tag("stop");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  StopElement.created() : super.created();
 
   @DomName('SVGStopElement.offset')
   @DocsEditable()
@@ -5224,6 +5548,12 @@
   @DomName('SVGStyleElement.SVGStyleElement')
   @DocsEditable()
   factory StyleElement() => _SvgElementFactoryProvider.createSvgElement_tag("style");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  StyleElement.created() : super.created();
 
   @DomName('SVGStyleElement.disabled')
   @DocsEditable()
@@ -5434,6 +5764,12 @@
   }
   // To suppress missing implicit constructor warnings.
   factory SvgElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SvgElement.created() : super.created();
 
   @DomName('SVGElement.className')
   @DocsEditable()
@@ -5499,6 +5835,12 @@
 
   // To suppress missing implicit constructor warnings.
   factory SvgSvgElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SvgSvgElement.created() : super.created();
 
   @DomName('SVGSVGElement.contentScriptType')
   @DocsEditable()
@@ -5702,6 +6044,12 @@
   @DomName('SVGSwitchElement.SVGSwitchElement')
   @DocsEditable()
   factory SwitchElement() => _SvgElementFactoryProvider.createSvgElement_tag("switch");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SwitchElement.created() : super.created();
 
   @DomName('SVGSwitchElement.externalResourcesRequired')
   @DocsEditable()
@@ -5725,6 +6073,12 @@
   @DomName('SVGSymbolElement.SVGSymbolElement')
   @DocsEditable()
   factory SymbolElement() => _SvgElementFactoryProvider.createSvgElement_tag("symbol");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  SymbolElement.created() : super.created();
 
   @DomName('SVGSymbolElement.externalResourcesRequired')
   @DocsEditable()
@@ -5756,6 +6110,12 @@
   @DomName('SVGTSpanElement.SVGTSpanElement')
   @DocsEditable()
   factory TSpanElement() => _SvgElementFactoryProvider.createSvgElement_tag("tspan");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TSpanElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -5800,6 +6160,12 @@
 class TextContentElement extends GraphicsElement implements ExternalResourcesRequired {
   // To suppress missing implicit constructor warnings.
   factory TextContentElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextContentElement.created() : super.created();
 
   @DomName('SVGTextContentElement.LENGTHADJUST_SPACING')
   @DocsEditable()
@@ -5879,6 +6245,12 @@
   @DomName('SVGTextElement.SVGTextElement')
   @DocsEditable()
   factory TextElement() => _SvgElementFactoryProvider.createSvgElement_tag("text");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -5894,6 +6266,12 @@
 class TextPathElement extends TextContentElement implements UriReference {
   // To suppress missing implicit constructor warnings.
   factory TextPathElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextPathElement.created() : super.created();
 
   @DomName('SVGTextPathElement.TEXTPATH_METHODTYPE_ALIGN')
   @DocsEditable()
@@ -5949,6 +6327,12 @@
 class TextPositioningElement extends TextContentElement {
   // To suppress missing implicit constructor warnings.
   factory TextPositioningElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TextPositioningElement.created() : super.created();
 
   @DomName('SVGTextPositioningElement.dx')
   @DocsEditable()
@@ -5988,6 +6372,12 @@
   @DomName('SVGTitleElement.SVGTitleElement')
   @DocsEditable()
   factory TitleElement() => _SvgElementFactoryProvider.createSvgElement_tag("title");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  TitleElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6225,6 +6615,12 @@
   @DomName('SVGUseElement.SVGUseElement')
   @DocsEditable()
   factory UseElement() => _SvgElementFactoryProvider.createSvgElement_tag("use");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  UseElement.created() : super.created();
 
   @DomName('SVGUseElement.animatedInstanceRoot')
   @DocsEditable()
@@ -6292,6 +6688,12 @@
   @DomName('SVGViewElement.SVGViewElement')
   @DocsEditable()
   factory ViewElement() => _SvgElementFactoryProvider.createSvgElement_tag("view");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  ViewElement.created() : super.created();
 
   @DomName('SVGViewElement.viewTarget')
   @DocsEditable()
@@ -6522,6 +6924,12 @@
 class _GradientElement extends SvgElement implements UriReference, ExternalResourcesRequired {
   // To suppress missing implicit constructor warnings.
   factory _GradientElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _GradientElement.created() : super.created();
 
   @DomName('SVGGradientElement.SVG_SPREADMETHOD_PAD')
   @DocsEditable()
@@ -6573,6 +6981,12 @@
 abstract class _SVGAltGlyphDefElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory _SVGAltGlyphDefElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGAltGlyphDefElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6588,6 +7002,12 @@
 abstract class _SVGAltGlyphItemElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory _SVGAltGlyphItemElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGAltGlyphItemElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6603,6 +7023,12 @@
 abstract class _SVGAnimateColorElement extends AnimationElement {
   // To suppress missing implicit constructor warnings.
   factory _SVGAnimateColorElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGAnimateColorElement.created() : super.created();
 
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
@@ -6631,6 +7057,12 @@
 abstract class _SVGComponentTransferFunctionElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory _SVGComponentTransferFunctionElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGComponentTransferFunctionElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6650,6 +7082,12 @@
   @DomName('SVGCursorElement.SVGCursorElement')
   @DocsEditable()
   factory _SVGCursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGCursorElement.created() : super.created();
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -6668,6 +7106,12 @@
 abstract class _SVGFEDropShadowElement extends SvgElement implements FilterPrimitiveStandardAttributes {
   // To suppress missing implicit constructor warnings.
   factory _SVGFEDropShadowElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFEDropShadowElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6683,6 +7127,12 @@
 abstract class _SVGFontElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory _SVGFontElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFontElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6698,6 +7148,12 @@
 abstract class _SVGFontFaceElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory _SVGFontFaceElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFontFaceElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6713,6 +7169,12 @@
 abstract class _SVGFontFaceFormatElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory _SVGFontFaceFormatElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFontFaceFormatElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6728,6 +7190,12 @@
 abstract class _SVGFontFaceNameElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory _SVGFontFaceNameElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFontFaceNameElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6743,6 +7211,12 @@
 abstract class _SVGFontFaceSrcElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory _SVGFontFaceSrcElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFontFaceSrcElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6758,6 +7232,12 @@
 abstract class _SVGFontFaceUriElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory _SVGFontFaceUriElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGFontFaceUriElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6777,6 +7257,12 @@
   @DomName('SVGGlyphElement.SVGGlyphElement')
   @DocsEditable()
   factory _SVGGlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGGlyphElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6792,6 +7278,12 @@
 abstract class _SVGGlyphRefElement extends SvgElement implements UriReference {
   // To suppress missing implicit constructor warnings.
   factory _SVGGlyphRefElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGGlyphRefElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6811,6 +7303,12 @@
   @DomName('SVGHKernElement.SVGHKernElement')
   @DocsEditable()
   factory _SVGHKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGHKernElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6829,6 +7327,12 @@
   @DomName('SVGMPathElement.SVGMPathElement')
   @DocsEditable()
   factory _SVGMPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGMPathElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6844,6 +7348,12 @@
 abstract class _SVGMissingGlyphElement extends SvgElement {
   // To suppress missing implicit constructor warnings.
   factory _SVGMissingGlyphElement._() { throw new UnsupportedError("Not supported"); }
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGMissingGlyphElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6878,6 +7388,12 @@
   @DomName('SVGTRefElement.SVGTRefElement')
   @DocsEditable()
   factory _SVGTRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGTRefElement.created() : super.created();
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -6897,5 +7413,11 @@
   @DomName('SVGVKernElement.SVGVKernElement')
   @DocsEditable()
   factory _SVGVKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  _SVGVKernElement.created() : super.created();
 
 }
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
index c911f20..2859980 100644
--- a/tests/co19/co19-analyzer.status
+++ b/tests/co19/co19-analyzer.status
@@ -3,25 +3,12 @@
 # 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
-
-# not clear: null..[1](1)[2](2).foo(3, bar: 4)=5 - it seems that verything before =5 it not assignable
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: fail
-
 # invalid argument for constant constructor
 Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t02: fail
 
-# 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
 
@@ -29,16 +16,6 @@
 Language/15_Types/4_Interface_Types_A11_t01: Skip
 Language/15_Types/4_Interface_Types_A11_t02: Skip
 
-# TBF: Hence, a static warning will not be issued if f has no declared return type, since the return type would be dynamic and dynamic may be assigned to void.
-Language/13_Statements/11_Return_A07_t01: fail
-
-# TBF: typedef int func2(int); - "int is not a type"
-Language/15_Types/6_Type_dynamic_A03_t01: fail
-Language/15_Types/6_Type_dynamic_A04_t01: fail
-
-
-LibTest/core/Uri/decodeQueryComponent_A02_t01: fail # co19 Issue 591
-
 # co19 issue #380, Strings class has been removed
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: fail, OK
 
@@ -49,9 +26,6 @@
 LibTest/core/Set/isSubsetOf_A01_t02: fail, OK
 
 # co19 issue #425, Only static fields can be declared as 'const'
-Language/05_Variables/05_Variables_A12_t01: fail, OK
-Language/05_Variables/05_Variables_A12_t06: fail, OK
-Language/05_Variables/05_Variables_A13_t01: fail, OK
 Language/07_Classes/07_Classes_A02_t11: fail, OK
 
 # co19 issue #442, undefined name "Expect"
@@ -90,7 +64,6 @@
 Language/12_Expressions/12_Instance_Creation_A01_t06: 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 #541: tests contain unqualified reference to static members defined in superclass
@@ -100,20 +73,54 @@
 # co19 issue #543: invocation of a non-function
 Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t02: fail, OK
 
-# co19 issue #562: malformed superclass
-Language/14_Libraries_and_Scripts/1_Imports_A03_t27: fail, OK
-
-# co19 issue #563: implicitly named libraries are allowed
-Language/14_Libraries_and_Scripts/2_Exports_A05_t01: fail, OK
-
 # co19 issue #564: URI can be any number adjacent string literals
 Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail, OK
 Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail, OK
 
-# co19 issue #596: initializing final variable at declaration and in constructor
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail, OK
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail, OK
+# co19 issue #609, return type of "factory M" is M, so we need static warning for "return;".
+Language/13_Statements/11_Return_A07_t01: fail, OK
 
-# co19 issue #597: concrete class with abstract method
-Language/07_Classes/4_Abstract_Instance_Members_A07_t08: fail, OK
-
+Language/09_Mixins/1_Mixin_Application_A01_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/01_Constants_A22_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/07_Maps_A13_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/12_Instance_Creation_A01_t08: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/13_Property_Extraction_A02_t02: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/13_Property_Extraction_A04_t02: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/13_Property_Extraction_A04_t03: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t03: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t04: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A04_t04: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t05: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/16_Getter_Lookup_A02_t05: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/16_Getter_Lookup_A02_t06: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t02: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A01_t07: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A04_t09: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/02_Expression_Statements_A01_t13: Fail # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t08: Fail # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t09: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/HasNextIterator/HasNextIterator_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet.from_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/LinkedList_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/first_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/reduce_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isAccessor_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isAccessor_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isGetter_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isGetter_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isMethod_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isMethod_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isSetter_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isSetter_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/memberName_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/namedArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/positionalArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/RuneIterator/currentAsString_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/RuneIterator/current_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/isEmpty_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/isNotEmpty_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/lastWhere_A02_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/length_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t04: Fail # co19-roll r607: Please triage this failure
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 4a00538..cb338fd 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -3,9 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2analyzer ]
-# 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
-
 # not clear: null..[1](1)[2](2).foo(3, bar: 4)=5 - it seems that verything before =5 it not assignable
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A04_t15: fail
 
@@ -32,55 +29,18 @@
 # TBF: Hence, a static warning will not be issued if f has no declared return type, since the return type would be dynamic and dynamic may be assigned to void.
 Language/13_Statements/11_Return_A07_t01: fail
 
-# TBF: typedef int func2(int); - "int is not a type"
-Language/15_Types/6_Type_dynamic_A03_t01: fail
-Language/15_Types/6_Type_dynamic_A04_t01: fail
-
-
-LibTest/core/Uri/decodeQueryComponent_A02_t01: fail # co19 Issue 591
-
-# co19 issue #380, Strings class has been removed
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: fail, OK
-
-# co19 issue #400, collection library reorg
-LibTest/core/String/concat_A01_t01: fail, OK
-LibTest/core/String/concat_A02_t01: fail, OK
-LibTest/core/Set/isSubsetOf_A01_t01: fail, OK
-LibTest/core/Set/isSubsetOf_A01_t02: fail, OK
-
-# co19 issue #425, Only static fields can be declared as 'const'
-Language/05_Variables/05_Variables_A12_t01: fail, OK
-Language/05_Variables/05_Variables_A12_t06: fail, OK
-Language/05_Variables/05_Variables_A13_t01: fail, OK
-Language/07_Classes/07_Classes_A02_t11: fail, OK
-
 # co19 issue #442, undefined name "Expect"
 Language/15_Types/4_Interface_Types_A08_t03: fail, OK
 
 # co19 issue #455, undeclared identifier is static warning
 Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t10: fail, OK
-Language/13_Statements/04_Local_Function_Declaration_A02_t02: fail, OK
 Language/14_Libraries_and_Scripts/1_Imports_A02_t12: fail, OK
 Language/14_Libraries_and_Scripts/1_Imports_A02_t15: 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 #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_t03: fail, OK
-
-# co19 issue #593: Conditional expressions are now allowed as constant expressions
-Language/12_Expressions/01_Constants_A15_t16: 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 #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
 
@@ -90,7 +50,6 @@
 Language/12_Expressions/12_Instance_Creation_A01_t06: 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 #541: tests contain unqualified reference to static members defined in superclass
@@ -100,20 +59,51 @@
 # co19 issue #543: invocation of a non-function
 Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t02: fail, OK
 
-# co19 issue #562: malformed superclass
-Language/14_Libraries_and_Scripts/1_Imports_A03_t27: fail, OK
-
-# co19 issue #563: implicitly named libraries are allowed
-Language/14_Libraries_and_Scripts/2_Exports_A05_t01: fail, OK
-
 # co19 issue #564: URI can be any number adjacent string literals
 Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail, OK
 Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail, OK
 
-# co19 issue #596: initializing final variable at declaration and in constructor
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail, OK
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail, OK
-
-# co19 issue #597: concrete class with abstract method
-Language/07_Classes/4_Abstract_Instance_Members_A07_t08: fail, OK
-
+Language/09_Mixins/1_Mixin_Application_A01_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/01_Constants_A22_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/07_Maps_A13_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/12_Instance_Creation_A01_t08: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/13_Property_Extraction_A02_t02: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/13_Property_Extraction_A04_t02: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/13_Property_Extraction_A04_t03: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t03: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t04: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A04_t04: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t05: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/16_Getter_Lookup_A02_t05: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/16_Getter_Lookup_A02_t06: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t02: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A01_t07: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A04_t09: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/02_Expression_Statements_A01_t13: Fail # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t08: Fail # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t09: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/HasNextIterator/HasNextIterator_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet.from_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/LinkedList_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/first_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/reduce_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isAccessor_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isAccessor_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isGetter_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isGetter_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isMethod_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isMethod_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isSetter_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/isSetter_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/memberName_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/namedArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/positionalArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/RuneIterator/currentAsString_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/RuneIterator/current_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/isEmpty_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/isNotEmpty_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/lastWhere_A02_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/length_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t04: Fail # co19-roll r607: Please triage this failure
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 3bd647f..5dcead1 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -10,13 +10,32 @@
 
 
 [ $runtime == vm || $compiler == dart2dart || $compiler == dart2js ]
+Language/12_Expressions/05_Strings_A02_t46: fail, pass, ok # co19 issue 612
+Language/12_Expressions/05_Strings_A02_t48: fail, pass, ok # co19 issue 612
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail # co19-roll r587: Please triage this failure
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail # co19-roll r587: Please triage this failure
-LibTest/core/Uri/decodeQueryComponent_A02_t01: fail # co19 Issue 591
 LibTest/core/Uri/toFilePath_A01_t01: pass, fail, ok # co19 Issue 592
 # Maybe we should wait until isolate library is sealed before triaging these.
 LibTest/isolate/isolate_api/spawnFunction_A04_t01: fail, timeout # co19-roll r546: Please triage this failure
 LibTest/isolate/isolate_api/streamSpawnFunction_A02_t01: fail, timeout # co19-roll r546: Please triage this failure
+Language/15_Types/1_Static_Types_A03_t01: Fail # co19-roll r607: Please triage this failure
+
+Language/09_Mixins/1_Mixin_Application_A01_t01: CompileTimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: CompileTimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/first_A01_t02: CompileTimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A01_t07: RuntimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A04_t09: RuntimeError # co19-roll r607: Please triage this failure
+Language/13_Statements/04_Local_Function_Declaration_A04_t01: MissingCompileTimeError # co19-roll r607: Please triage this failure
+Language/13_Statements/02_Expression_Statements_A01_t13: MissingCompileTimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t03: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/HasNextIterator/HasNextIterator_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet.from_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Runes/lastWhere_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/LinkedList_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/forEach_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/reduce_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/namedArguments_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t04: RuntimeError # co19-roll r607: Please triage this failure
 
 [ $runtime == vm || $compiler == dart2dart || $compiler == dart2js ]
 LibTest/typed_data/ByteData/elementSizeInBytes_A01_t01: fail # co19-roll r569: Please triage this failure
@@ -32,21 +51,15 @@
 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/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/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/truncate_A01_t03: FAIL, OK # co19 issue 389
-LibTest/core/double/truncate_A01_t04: FAIL, OK # co19 issue 389
 
 LibTest/async/Stream/Stream.periodic_A01_t01: TIMEOUT, PASS, FAIL, OK # co19 issue 538
 LibTest/async/Stream/Stream.periodic_A03_t01: PASS, FAIL, OK # co19 issue 538
@@ -61,61 +74,19 @@
 LibTest/isolate/SendPort/send_A02_t03: SKIP # co19 issue 495
 
 LibTest/isolate/isolate_api/streamSpawnFunction_A02_t02: PASS, FAIL, OK # co19 issue 540
-LibTest/isolate/isolate_api/streamSpawnFunction_A02_t03: PASS, FAIL, OK # co19 issue 540
 LibTest/isolate/IsolateStream/contains_A02_t01: PASS, FAIL, OK # co19 issue 540
 
 LibTest/async/EventTransformStream/listen_A04_t01: Pass, Timeout # co19 issue 542
 
 LibTest/typed_data/Int8List/Int8List.fromList_A01_t02: Fail # co19-roll r559: Please triage this failure
 
-LibTest/typed_data/Float32List/removeAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Float32List/retainAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Float32x4List/removeAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Float32x4List/retainAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Float64List/removeAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Float64List/retainAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Int16List/removeAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Int16List/retainAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Int32List/removeAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Int32List/retainAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Int64List/removeAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Int64List/retainAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Int8List/removeAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Int8List/retainAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Uint16List/removeAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Uint16List/retainAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Uint32List/removeAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Uint32List/retainAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Uint64List/removeAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Uint64List/retainAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Uint8ClampedList/removeAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Uint8ClampedList/retainAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Uint8List/removeAll_A01_t01: Fail  # co19 issue 548
-LibTest/typed_data/Uint8List/retainAll_A01_t01: Fail  # co19 issue 548
-
-LibTest/core/String/concat_A01_t01: Fail  # co19 issue 561
-LibTest/core/String/concat_A02_t01: Fail  # co19 issue 561
-
-[ $compiler != dartanalyzer && $compiler != dart2analyzer ]
-# Dart2js/Dart2dart succeedes due to a bug in their parser (issue 13223).
-Language/12_Expressions/21_Bitwise_Expressions_A01_t01: Fail # co19 Issue 595
-
 ### CHECKED MODE FAILURES ###
 
 [ ($runtime == vm || $compiler == dart2js) && $checked]
 Language/07_Classes/6_Constructors/2_Factories_A12_t02: fail # co19-roll r587: Please triage this failure
 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/14_Libraries_and_Scripts/1_Imports_A03_t46: PASS, FAIL, OK # co19 issue 560
 Language/14_Libraries_and_Scripts/1_Imports_A03_t66: PASS, FAIL, OK # co19 issue 560
-Language/15_Types/1_Static_Types_A03_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/async/EventTransformStream/contains_A01_t01: FAIL, OK  # co19 issue 498
-LibTest/core/DateTime/compareTo_A02_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/collection/DoubleLinkedQueue/removeFirst_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 788a3df..5da24a9 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -4,6 +4,15 @@
 
 [ $compiler == dart2dart ]
 LibTest/async/Stream/Stream.periodic_A01_t01: Pass, Fail # Issue 12562.
+LibTest/core/Symbol/Symbol_A01_t02: CompileTimeError # co19-roll r607: Please triage this failure
+
+Language/12_Expressions/12_Instance_Creation/1_New_A04_t02: RuntimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t02: Pass, RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/memberName_A01_t01: Pass, RuntimeError # co18-roll r607: Please triage this failure
+LibTest/core/Invocation/positionalArguments_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # co19-roll r607: Please triage this failure
 
 Language/07_Classes/9_Superclasses/1_Inheritance_and_Overriding_A01_t03: Fail # TODO(dart2dart-team): Please triage this failure.
 
@@ -13,20 +22,9 @@
 
 Language/03_Overview/1_Scoping_A02_t05: Fail # Inherited from dart2js
 Language/03_Overview/1_Scoping_A02_t06: Fail # inherited from dart2js
-Language/05_Variables/05_Variables_A07_t07: Fail # Inherited from dart2js
-Language/05_Variables/05_Variables_A07_t08: Fail # Inherited from dart2js
-Language/05_Variables/05_Variables_A08_t01: Fail # Inherited from dart2js
-Language/05_Variables/05_Variables_A08_t02: Fail # Inherited from dart2js
 Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Fail # Inherited from VM (circular initialization?).
 Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t05: Fail # Inherited from dart2js
-Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t06: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t07: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A02_t01: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A02_t02: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # inherited from VM
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t04: Fail # http://dartbug.com/5519
 Language/06_Functions/4_External_Functions_A01_t01: Fail # inherited from VM
-Language/07_Classes/07_Classes_A02_t11: Fail # http://dartbug.com/5519
 Language/07_Classes/3_Setters_A04_t01: Fail # inherited from VM
 Language/07_Classes/3_Setters_A04_t02: Fail # inherited from VM
 Language/07_Classes/3_Setters_A04_t03: Fail # inherited from VM
@@ -35,20 +33,17 @@
 Language/07_Classes/3_Setters_A04_t06: Fail # inherited from VM
 Language/07_Classes/3_Setters_A04_t07: Fail # inherited from VM
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: Fail # http://dartbug.com/5519
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t01: Fail # inherited from VM
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t02: Fail # inherited from VM
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t03: Fail # inherited from VM
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t01: Fail # inherited from VM
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t02: Fail # inherited from VM
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t03: Fail # inherited from VM
+Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t04: Fail # Issue 13652
 Language/07_Classes/6_Constructors_A02_t01: Fail # http://dartbug.com/5519
-Language/12_Expressions/07_Maps_A12_t03: Fail # http://dartbug.com/5519
+Language/12_Expressions/01_Constants_A03_t01: Fail # Issue 13652
+Language/13_Statements/09_Switch_A02_t04: Fail # co19 issue 605
+Language/12_Expressions/00_Object_Identity/1_Object_Identity_A04_t02: Fail # co19 issue 606
+
 LibTest/core/Match/operator_subscript_A01_t01: Fail # inherited from VM
 LibTest/core/Match/operator_subscript_A01_t01: Fail, OK # co19 issue 294
 LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail # inherited from VM
 LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail, OK # co19 issue 294
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # inherited from VM
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: Fail # inherited from VM
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail
 LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # inherited from VM
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # inherited from VM
@@ -66,14 +61,11 @@
 LibTest/isolate/isolate_api/spawnUri_A01_t03: Fail, OK # Problems with the test: encoded file name
 LibTest/isolate/isolate_api/spawnUri_A01_t04: Fail, OK # Problems with the test: encoded file name
 LibTest/isolate/isolate_api/spawnUri_A01_t05: Fail, OK # Problems with the test: encoded file name
+LibTest/isolate/IsolateSink/add_A01_t01: CompileTimeError # Issue 13683
+LibTest/isolate/SendPort/send_A02_t01: CompileTimeError # Issue 13683
 LibTest/math/exp_A01_t01: Fail # Issue co19 - 44
 LibTest/math/sin_A01_t01: Fail # Inherited from VM.
 LibTest/math/tan_A01_t01: Fail # Issue co19 - 44
-LibTest/typed_data/Float32x4/toUint32x4_A01_t01: Fail # co19 Issue 601
-LibTest/typed_data/Float32x4/toUint32x4_A01_t02: Fail # co19 Issue 601
-LibTest/typed_data/Uint32x4/toFloat32x4_A01_t01: Fail # co19 Issue 601
-LibTest/typed_data/Uint32x4/toFloat32x4_A01_t02: Fail # co19 Issue 601
-LibTest/typed_data/Float32x4/clamp_A02_t01: RuntimeError # co19 Issue 600
 LibTest/typed_data/Float32x4/clamp_A01_t01: RuntimeError # co19 Issue 600
 
 
@@ -101,8 +93,6 @@
 Language/14_Libraries_and_Scripts/1_Imports_A01_t17: Fail # co19 Issue 603
 Language/14_Libraries_and_Scripts/1_Imports_A04_t01: Fail # co19 Issue 603
 
-Language/14_Libraries_and_Scripts/2_Exports_A05_t01: Fail # co19 Issue 604
-
 
 # co19-roll r546 (11.08.2013) caused these failures
 [ $compiler == dart2dart ]
@@ -124,60 +114,9 @@
 Language/07_Classes/4_Abstract_Instance_Members_A03_t04: Fail # co19-roll r559: Please triage this failure
 Language/07_Classes/6_Constructors/2_Factories_A10_t01: crash # co19-roll r587: Please triage this failure
 Language/07_Classes/6_Constructors/2_Factories_A10_t04: crash # co19-roll r587: Please triage this failure
-Language/12_Expressions/01_Constants_A03_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A03_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A03_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A03_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A05_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A05_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A05_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A08_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A09_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A10_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A10_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A11_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A11_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A11_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A12_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A12_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A13_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A13_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A13_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A13_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A14_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t06: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t07: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t08: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t09: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t10: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t11: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t12: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t13: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t14: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t15: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t16: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t17: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t18: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t20: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t21: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A15_t31: 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_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A17_t02: 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/01_Constants_A19_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A19_t03: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A19_t04: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/01_Constants_A20_t02: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/01_Constants_A20_t03: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/05_Strings/1_String_Interpolation_A01_t09: 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/06_Lists_A03_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/06_Lists_A03_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A02_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A02_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A12_t01: 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_t06: fail # co19-roll r546: Please triage this failure
@@ -190,10 +129,6 @@
 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_t12: fail # co19-roll r546: Please triage this failure
 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_A06_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/12_Instance_Creation/2_Const_A06_t02: 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_A05_t01: 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/22_Equality_A01_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/22_Equality_A01_t19: fail # co19-roll r546: Please triage this failure
@@ -201,9 +136,6 @@
 Language/12_Expressions/22_Equality_A05_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/27_Unary_Expressions_A01_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/30_Identifier_Reference_A02_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/30_Identifier_Reference_A04_t09: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/30_Identifier_Reference_A05_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/30_Identifier_Reference_A05_t12: fail # co19-roll r546: Please triage this failure
 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
@@ -221,7 +153,6 @@
 Language/14_Libraries_and_Scripts/1_Imports_A03_t08: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t09: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t10: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t27: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t28: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t29: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t30: fail # co19-roll r546: Please triage this failure
@@ -257,4 +188,4 @@
 LibTest/json/stringify_A02_t01: fail # co19-roll r587: Please triage this failure
 LibTest/json/stringify_A03_t02: fail # co19-roll r587: Please triage this failure
 LibTest/json/printOn_A02_t01: fail # co19-roll r587: Please triage this failure
-LibTest/json/printOn_A03_t02: fail # co19-roll r587: Please triage this failure
+LibTest/json/printOn_A03_t02: fail # co19-roll r587: Please triage this failure
\ No newline at end of file
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 9bc5de1..0021c0c 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -5,6 +5,7 @@
 [ $compiler == dart2js && $runtime == jsshell ]
 LibTest/isolate/isolate_api/spawnUri_A02_t01: Crash # TODO(ahe): Please triage this crash.
 LibTest/core/List/sort_A01_t04: Fail, Pass, Timeout # Must be a bug in jsshell, test sometimes times out.
+LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
 
 [ $compiler == dart2js && $checked && $runtime == ie9 ]
 LibTest/core/Uri/encodeQueryComponent_A01_t02: Pass, Timeout # co19-roll r576: Please triage this failure
@@ -21,7 +22,6 @@
 LibTest/core/double/INFINITY_A01_t04: RuntimeError # TODO(ahe): Please triage this failure.
 LibTest/core/double/NEGATIVE_INFINITY_A01_t04: RuntimeError # TODO(ahe): Please triage this failure.
 LibTest/core/List/List_A03_t01: RuntimeError # TODO(kasperl): Please triage this failure.
-LibTest/core/List/sort_A01_t04: Pass, Slow # http://dartbug.com/11846
 
 LibTest/typed_data/ByteData/getFloat32_A02_t02: fail # co19-roll r569: Please triage this failure
 LibTest/typed_data/ByteData/getFloat64_A02_t02: fail # co19-roll r569: Please triage this failure
@@ -64,7 +64,7 @@
 LibTest/isolate/isolate_api/spawnFunction_A03_t01: Fail, Pass # TODO(ahe): Please triage this failure.
 LibTest/isolate/isolate_api/spawnUri_A02_t02: Fail, Pass # TODO(ahe): Please triage this failure.
 LibTest/isolate/isolate_api/spawnUri_A02_t03: Fail, Pass # TODO(ahe): Please triage this failure.
-
+LibTest/core/Uri/Uri_A06_t03: Pass, Slow
 
 [ $compiler == dart2js ]
 
@@ -101,10 +101,11 @@
 LibTest/core/double/round_A01_t01: Fail # TODO(ngeoaffray): Please triage these failure.
 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.
 
 [ $compiler == dart2js && $checked ]
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A17_t03: Fail # TODO(ahe): Please triage this failure.
+Language/15_Types/2_Dynamic_Type_System_A01_t02: RuntimeError # co19-roll r607: Please triage this failure
+Language/15_Types/8_Parameterized_Types_A03_t07: RuntimeError # co19-roll r607: Please triage this failure
 
 
 [ $compiler == dart2js ]
@@ -127,8 +128,11 @@
 LibTest/core/int/isOdd_A01_t01: RuntimeError, OK # co19 issue 277
 LibTest/core/int/isEven_A01_t01: RuntimeError, OK # co19 issue 277
 
+Language/12_Expressions/01_Constants_A20_t03: MissingCompileTimeError # co19 Issue 611
+
 [ $compiler == dart2js ]
-LibTest/isolate/SendPort/send_A02_t01: CompileTimeError # Compile-time error: error: not a compile-time constant
+LibTest/isolate/IsolateSink/add_A01_t01: CompileTimeError # Issue 13683
+LibTest/isolate/SendPort/send_A02_t01: CompileTimeError # Issue 13683
 
 LibTest/isolate/isolate_api/spawnUri_A02_t01: RuntimeError # Runtime error: Expect.throws() fails
 LibTest/isolate/isolate_api/spawnUri_A01_t01: RuntimeError # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
@@ -223,19 +227,10 @@
 LibTest/typed_data/ByteData/setUint8_A02_t02: fail # Issue 12989
 LibTest/typed_data/ByteData/setUint8_A02_t02: fail # Issue 12989
 
-LibTest/typed_data/Float32x4/toUint32x4_A01_t01: RuntimeError # co19 Issue 601
-LibTest/typed_data/Float32x4/toUint32x4_A01_t02: RuntimeError # co19 Issue 601
-LibTest/typed_data/Uint32x4/toFloat32x4_A01_t01: RuntimeError # co19 Issue 601
-LibTest/typed_data/Uint32x4/toFloat32x4_A01_t02: RuntimeError # co19 Issue 601
-LibTest/typed_data/Float32x4/clamp_A02_t01: RuntimeError # co19 Issue 600
-
 Language/14_Libraries_and_Scripts/1_Imports_A01_t17: Fail # co19 Issue 603
 Language/14_Libraries_and_Scripts/1_Imports_A04_t01: Fail # co19 Issue 603
 
-Language/14_Libraries_and_Scripts/2_Exports_A05_t01: Fail # co19 Issue 604
-
 [ $compiler == dart2js && $jscl ]
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: Fail, Pass # issue 3333
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail, Pass # issue 3333
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError, OK # This is not rejected by V8.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A04_t01: RuntimeError, OK # co19 issue 92.
@@ -254,6 +249,10 @@
 LibTest/core/int/toRadixString_A01_t01: RuntimeError, OK # Bad test: uses Expect.fail, Expect.throws, assumes case of result, and uses unsupported radixes.
 
 [ $compiler == dart2js && $runtime == ie9 ]
+Language/12_Expressions/00_Object_Identity/1_Object_Identity_A05_t02: RuntimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/02_Null_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t02: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/add_A01_t01: Pass, Timeout  # co19-roll r607: Please triage this failure
 LibTest/core/Uri/Uri_A06_t03: Pass, Timeout # Issue 13511
 LibTest/math/cos_A01_t01: Fail # co19 issue 44
 
@@ -314,21 +313,7 @@
 # Missing compile-time errors.
 #
 [ $compiler == dart2js ]
-Language/05_Variables/05_Variables_A07_t07: MissingCompileTimeError # Checks that a compile-time error occurs if a global constant variable is not initialized at declaration.
-Language/05_Variables/05_Variables_A07_t08: MissingCompileTimeError # Checks that a compile-time error occurs if a global typed constant variable is not initialized at declaration.
-Language/05_Variables/05_Variables_A08_t01: MissingCompileTimeError # Checks that a compile-time error occurs if a constant variable is not initialized.
-Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t06: MissingCompileTimeError # Checks that a functionSignature parameter cannot be final.
-Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t07: MissingCompileTimeError # Checks that a functionSignature parameter cannot be declared as variable.
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: MissingCompileTimeError # TODO(ahe): Enforce optional parameter semantics.
-Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t04: MissingCompileTimeError # TODO(ahe): Enforce optional parameter semantics.
-Language/07_Classes/07_Classes_A02_t11: MissingCompileTimeError # Checks that it is a compile-time error if a static final variable declaration does not include explicit initializer.
-Language/12_Expressions/01_Constants_A20_t03: MissingCompileTimeError # Checks that an identifier expression that denotes a type parameter  can not be assigned to a constant variable.
 Language/12_Expressions/05_Strings/1_String_Interpolation_A01_t09: MissingCompileTimeError # Checks that it is a compile-time error if a string interpolation construct does not start with IDENTIFIER_NO_DOLLAR or opening brace.
-Language/12_Expressions/05_Strings_A02_t46: MissingCompileTimeError # Checks that multi-line strings that contain characters and sequences prohibited by this grammar, cause compile-time errors.
-Language/12_Expressions/05_Strings_A02_t48: MissingCompileTimeError # Checks that multi-line strings that contain characters and sequences prohibited by this grammar, cause compile-time errors.
-Language/12_Expressions/30_Identifier_Reference_A04_t09: MissingCompileTimeError # Checks that it is a compile-time error when a built-in identifier dynamic is used as the declared name of a type variable.
-Language/12_Expressions/30_Identifier_Reference_A05_t01: MissingCompileTimeError # Checks that it is a compile-time error when a built-in identifier "abstract" is used as a type annotation of a local variable.
-Language/12_Expressions/30_Identifier_Reference_A05_t12: MissingCompileTimeError # Checks that it is a compile-time error when a built-in identifier "static" is used as a type annotation of a local variable.
 Language/16_Reference/1_Lexical_Rules/1_Reserved_Words_A40_t04: MissingCompileTimeError # Checks that other Unicode whitespaces are not allowed:  check NO-BREAK SPACE (U+00A0)
 Language/16_Reference/1_Lexical_Rules_A02_t06: MissingCompileTimeError # Checks that Unicode whitespaces other than WHITESPACE are not permitted in the source code. Checks symbol U+00a0.
 
@@ -345,6 +330,9 @@
 Language/07_Classes/3_Setters_A04_t06: CompileTimeError # http://dartbug.com/5023
 Language/07_Classes/3_Setters_A04_t07: CompileTimeError # http://dartbug.com/5023
 
+Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t04: CompileTimeError # Issue 13652
+Language/12_Expressions/01_Constants_A03_t01: CompileTimeError # Issue 13652
+
 
 [ $compiler == dart2js && $runtime == ie9 ]
 # These are most likey due to the fact that IE9 doesn't support typed data
@@ -414,7 +402,6 @@
 LibTest/typed_data/ByteData/setUint8_A01_t01: fail # co19-roll r569: Please triage this failure
 LibTest/typed_data/ByteData/toString_A01_t01: fail # co19-roll r569: Please triage this failure
 
-
 [ $compiler == dart2js ]
 Language/03_Overview/1_Scoping_A02_t28: fail # co19-roll r559: Please triage this failure
 Language/05_Variables/05_Variables_A05_t01: fail # co19-roll r546: Please triage this failure
@@ -427,8 +414,6 @@
 Language/07_Classes/4_Abstract_Instance_Members_A03_t04: fail # co19-roll r559: Please triage this failure
 Language/12_Expressions/00_Object_Identity/1_Object_Identity_A02_t02: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/00_Object_Identity/1_Object_Identity_A06_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A06_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/01_Constants_A03_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/03_Numbers_A01_t06: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/03_Numbers_A01_t09: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/05_Strings_A20_t01: fail # co19-roll r546: Please triage this failure
@@ -459,7 +444,6 @@
 Language/14_Libraries_and_Scripts/1_Imports_A03_t08: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t09: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t10: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t27: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t28: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t29: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t30: fail # co19-roll r546: Please triage this failure
@@ -484,7 +468,6 @@
 LibTest/isolate/isolate_api/spawnUri_A02_t02: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/isolate_api/spawnUri_A02_t03: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/isolate_api/streamSpawnFunction_A02_t02: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateSink/add_A01_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
@@ -532,6 +515,7 @@
 LibTest/typed_data/Uint8List/Uint8List.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint8List/Uint8List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
 Utils/tests/Expect/identical_A01_t01: fail # co19-roll r546: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t05: CompileTimeError # co19-roll r607: Please triage this failure
 
 [ $compiler == dart2js && $checked ]
 Language/10_Generics/09_Generics_A03_t01: fail # co19-roll r546: Please triage this failure
@@ -540,7 +524,6 @@
 Language/12_Expressions/06_Lists_A09_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/06_Lists_A09_t04: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/07_Maps_A10_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A11_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/12_Instance_Creation/1_New_A07_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/12_Instance_Creation/1_New_A12_t02: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/12_Instance_Creation/2_Const_A09_t02: Fail # co19-roll r559: Please triage this failure
@@ -595,6 +578,9 @@
 LibTest/async/Timer/Timer_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/typed_data/Float32x4List/Float32x4List.view_A01_t02: fail # co19-roll r587: Please triage this failure
 LibTest/typed_data/Float32x4List/Float32x4List.view_A06_t01: fail # co19-roll r587: Please triage this failure
+Language/12_Expressions/00_Object_Identity/1_Object_Identity_A05_t02: RuntimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/02_Null_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/17_Getter_Invocation_A07_t02: RuntimeError # co19-roll r607: Please triage this failure
 
 [ $compiler == dart2js && $minified ]
 Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: fail # co19-roll r559: Please triage this failure
@@ -627,10 +613,12 @@
 Language/07_Classes/6_Constructors/2_Factories_A10_t02: fail # co19-roll r587: Please triage this failure
 Language/07_Classes/6_Constructors/2_Factories_A10_t03: fail # co19-roll r587: Please triage this failure
 Language/10_Generics/09_Generics_A01_t17: fail # co19-roll r587: Please triage this failure
+Language/15_Types/5_Function_Types_A07_t01: CompileTimeError # co19-roll r607: Please triage this failure
+Language/15_Types/5_Function_Types_A07_t01: CompileTimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t02: CompileTimeError # co19-roll r607: Please triage this failure
+Language/12_Expressions/07_Maps_A13_t01: MissingCompileTimeError # co19-roll r607: Please triage this failure
 
 [ $compiler == dart2js ]
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t04: fail # co19-roll r587: Please triage this failure
-Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t04: fail # co19-roll r587: Please triage this failure
 LibTest/json/stringify_A01_t01: fail # co19-roll r587: Please triage this failure
 LibTest/json/stringify_A02_t01: fail # co19-roll r587: Please triage this failure
 LibTest/json/printOn_A01_t01: fail # co19-roll r587: Please triage this failure
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
new file mode 100644
index 0000000..471d509
--- /dev/null
+++ b/tests/co19/co19-dartium.status
@@ -0,0 +1,117 @@
+# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+[ $compiler == none && $runtime == dartium ]
+Language/03_Overview/2_Privacy_A01_t06: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A05_t01: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A05_t02: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A06_t01: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A06_t02: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A06_t03: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A06_t04: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A06_t05: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A06_t06: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/05_Variables_A16_t02: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Fail # Issue 13719: Please triage this failure.
+Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t05: Fail # Issue 13719: Please triage this failure.
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: Fail # Issue 13719: Please triage this failure.
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: Fail # Issue 13719: Please triage this failure.
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: Fail # Issue 13719: Please triage this failure.
+Language/09_Mixins/1_Mixin_Application_A01_t01: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/00_Object_Identity/1_Object_Identity_A04_t02: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/01_Constants_A16_t01: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/01_Constants_A16_t02: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/01_Constants_A16_t04: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/01_Constants_A16_t05: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/12_Instance_Creation/1_New_A09_t09: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/12_Instance_Creation/2_Const_A10_t01: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t03: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t09: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/18_Assignment_A01_t07: Fail  # co19-roll r607: Please triage this failure
+Language/12_Expressions/18_Assignment_A04_t09: Fail # co19-roll r607: Please triage this failure
+Language/12_Expressions/30_Identifier_Reference_A08_t02: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/32_Type_Test_A04_t02: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/32_Type_Test_A04_t03: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/32_Type_Test_A04_t04: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/33_Type_Cast_A03_t02: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/33_Type_Cast_A03_t03: Fail # Issue 13719: Please triage this failure.
+Language/13_Statements/02_Expression_Statements_A01_t13: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/03_Variable_Declaration_A04_t01: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/03_Variable_Declaration_A04_t02: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/03_Variable_Declaration_A04_t05: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/03_Variable_Declaration_A04_t06: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/03_Variable_Declaration_A04_t07: Fail # Issue 13719: Please triage this failure.
+Language/13_Statements/03_Variable_Declaration_A04_t08: Fail # Issue 13719: Please triage this failure.
+Language/13_Statements/04_Local_Function_Declaration_A04_t01: Fail # co19-roll r607: Please triage this failure
+Language/13_Statements/06_For_A01_t11: Fail # Issue 13719: Please triage this failure.
+Language/13_Statements/09_Switch_A01_t02: Fail # Issue 13719: Please triage this failure.
+Language/13_Statements/09_Switch_A02_t04: Fail # Issue 13719: Please triage this failure.
+Language/13_Statements/12_Labels_A01_t03: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/2_Exports_A04_t02: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/2_Exports_A04_t03: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/4_Scripts_A03_t02: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/5_URIs_A01_t04: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/5_URIs_A01_t05: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/5_URIs_A01_t14: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/5_URIs_A01_t15: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/5_URIs_A01_t24: Fail # Issue 13719: Please triage this failure.
+Language/14_Libraries_and_Scripts/5_URIs_A01_t25: Fail # Issue 13719: Please triage this failure.
+Language/15_Types/1_Static_Types_A03_t01: Fail # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t08: Fail # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t09: Fail # co19-roll r607: Please triage this failure
+LibTest/async/Completer/completeError_A02_t01: Pass, Fail # Issue 13719: Please triage this failure.
+LibTest/async/Stream/Stream.periodic_A01_t01: Timeout # Issue 13719: Please triage this failure.
+LibTest/collection/HasNextIterator/HasNextIterator_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedHashSet/LinkedHashSet.from_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/first_A01_t02: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/forEach_A02_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/LinkedList_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/reduce_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/DateTime/parse_A03_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/double/ceil_A01_t03: Fail # Issue 13719: Please triage this failure.
+LibTest/core/double/ceil_A01_t04: Fail # Issue 13719: Please triage this failure.
+LibTest/core/double/floor_A01_t03: Fail # Issue 13719: Please triage this failure.
+LibTest/core/double/floor_A01_t04: Fail # Issue 13719: Please triage this failure.
+LibTest/core/double/round_A01_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/core/double/round_A01_t04: Fail # Issue 13719: Please triage this failure.
+LibTest/core/int/toRadixString_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/Invocation/namedArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/positionalArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Match/operator_subscript_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/firstMatch_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A03_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Runes/lastWhere_A02_t01: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t03: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t04: Fail # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t05: Fail # co19-roll r607: Please triage this failure
+LibTest/isolate/isolate_api/spawnFunction_A04_t01: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnFunction_A04_t02: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnFunction_A04_t03: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A01_t01: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A01_t02: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A01_t03: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A01_t04: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A01_t05: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A02_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/spawnUri_A02_t03: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/streamSpawnFunction_A02_t01: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/isolate_api/streamSpawnFunction_A02_t02: Timeout # Issue 13719: Please triage this failure.
+LibTest/isolate/IsolateSink/addError_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/IsolateSink/addError_A01_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/IsolateStream/any_A02_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/ReceivePort/receive_A01_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/SendPort/send_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/typed_data/ByteData/elementSizeInBytes_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/typed_data/Float32x4/clamp_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/typed_data/Int8List/Int8List.fromList_A01_t02: Fail # Issue 13719: Please triage this failure.
\ No newline at end of file
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 719fc5d..6796d88 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -2,13 +2,13 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $runtime == vm ]
+[ $compiler == none && $runtime == vm ]
 Language/12_Expressions/01_Constants_A16_t04: fail # Issue 392
 Language/12_Expressions/01_Constants_A16_t05: fail # Issue 392
-
-[ $runtime == vm && $system == windows ]
-LibTest/core/Stopwatch/elapsed_A01_t01: Pass, Fail # Issue 11382.
-LibTest/core/Stopwatch/elapsed_A01_t03: Pass, Fail # Issue 12383.
+Language/13_Statements/03_Variable_Declaration_A04_t01: MissingCompileTimeError # Issue 7052
+Language/13_Statements/03_Variable_Declaration_A04_t02: MissingCompileTimeError # Issue 7052
+Language/13_Statements/03_Variable_Declaration_A04_t05: MissingCompileTimeError # Issue 7052
+Language/13_Statements/03_Variable_Declaration_A04_t06: MissingCompileTimeError # Issue 7052
 
 [ $compiler == none && $runtime == vm ]
 Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Fail # Dart issue 5802
@@ -18,7 +18,6 @@
 LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail # Issue 12508
 LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # Issue 12508
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # Issue 12508
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: Fail # Issue 12508
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 12508
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail # Issue 12508
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 12508
@@ -70,12 +69,10 @@
 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/6_Constructors/1_Generative_Constructors_A09_t01: fail # Dart issue 12543
-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/00_Object_Identity/1_Object_Identity_A04_t02: fail # co19 issue 606
 Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: fail # Dart issue 12549
 Language/12_Expressions/12_Instance_Creation/1_New_A09_t09: fail # Dart issue 1372
 Language/12_Expressions/12_Instance_Creation/2_Const_A10_t01: fail # co19 issue 525
-Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A05_t01: fail # Dart issue 12550
 Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t09: fail # Dart issue 12549
 Language/12_Expressions/30_Identifier_Reference_A08_t02: fail # Dart issue 12593
 Language/12_Expressions/32_Type_Test_A04_t02: fail # co19 issue 503
@@ -86,12 +83,11 @@
 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_A02_t04: fail # co19 issue 605
 Language/13_Statements/09_Switch_A01_t02: fail # Dart issue 12908
 Language/13_Statements/12_Labels_A01_t03: fail # Dart issue 2238
-Language/14_Libraries_and_Scripts/1_Imports_A03_t27: fail # Dart issue 12915
 Language/14_Libraries_and_Scripts/2_Exports_A04_t02: fail # Dart issue 12916
 Language/14_Libraries_and_Scripts/2_Exports_A04_t03: fail # Dart issue 12916
-Language/14_Libraries_and_Scripts/2_Exports_A05_t01: fail # Dart issue 12918
 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_t14: fail # Issue 12521
@@ -136,6 +132,7 @@
 LibTest/typed_data/Float32x4List/skip_A01_t01: Fail # Dart issue 12861
 LibTest/typed_data/Float32x4List/take_A01_t01: Fail # Dart issue 12861
 LibTest/typed_data/Float32x4List/take_A02_t01: Fail # Dart issue 12861
+Language/12_Expressions/12_Instance_Creation_A01_t08: CompileTimeError # co19-roll r607: Please triage this failure
 
 [ $compiler == none && $runtime == vm && $system == windows && $mode == debug ]
 Language/15_Types/4_Interface_Types_A11_t01: pass, timeout # Issue 13349
@@ -146,8 +143,15 @@
 LibTest/typed_data/Float32x4/clamp_A02_t01: Pass, Fail # Issue 13543
 LibTest/typed_data/Float32x4/reciprocalSqrt_A01_t01: Pass, Fail # Issue 13543
 LibTest/typed_data/Float32x4/reciprocal_A01_t01: Pass, Fail # Issue 13543
-LibTest/typed_data/Float32x4/toUint32x4_A01_t01: Fail # co19 Issue 601
-LibTest/typed_data/Float32x4/toUint32x4_A01_t02: Fail # co19 Issue 601
-LibTest/typed_data/Uint32x4/toFloat32x4_A01_t01: Fail # co19 Issue 601
-LibTest/typed_data/Uint32x4/toFloat32x4_A01_t02: Fail # co19 Issue 601
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t08: MissingCompileTimeError # co19-roll r607: Please triage this failure
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t09: MissingCompileTimeError # co19-roll r607: Please triage this failure
+LibTest/core/Invocation/positionalArguments_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # co19-roll r607: Please triage this failure
+
+[ $compiler == none && $runtime == vm && $mode == debug && $checked ]
+LibTest/collection/LinkedList/add_A01_t01: Pass, Crash # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/iterator_current_A01_t01: Pass, Crash # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/single_A01_t01: Pass, Crash # co19-roll r607: Please triage this failure
 
diff --git a/tests/co19/test_config.dart b/tests/co19/test_config.dart
index 547ea88..d37b5fa 100644
--- a/tests/co19/test_config.dart
+++ b/tests/co19/test_config.dart
@@ -20,7 +20,8 @@
                "tests/co19/co19-analyzer2.status",
                "tests/co19/co19-runtime.status",
                "tests/co19/co19-dart2dart.status",
-               "tests/co19/co19-dart2js.status"]);
+               "tests/co19/co19-dart2js.status",
+               "tests/co19/co19-dartium.status"]);
 
   bool isTestFile(String filename) => _testRegExp.hasMatch(filename);
   bool get listRecursively => true;
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index 8af47af..3e76675 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -148,14 +148,13 @@
     element = compiler.coreLibrary.find(sourceName);
   }
   Expect.isNotNull(element, 'Could not locate $name');
-  var dartType = element.computeType(compiler);
   switch (how) {
-    case 'exact': return new types.TypeMask.exact(dartType);
-    case 'nonNullExact': return new types.TypeMask.nonNullExact(dartType);
-    case 'subclass': return new types.TypeMask.subclass(dartType);
-    case 'nonNullSubclass': return new types.TypeMask.nonNullSubclass(dartType);
-    case 'subtype': return new types.TypeMask.subtype(dartType);
-    case 'nonNullSubtype': return new types.TypeMask.nonNullSubtype(dartType);
+    case 'exact': return new types.TypeMask.exact(element);
+    case 'nonNullExact': return new types.TypeMask.nonNullExact(element);
+    case 'subclass': return new types.TypeMask.subclass(element);
+    case 'nonNullSubclass': return new types.TypeMask.nonNullSubclass(element);
+    case 'subtype': return new types.TypeMask.subtype(element);
+    case 'nonNullSubtype': return new types.TypeMask.nonNullSubtype(element);
   }
   Expect.fail('Unknown HType constructor $how');
 }
diff --git a/tests/compiler/dart2js/cpa_inference_test.dart b/tests/compiler/dart2js/cpa_inference_test.dart
index ab3b4be..044d9f3 100644
--- a/tests/compiler/dart2js/cpa_inference_test.dart
+++ b/tests/compiler/dart2js/cpa_inference_test.dart
@@ -1375,7 +1375,7 @@
 
     final String source2 = r"""
       import 'dart:foreign';
-  
+
       main () {
         var x = "__dynamic_for_test".truncate();
         JS('double', 'foo');
@@ -1480,24 +1480,24 @@
 
     for (ClassElement cls in [a, b, c, d]) {
       Expect.equals(convert(singleton(cls)),
-                    new TypeMask.nonNullExact(cls.rawType));
+                    new TypeMask.nonNullExact(cls));
     }
 
     for (ClassElement cls in [a, b, c, d]) {
       Expect.equals(convert(singleton(cls).union(nullSingleton)),
-                    new TypeMask.exact(cls.rawType));
+                    new TypeMask.exact(cls));
     }
 
     Expect.equals(convert(singleton(a).union(singleton(b))),
-                  new TypeMask.nonNullSubclass(a.rawType));
+                  new TypeMask.nonNullSubclass(a));
 
     Expect.equals(
         convert(singleton(a).union(singleton(b)).union(nullSingleton)),
-                  new TypeMask.subclass(a.rawType));
+                  new TypeMask.subclass(a));
 
     Expect.equals(
         convert(singleton(b).union(singleton(d))).simplify(result.compiler),
-        new TypeMask.nonNullSubtype(a.rawType));
+        new TypeMask.nonNullSubtype(a));
   });
 }
 
@@ -1545,20 +1545,20 @@
 
     Expect.equals(
         inferredType(foo).simplify(result.compiler),
-        new TypeMask.nonNullSubclass(abc.rawType));
+        new TypeMask.nonNullSubclass(abc));
     Expect.equals(
-        inferredType(new TypedSelector.subclass(x.rawType, foo)),
-        new TypeMask.nonNullExact(b.rawType));
+        inferredType(new TypedSelector.subclass(x, foo)),
+        new TypeMask.nonNullExact(b));
     Expect.equals(
-        inferredType(new TypedSelector.subclass(y.rawType, foo)),
-        new TypeMask.nonNullExact(c.rawType));
+        inferredType(new TypedSelector.subclass(y, foo)),
+        new TypeMask.nonNullExact(c));
     Expect.equals(
-        inferredType(new TypedSelector.subclass(z.rawType, foo)),
-        new TypeMask.nonNullExact(a.rawType));
+        inferredType(new TypedSelector.subclass(z, foo)),
+        new TypeMask.nonNullExact(a));
     Expect.equals(
         inferredType(new TypedSelector.subclass(
-            xy.rawType, foo)).simplify(result.compiler),
-        new TypeMask.nonNullSubclass(bc.rawType));
+            xy, foo)).simplify(result.compiler),
+        new TypeMask.nonNullSubclass(bc));
 
     Selector bar = new Selector.call(buildSourceString("bar"), null, 0);
 
diff --git a/tests/compiler/dart2js/dart_backend_test.dart b/tests/compiler/dart2js/dart_backend_test.dart
index 508010c..5469890 100644
--- a/tests/compiler/dart2js/dart_backend_test.dart
+++ b/tests/compiler/dart2js/dart_backend_test.dart
@@ -269,14 +269,14 @@
       'var globalVarInitialized=6,globalVarInitialized2=7;'
       'class A{A(){}A.fromFoo(){}static staticfoo(){}foo(){}'
           'static const field=5;}'
-      'p_globalfoo(){}'
-      'var p_globalVar;var p_globalVarInitialized=6,p_globalVarInitialized2=7;'
-      'class p_A{p_A(){}p_A.p_fromFoo(){}static p_staticfoo(){}foo(){}'
-          'static const p_field=5;}'
-      'main(){p_globalVar;p_globalVarInitialized;'
-         'p_globalVarInitialized2;p_globalfoo();'
-         'p_A.p_field;p_A.p_staticfoo();'
-         'new p_A();new p_A.p_fromFoo();new p_A().foo();'
+      'A_globalfoo(){}'
+      'var A_globalVar;var A_globalVarInitialized=6,A_globalVarInitialized2=7;'
+      'class A_A{A_A(){}A_A.A_fromFoo(){}static A_staticfoo(){}foo(){}'
+          'static const A_field=5;}'
+      'main(){A_globalVar;A_globalVarInitialized;'
+         'A_globalVarInitialized2;A_globalfoo();'
+         'A_A.A_field;A_A.A_staticfoo();'
+         'new A_A();new A_A.A_fromFoo();new A_A().foo();'
          'globalVar;globalVarInitialized;globalVarInitialized2;globalfoo();'
          'A.field;A.staticfoo();'
          'new A();new A.fromFoo();new A().foo();}';
@@ -383,11 +383,11 @@
   var expectedResult =
     'topfoo(){}'
     'class A{foo(){}}'
-    'p_topfoo(){var x=5;}'
-    'class p_A{num foo(){}p_A.fromFoo(){}A myliba;List<p_A> mylist;}'
+    'A_topfoo(){var x=5;}'
+    'class A_A{num foo(){}A_A.fromFoo(){}A myliba;List<A_A> mylist;}'
     'A getA()=>null;'
-    'main(){var a=new A();a.foo();var b=new p_A.fromFoo();b.foo();'
-        'var GREATVAR=b.myliba;b.mylist;a=getA();p_topfoo();topfoo();}';
+    'main(){var a=new A();a.foo();var b=new A_A.fromFoo();b.foo();'
+        'var GREATVAR=b.myliba;b.mylist;a=getA();A_topfoo();topfoo();}';
   testDart2DartWithLibrary(mainSrc, librarySrc,
       continuation: (String result) { Expect.equals(expectedResult, result); });
 }
@@ -426,9 +426,9 @@
   var expectedResult =
     'get topgetset=>5;'
     'set topgetset(arg){}'
-    'get p_topgetset=>6;'
-    'set p_topgetset(arg){}'
-    'main(){p_topgetset;p_topgetset=6;topgetset;topgetset=5;}';
+    'get A_topgetset=>6;'
+    'set A_topgetset(arg){}'
+    'main(){A_topgetset;A_topgetset=6;topgetset;topgetset=5;}';
   testDart2DartWithLibrary(mainSrc, librarySrc,
       continuation: (String result) { Expect.equals(expectedResult, result); });
 }
@@ -504,12 +504,12 @@
     'class T{}'
     'class B<T>{}'
     'class A<T> extends B<T>{T f;}'
-    'typedef void p_MyFunction<p_T extends num>(p_T arg);'
-    'class p_T{}'
-    'class p_B<p_T>{}'
-    'class p_A<p_T> extends p_B<p_T>{p_T f;}'
-    'main(){p_MyFunction myf1;MyFunction myf2;new p_A<int>().f;'
-        'new p_T();new A<int>().f;new T();}';
+    'typedef void A_MyFunction<A_T extends num>(A_T arg);'
+    'class A_T{}'
+    'class A_B<A_T>{}'
+    'class A_A<A_T> extends A_B<A_T>{A_T f;}'
+    'main(){A_MyFunction myf1;MyFunction myf2;new A_A<int>().f;'
+        'new A_T();new A<int>().f;new T();}';
   testDart2DartWithLibrary(mainSrc, librarySrc,
       continuation: (String result) { Expect.equals(expectedResult, result); });
 }
@@ -536,9 +536,9 @@
   var expectedResult =
     'class I{}'
     'class A<T extends I>{}'
-    'class p_I{}'
-    'class p_A<p_T extends p_I>{}'
-    'main(){new p_A();new A();}';
+    'class A_I{}'
+    'class A_A<A_T extends A_I>{}'
+    'main(){new A_A();new A();}';
   testDart2DartWithLibrary(mainSrc, librarySrc,
       continuation: (String result) { Expect.equals(expectedResult, result); });
 }
@@ -555,8 +555,8 @@
 }
 ''';
   var expectedResult =
-    'p_main(){}'
-    'main(){p_main();}';
+    'A_main(){}'
+    'main(){A_main();}';
   testDart2DartWithLibrary(mainSrc, librarySrc,
       continuation: (String result) { Expect.equals(expectedResult, result); });
 }
@@ -667,8 +667,8 @@
 }
 ''';
   var expectedResult = 'import "dart:html" as p;'
-      'class A{static String get p_userAgent=>p.window.navigator.userAgent;}'
-      'main(){A.p_userAgent;}';
+      'class A{static String get A_userAgent=>p.window.navigator.userAgent;}'
+      'main(){A.A_userAgent;}';
   testDart2Dart(src,
       continuation: (String result) { Expect.equals(expectedResult, result); });
 }
@@ -684,8 +684,8 @@
   print('local');
 }
 ''';
-  var expectedResult = "p_print(x){throw 'fisk';}"
-      "main(){print('corelib');p_print('local');}";
+  var expectedResult = "A_print(x){throw 'fisk';}"
+      "main(){print('corelib');A_print('local');}";
   testDart2Dart(src,
       continuation: (String result) { Expect.equals(expectedResult, result); });
 }
@@ -701,7 +701,7 @@
   new A.named();
 }
 ''';
-  var expectedResult = "class A{A(){}}main(){new A();new p_Unresolved();}";
+  var expectedResult = "class A{A(){}}main(){new A();new A_Unresolved();}";
   testDart2Dart(src,
       continuation: (String result) { Expect.equals(expectedResult, result); });
 }
diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
index 4aee0ac..7961fe6 100644
--- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -515,7 +515,7 @@
   runTest(TEST_15, {'f': (compiler) {
                             ClassElement cls =
                                 compiler.typesTask.compiler.backend.jsIndexableClass;
-                            return new TypeMask.nonNullSubtype(cls.rawType);
+                            return new TypeMask.nonNullSubtype(cls);
                          }});
   runTest(TEST_16, {'f': subclassOfInterceptor});
   runTest(TEST_17, {'f': (compiler) => compiler.typesTask.intType.nullable()});
diff --git a/tests/compiler/dart2js/licm_test.dart b/tests/compiler/dart2js/licm_test.dart
index 0b16cba..3e1a98a 100644
--- a/tests/compiler/dart2js/licm_test.dart
+++ b/tests/compiler/dart2js/licm_test.dart
@@ -25,6 +25,6 @@
 ''';
 
 main() {
-  compileAndMatch(
-      TEST, 'main', new RegExp("if \\(count == null\\)(.|\\n)*while"));
+  compileAndMatch(TEST, 'main',
+      new RegExp('if \\(typeof count !== "number"\\)(.|\\n)*while'));
 }
diff --git a/tests/compiler/dart2js/list_tracer_node_type_test.dart b/tests/compiler/dart2js/list_tracer_node_type_test.dart
index dfefd9b..4296d74 100644
--- a/tests/compiler/dart2js/list_tracer_node_type_test.dart
+++ b/tests/compiler/dart2js/list_tracer_node_type_test.dart
@@ -68,26 +68,19 @@
 
 main() {
   asyncTest(() => compileAll(TEST1).then((generated) {
-    // Check that we only do a null check on the receiver for
-    // [: a[0] + 42 :]. We can do a null check because we inferred that
-    // the list is of type int or null.
-    Expect.isFalse(generated.contains('if (typeof t1'));
-    Expect.isTrue(generated.contains('if (t1 == null)'));
+    Expect.isTrue(generated.contains('if (typeof t1'));
   }));
 
   asyncTest(() => compileAll(TEST2).then((generated) {
-    Expect.isFalse(generated.contains('if (typeof t1'));
-    Expect.isTrue(generated.contains('if (t1 == null)'));
+    Expect.isTrue(generated.contains('if (typeof t1'));
   }));
 
   asyncTest(() => compileAll(TEST3).then((generated) {
-    Expect.isFalse(generated.contains('if (typeof t1'));
-    Expect.isTrue(generated.contains('if (t1 == null)'));
+    Expect.isTrue(generated.contains('if (typeof t1'));
   }));
 
   asyncTest(() => compileAll(TEST4).then((generated) {
-    Expect.isFalse(generated.contains('if (typeof t1'));
-    Expect.isTrue(generated.contains('if (t1 == null)'));
+    Expect.isTrue(generated.contains('if (typeof t1'));
   }));
 
   asyncTest(() => compileAll(TEST5).then((generated) {
diff --git a/tests/compiler/dart2js/list_tracer_test.dart b/tests/compiler/dart2js/list_tracer_test.dart
index 936dd17..5668c63 100644
--- a/tests/compiler/dart2js/list_tracer_test.dart
+++ b/tests/compiler/dart2js/list_tracer_test.dart
@@ -222,12 +222,13 @@
     checkType('listPassedToClosure', typesTask.dynamicType);
     checkType('listReturnedFromClosure', typesTask.dynamicType);
     checkType('listUsedWithNonOkSelector', typesTask.dynamicType);
-    checkType('listPassedAsOptionalParameter', typesTask.dynamicType);
-    checkType('listPassedAsNamedParameter', typesTask.dynamicType);
+    checkType('listPassedAsOptionalParameter', typesTask.numType);
+    checkType('listPassedAsNamedParameter', typesTask.numType);
 
     if (!allocation.contains('filled')) {
       checkType('listUnset', new TypeMask.nonNullEmpty());
-      checkType('listOnlySetWithConstraint', new TypeMask.nonNullEmpty());
+      // TODO(ngeoffray): Re-enable this test.
+      // checkType('listOnlySetWithConstraint', new TypeMask.nonNullEmpty());
     }
   }));
 }
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index 065da51..1f25936 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -92,20 +92,14 @@
       });
     }
 
-    // There should at least be three metadata constants:
-    // 1. The type literal 'Foo'.
-    // 2. The list 'const [Foo]'.
-    // 3. The constructed constant for 'MirrorsUsed'.
-    Expect.isTrue(compiler.metadataHandler.compiledConstants.length >= 3);
+    // There should at least be one metadata constant:
+    // 1. The constructed constant for 'MirrorsUsed'.
+    Expect.isTrue(compiler.backend.metadataConstants.length >= 1);
 
     // Make sure that most of the metadata constants aren't included in the
     // generated code.
-    for (Constant constant in compiler.metadataHandler.compiledConstants) {
-      if (constant is TypeConstant && '${constant.representedType}' == 'Foo') {
-        // The type literal 'Foo' is retained as a constant because it is being
-        // passed to reflectClass.
-        continue;
-      }
+    for (var dependency in compiler.backend.metadataConstants) {
+      Constant constant = dependency.constant;
       Expect.isFalse(
           compiler.constantHandler.compiledConstants.contains(constant),
           '$constant');
@@ -114,7 +108,7 @@
     // The type literal 'Foo' is both used as metadata, and as a plain value in
     // the program. Make sure that it isn't duplicated.
     int fooConstantCount = 0;
-    for (Constant constant in compiler.metadataHandler.compiledConstants) {
+    for (Constant constant in compiler.constantHandler.compiledConstants) {
       if (constant is TypeConstant && '${constant.representedType}' == 'Foo') {
         fooConstantCount++;
       }
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 5fb2d85..73eea5c 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -250,6 +250,7 @@
     // Set up the library imports.
     importHelperLibrary(coreLibrary);
     libraryLoader.importLibrary(jsHelperLibrary, coreLibrary, null);
+    libraryLoader.importLibrary(foreignLibrary, coreLibrary, null);
     libraryLoader.importLibrary(interceptorsLibrary, coreLibrary, null);
     libraryLoader.importLibrary(isolateHelperLibrary, coreLibrary, null);
 
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 9881810..34bf187 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -730,7 +730,7 @@
     // typed selector.
     var selector = new Selector.call(
         buildSourceString('method'), compiler.coreLibrary, 0);
-    var typedSelector = new TypedSelector.exact(cls.rawType, selector);
+    var typedSelector = new TypedSelector.exact(cls, selector);
     Element method =
         cls.implementation.lookupLocalMember(buildSourceString('method'));
     Expect.isTrue(selector.applies(method, compiler));
@@ -740,7 +740,7 @@
     // for a typed selector.
     selector = new Selector.call(
         buildSourceString('clear'), compiler.coreLibrary, 0);
-    typedSelector = new TypedSelector.exact(cls.rawType, selector);
+    typedSelector = new TypedSelector.exact(cls, selector);
     method = cls.lookupLocalMember(buildSourceString('clear'));
     Expect.isTrue(selector.applies(method, compiler));
     Expect.isTrue(typedSelector.applies(method, compiler));
@@ -749,7 +749,7 @@
     // for a typed selector on a subclass.
     cls = ensure(compiler, "B", compiler.coreLibrary.find);
     cls.ensureResolved(compiler);
-    typedSelector = new TypedSelector.exact(cls.rawType, selector);
+    typedSelector = new TypedSelector.exact(cls, selector);
     Expect.isTrue(selector.applies(method, compiler));
     Expect.isTrue(typedSelector.applies(method, compiler));
   }));
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
index a8093aa..4746044 100644
--- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
@@ -145,6 +145,6 @@
           typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
     }
     var cls = findElement(compiler, 'A');
-    checkReturnInClass('A', 'foo', new TypeMask.nonNullExact(cls.rawType));
+    checkReturnInClass('A', 'foo', new TypeMask.nonNullExact(cls));
   }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index 45b882a..879f819 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -505,6 +505,39 @@
   return a;
 }
 
+testReturnNull1(a) {
+  if (a == null) return a;
+  return null;
+}
+
+testReturnNull2(a) {
+  if (a != null) return null;
+  return a;
+}
+
+testReturnNull3(a) {
+  if (a == null) return 42;
+  return a;
+}
+
+testReturnNull4() {
+  var a = topLeveGetter();
+  if (a == null) return a;
+  return null;
+}
+
+testReturnNull5() {
+  var a = topLeveGetter();
+  if (a != null) return null;
+  return a;
+}
+
+testReturnNull6() {
+  var a = topLeveGetter();
+  if (a == null) return 42;
+  return a;
+}
+
 testReturnInvokeDynamicGetter() => new A().myFactory();
 
 var topLevelConstList = const [42];
@@ -656,6 +689,12 @@
   testSpecialization1();
   testSpecialization2();
   testSpecialization3();
+  testReturnNull1(topLevelGetter());
+  testReturnNull2(topLevelGetter());
+  testReturnNull3(topLevelGetter());
+  testReturnNull4();
+  testReturnNull5();
+  testReturnNull6();
 }
 """;
 
@@ -692,7 +731,7 @@
     checkReturn('returnInt8', typesTask.intType);
     checkReturn('returnEmpty1', const TypeMask.nonNullEmpty());
     checkReturn('returnEmpty2', const TypeMask.nonNullEmpty());
-    TypeMask intType = new TypeMask.nonNullSubtype(compiler.intClass.rawType);
+    TypeMask intType = new TypeMask.nonNullSubtype(compiler.intClass);
     checkReturn('testIsCheck1', intType);
     checkReturn('testIsCheck2', intType);
     checkReturn('testIsCheck3', intType.nullable());
@@ -725,7 +764,7 @@
     checkReturn('testIf1', typesTask.intType.nullable());
     checkReturn('testIf2', typesTask.intType.nullable());
     checkReturn('returnAsString',
-        new TypeMask.subtype(compiler.stringClass.computeType(compiler)));
+        new TypeMask.subtype(compiler.stringClass));
     checkReturn('returnIntAsNum', typesTask.intType);
     checkReturn('returnAsTypedef', typesTask.functionType.nullable());
     checkReturn('returnTopLevelGetter', typesTask.intType);
@@ -780,16 +819,22 @@
     checkFactoryConstructor(String className, String factoryName) {
       var cls = findElement(compiler, className);
       var element = cls.localLookup(buildSourceString(factoryName));
-      Expect.equals(new TypeMask.nonNullExact(cls.rawType),
+      Expect.equals(new TypeMask.nonNullExact(cls),
                     typesInferrer.getReturnTypeOfElement(element));
     }
     checkFactoryConstructor('A', '');
 
     checkReturn('testCascade1', typesTask.growableListType);
     checkReturn('testCascade2', new TypeMask.nonNullExact(
-        findElement(compiler, 'CascadeHelper').rawType));
+        findElement(compiler, 'CascadeHelper')));
     checkReturn('testSpecialization1', typesTask.numType);
     checkReturn('testSpecialization2', typesTask.dynamicType);
     checkReturn('testSpecialization3', typesTask.intType.nullable());
+    checkReturn('testReturnNull1', typesTask.nullType);
+    checkReturn('testReturnNull2', typesTask.nullType);
+    checkReturn('testReturnNull3', typesTask.dynamicType);
+    checkReturn('testReturnNull4', typesTask.nullType);
+    checkReturn('testReturnNull5', typesTask.nullType);
+    checkReturn('testReturnNull6', typesTask.dynamicType);
   }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
index aa29c72..55ed3a7 100644
--- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
@@ -183,7 +183,7 @@
     checkReturn('returnInt4', typesTask.intType);
     checkReturn('returnInt5', typesTask.intType);
     checkReturn('returnInt6',
-        new TypeMask.nonNullSubtype(compiler.intClass.rawType));
+        new TypeMask.nonNullSubtype(compiler.intClass));
 
     var subclassOfInterceptor =
         findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart
index f1a1366..8947932 100644
--- a/tests/compiler/dart2js/type_combination_test.dart
+++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -518,7 +518,7 @@
   rule(jsIndexable, nonPrimitive1, CONFLICTING);
   rule(jsIndexable, nonPrimitive2, CONFLICTING);
   rule(jsIndexable, potentialArray, new HType.nonNullSubtype(
-      compiler.backend.jsArrayClass.computeType(compiler), compiler));
+      compiler.backend.jsArrayClass, compiler));
   rule(jsIndexable, potentialString, jsString);
   rule(jsIndexable, BOOLEAN_OR_NULL, CONFLICTING);
   rule(jsIndexable, NUMBER_OR_NULL, CONFLICTING);
@@ -668,7 +668,7 @@
 
 void testRegressions(MockCompiler compiler) {
   HType nonNullPotentialString = new HType.nonNullSubtype(
-      patternClass.computeType(compiler), compiler);
+      patternClass, compiler);
   Expect.equals(
       potentialString, jsStringOrNull.union(nonNullPotentialString, compiler));
 }
@@ -690,41 +690,41 @@
   patternClass = compiler.coreLibrary.find(buildSourceString('Pattern'));
 
   nonPrimitive1 = new HType.nonNullSubtype(
-      compiler.mapClass.computeType(compiler), compiler);
+      compiler.mapClass, compiler);
   nonPrimitive2 = new HType.nonNullSubtype(
-      compiler.functionClass.computeType(compiler), compiler);
+      compiler.functionClass, compiler);
   potentialArray = new HType.subtype(
-      compiler.listClass.computeType(compiler), compiler);
+      compiler.listClass, compiler);
   potentialString = new HType.subtype(
-      patternClass.computeType(compiler), compiler);
+      patternClass, compiler);
   jsInterceptor = new HType.nonNullSubclass(
-      compiler.backend.jsInterceptorClass.computeType(compiler), compiler);
+      compiler.backend.jsInterceptorClass, compiler);
   jsArrayOrNull = new HType.subclass(
-      compiler.backend.jsArrayClass.computeType(compiler), compiler);
+      compiler.backend.jsArrayClass, compiler);
   jsReadableArray = new HType.nonNullSubclass(
-      compiler.backend.jsArrayClass.computeType(compiler), compiler);
+      compiler.backend.jsArrayClass, compiler);
   jsMutableArrayOrNull = new HType.subclass(
-      compiler.backend.jsMutableArrayClass.computeType(compiler), compiler);
+      compiler.backend.jsMutableArrayClass, compiler);
   jsMutableArray = new HType.nonNullSubclass(
-      compiler.backend.jsMutableArrayClass.computeType(compiler), compiler);
+      compiler.backend.jsMutableArrayClass, compiler);
   jsFixedArrayOrNull = new HType.exact(
-      compiler.backend.jsFixedArrayClass.computeType(compiler), compiler);
+      compiler.backend.jsFixedArrayClass, compiler);
   jsFixedArray = new HType.nonNullExact(
-      compiler.backend.jsFixedArrayClass.computeType(compiler), compiler);
+      compiler.backend.jsFixedArrayClass, compiler);
   jsExtendableArrayOrNull = new HType.exact(
-      compiler.backend.jsExtendableArrayClass.computeType(compiler), compiler);
+      compiler.backend.jsExtendableArrayClass, compiler);
   jsExtendableArray = new HType.nonNullExact(
-      compiler.backend.jsExtendableArrayClass.computeType(compiler), compiler);
+      compiler.backend.jsExtendableArrayClass, compiler);
   jsIndexableOrNull = new HType.subtype(
-      compiler.backend.jsIndexableClass.computeType(compiler), compiler);
+      compiler.backend.jsIndexableClass, compiler);
   jsIndexable = new HType.nonNullSubtype(
-      compiler.backend.jsIndexableClass.computeType(compiler), compiler);
+      compiler.backend.jsIndexableClass, compiler);
   jsInterceptorOrNull = new HType.subclass(
-      compiler.backend.jsInterceptorClass.computeType(compiler), compiler);
+      compiler.backend.jsInterceptorClass, compiler);
   jsStringOrNull = new HType.exact(
-      compiler.backend.jsStringClass.computeType(compiler), compiler);
+      compiler.backend.jsStringClass, compiler);
   jsString = new HType.nonNullExact(
-      compiler.backend.jsStringClass.computeType(compiler), compiler);
+      compiler.backend.jsStringClass, compiler);
 
   testUnion(compiler);
   testIntersection(compiler);
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/type_representation_test.dart
index 5e6b7c5..e222971 100644
--- a/tests/compiler/dart2js/type_representation_test.dart
+++ b/tests/compiler/dart2js/type_representation_test.dart
@@ -94,7 +94,7 @@
     // List
     expect('$List_rep', List_.rawType);
     // List<dynamic>
-    expect('[$List_rep, null]', instantiate(List_, [dynamic_]));
+    expect('$List_rep', instantiate(List_, [dynamic_]));
     // List<int>
     expect('[$List_rep, $int_rep]', instantiate(List_, [int_]));
     // List<Typedef>
@@ -102,11 +102,12 @@
         instantiate(List_, [Typedef_]));
 
     // Map<K,V>
-    expect('[$Map_rep, $Map_K_rep, $Map_V_rep]', Map_.computeType(env.compiler));
+    expect('[$Map_rep, $Map_K_rep, $Map_V_rep]',
+           Map_.computeType(env.compiler));
     // Map
     expect('$Map_rep', Map_.rawType);
     // Map<dynamic,dynamic>
-    expect('[$Map_rep, null, null]', instantiate(Map_, [dynamic_, dynamic_]));
+    expect('$Map_rep', instantiate(Map_, [dynamic_, dynamic_]));
     // Map<int,String>
     expect('[$Map_rep, $int_rep, $String_rep]',
         instantiate(Map_, [int_, String_]));
diff --git a/tests/compiler/dart2js/union_type_test.dart b/tests/compiler/dart2js/union_type_test.dart
index 2b48e04..7cc13ba 100644
--- a/tests/compiler/dart2js/union_type_test.dart
+++ b/tests/compiler/dart2js/union_type_test.dart
@@ -15,9 +15,9 @@
   compiler.stringClass.ensureResolved(compiler);
 
   FlatTypeMask mask1 =
-      new FlatTypeMask.exact(new InterfaceType(compiler.intClass));
+      new FlatTypeMask.exact(compiler.intClass);
   FlatTypeMask mask2 =
-      new FlatTypeMask.exact(new InterfaceType(compiler.stringClass));
+      new FlatTypeMask.exact(compiler.stringClass);
   UnionTypeMask union1 = mask1.nonNullable().union(mask2, compiler);
   UnionTypeMask union2 = mask2.nonNullable().union(mask1, compiler);
   Expect.equals(union1, union2);
diff --git a/tests/compiler/dart2js_extra/field_initializer_test.dart b/tests/compiler/dart2js_extra/field_initializer_test.dart
index cb4a34b..b06f763 100644
--- a/tests/compiler/dart2js_extra/field_initializer_test.dart
+++ b/tests/compiler/dart2js_extra/field_initializer_test.dart
@@ -15,7 +15,7 @@
   static const i = false;
   static const j = n;
   static const k = 4.99;
-  static const l;
+  static const l = null;
   static const m = l;
   static const n = 42;
 }
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 2c2c7b9..7902d5a 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -81,6 +81,7 @@
 int_parse_radix_test: fail
 list_insert_test: fail
 list_removeat_test: fail
+symbol_test/01: fail # test issue 13730; It is static type warning if "const" instance creation argument type is not compatible with parameter type
 
 [ $compiler == dart2analyzer ]
 symbol_test/02: Fail
diff --git a/tests/html/custom/attribute_changed_callback_test.dart b/tests/html/custom/attribute_changed_callback_test.dart
index 955399f..3a9271a 100644
--- a/tests/html/custom/attribute_changed_callback_test.dart
+++ b/tests/html/custom/attribute_changed_callback_test.dart
@@ -3,13 +3,17 @@
 // 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';
+import 'dart:js' as js;
+import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import '../utils.dart';
 
 class A extends HtmlElement {
   static final tag = 'x-a';
   factory A() => new Element.tag(tag);
+  A.created() : super.created();
 
   static var attributeChangedInvocations = 0;
 
@@ -21,10 +25,11 @@
 class B extends HtmlElement {
   static final tag = 'x-b';
   factory B() => new Element.tag(tag);
+  B.created() : super.created();
 
   static var invocations = [];
 
-  void created() {
+  void createdCallback() {
     invocations.add('created');
   }
 
@@ -33,44 +38,75 @@
   }
 }
 
+// Pump custom events polyfill events.
+void customElementsTakeRecords() {
+  if (js.context.hasProperty('CustomElements')) {
+    js.context['CustomElements'].callMethod('takeRecords');
+  }
+}
+
 main() {
-  useHtmlConfiguration();
+  useHtmlIndividualConfiguration();
 
   // 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);
+  var registered = false;
+  setUp(() {
+    return loadPolyfills().then((_) {
+      if (!registered) {
+        registered = true;
+        document.register(A.tag, A);
+        document.register(B.tag, B);
+      }
+    });
   });
 
-  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']);
+  group('fully_supported', () {
+    test('transfer attribute changed callback', () {
+      var element = new A();
 
-    B.invocations = [];
-    b.attributes.remove('id');
-    expect(B.invocations, ['id: x => null']);
+      element.attributes['a'] = 'b';
+      expect(A.attributeChangedInvocations, 1);
+    });
 
-    B.invocations = [];
-    b.attributes['data-s'] = 't';
-    expect(B.invocations, ['data-s: null => t']);
+    test('add, change and remove an attribute', () {
+      var b = new B();
 
-    B.invocations = [];
-    b.classList.toggle('u');
-    expect(B.invocations, ['class: null => u']);
+      B.invocations = [];
+      b.attributes['data-s'] = 't';
+      expect(B.invocations, ['data-s: null => t']);
 
-    b.attributes['data-v'] = 'w';
-    B.invocations = [];
-    b.attributes['data-v'] = 'x';
-    expect(B.invocations, ['data-v: w => x']);
+      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, []);
+      B.invocations = [];
+      b.attributes['data-v'] = 'x';
+      expect(B.invocations, []);
+
+      b.attributes.remove('data-v');
+      expect(B.invocations, ['data-v: x => null']);
+    });
+  });
+
+  group('unsupported_on_polyfill', () {
+    test('add, change ID', () {
+      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']);
+    });
+
+    test('add, change classes', () {
+      var b = new B();
+
+      B.invocations = [];
+      b.classes.toggle('u');
+      expect(B.invocations, ['class: null => u']);
+    });
   });
 }
diff --git a/tests/html/custom/constructor_calls_created_synchronously_test.dart b/tests/html/custom/constructor_calls_created_synchronously_test.dart
index edd689a..2238df6 100644
--- a/tests/html/custom/constructor_calls_created_synchronously_test.dart
+++ b/tests/html/custom/constructor_calls_created_synchronously_test.dart
@@ -7,14 +7,16 @@
 import 'package:unittest/html_config.dart';
 import 'dart:html';
 import '../utils.dart';
+import 'dart:mirrors';
 
 class A extends HtmlElement {
   static final tag = 'x-a';
   factory A() => new Element.tag(tag);
+  A.created() : super.created();
 
   static int ncallbacks = 0;
 
-  void created() {
+  void createdCallback() {
     ncallbacks++;
   }
 }
diff --git a/tests/html/custom/created_callback_test.dart b/tests/html/custom/created_callback_test.dart
index ebd3fba..dfcd28f 100644
--- a/tests/html/custom/created_callback_test.dart
+++ b/tests/html/custom/created_callback_test.dart
@@ -6,15 +6,17 @@
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
 import 'dart:html';
+import 'dart:js' as js;
 import '../utils.dart';
 
 class A extends HtmlElement {
   static final tag = 'x-a';
   factory A() => new Element.tag(tag);
+  A.created() : super.created();
 
   static int createdInvocations = 0;
 
-  void created() {
+  void createdCallback() {
     createdInvocations++;
   }
 }
@@ -22,16 +24,18 @@
 class B extends HtmlElement {
   static final tag = 'x-b';
   factory B() => new Element.tag(tag);
+  B.created() : super.created();
 }
 
 class C extends HtmlElement {
   static final tag = 'x-c';
   factory C() => new Element.tag(tag);
+  C.created() : super.created();
 
   static int createdInvocations = 0;
   static var div;
 
-  void created() {
+  void createdCallback() {
     createdInvocations++;
 
     if (this.id != 'u') {
@@ -60,7 +64,17 @@
   // Adapted from Blink's
   // fast/dom/custom/created-callback test.
 
-  setUp(loadPolyfills);
+  var registered = false;
+  setUp(() {
+    return loadPolyfills().then((_) {
+      if (!registered) {
+        registered = true;
+        document.register(B.tag, B);
+        document.register(C.tag, C);
+        ErrorConstructorElement.register();
+      }
+    });
+  });
 
   test('transfer created callback', () {
     document.register(A.tag, A);
@@ -68,10 +82,7 @@
     expect(A.createdInvocations, 1);
   });
 
-  test(':unresolved and created callback timing', () {
-    document.register(B.tag, B);
-    document.register(C.tag, C);
-
+  test('unresolved and created callback timing', () {
     var div = new DivElement();
     C.div = div;
     div.setInnerHtml("""
@@ -87,6 +98,194 @@
     expect(div.query('#w') is B, isTrue);
   });
 
+  test('nesting of constructors', NestedElement.test);
+
+  test('access while upgrading gets unupgraded element',
+      AccessWhileUpgradingElement.test);
+
+  test('cannot call created constructor', () {
+    expect(() {
+      new B.created();
+    }, throws);
+  });
+
+  test('cannot register without created', () {
+    expect(() {
+      document.register(MissingCreatedElement.tag, MissingCreatedElement);
+    }, throws);
+  });
+
+  test('throw on createElement does not upgrade', () {
+    ErrorConstructorElement.callCount = 0;
+
+    var e;
+    expectGlobalError(() {
+      e = new Element.tag(ErrorConstructorElement.tag);
+    });
+    expect(ErrorConstructorElement.callCount, 1);
+    expect(e is HtmlElement, isTrue);
+    expect(e is ErrorConstructorElement, isFalse);
+
+    var dummy = new DivElement();
+    dummy.append(e);
+    e = dummy.firstChild;
+    expect(ErrorConstructorElement.callCount, 1);
+  });
+
+  test('throw on innerHtml does not upgrade', () {
+    ErrorConstructorElement.callCount = 0;
+
+    var dummy = new DivElement();
+    var tag = ErrorConstructorElement.tag;
+    expectGlobalError(() {
+      dummy.setInnerHtml('<$tag></$tag>',
+          treeSanitizer: new NullTreeSanitizer());
+    });
+
+    expect(ErrorConstructorElement.callCount, 1);
+
+    var e = dummy.firstChild;
+    // Accessing should not re-run the constructor.
+    expect(ErrorConstructorElement.callCount, 1);
+    expect(e is HtmlElement, isTrue);
+    expect(e is ErrorConstructorElement, isFalse);
+  });
+
+  // Issue - 13711 Need to fix the handling of the created constructor.
+  // test('created cannot be called from nested constructor',
+  //     NestedCreatedConstructorElement.test);
+
+
   // 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
 }
+
+
+class NestedElement extends HtmlElement {
+  static final tag = 'x-nested';
+
+  final Element b = new B();
+
+  factory NestedElement() => new Element.tag(tag);
+  NestedElement.created() : super.created();
+
+  static void register() {
+    document.register(tag, NestedElement);
+  }
+
+  static void test() {
+    register();
+
+    var e = new NestedElement();
+    expect(e.b, isNotNull);
+    expect(e.b is B, isTrue);
+    expect(e is NestedElement, isTrue);
+  }
+}
+
+
+class AccessWhileUpgradingElement extends HtmlElement {
+  static final tag = 'x-access-while-upgrading';
+
+  static Element upgradingContext;
+  static Element upgradingContextChild;
+
+  final foo = runInitializerCode();
+
+  factory AccessWhileUpgradingElement() => new Element.tag(tag);
+  AccessWhileUpgradingElement.created() : super.created();
+
+  static runInitializerCode() {
+    upgradingContextChild = upgradingContext.firstChild;
+
+    return 666;
+  }
+
+  static void register() {
+    document.register(tag, AccessWhileUpgradingElement);
+  }
+
+  static void test() {
+    register();
+
+    upgradingContext = new DivElement();
+    upgradingContext.setInnerHtml('<$tag></$tag>',
+        treeSanitizer: new NullTreeSanitizer());
+    var child = upgradingContext.firstChild;
+
+    expect(child.foo, 666);
+    expect(upgradingContextChild is HTMLElement, isTrue);
+    expect(upgradingContextChild is AccessWhileUpgradingElement, isFalse,
+        reason: 'Elements accessed while upgrading should not be upgraded.');
+  }
+}
+
+class MissingCreatedElement extends HtmlElement {
+  static final tag = 'x-missing-created';
+
+  factory MissingCreatedElement() => new Element.tag(tag);
+}
+
+class ErrorConstructorElement extends HtmlElement {
+  static final tag = 'x-throws-in-constructor';
+  static int callCount = 0;
+
+  factory ErrorConstructorElement() => new Element.tag(tag);
+
+  ErrorConstructorElement.created() : super.created() {
+    ++callCount;
+    throw new Exception('Just messin with ya');
+  }
+
+  static void register() {
+    document.register(tag, ErrorConstructorElement);
+  }
+}
+
+class NestedCreatedConstructorElement extends HtmlElement {
+  static final tag = 'x-nested-created-constructor';
+
+  // Should not be able to call this here.
+  final B b = constructB();
+  static B constructedB;
+
+  factory NestedCreatedConstructorElement() => new Element.tag(tag);
+  NestedCreatedConstructorElement.created() : super.created();
+
+  static void register() {
+    document.register(tag, NestedCreatedConstructorElement);
+  }
+
+  // Try to run the created constructor, and record the results.
+  static constructB() {
+    // This should throw an exception.
+    constructedB = new B.created();
+    return constructedB;
+  }
+
+  static void test() {
+    register();
+
+    // Exception should have occurred on upgrade.
+    var e = new Element.tag(tag);
+    expect(e is NestedCreatedConstructorElement, isFalse);
+    expect(e is HtmlElement, isTrue);
+    // Should not have been set.
+    expect(constructedB, isNull);
+  }
+}
+
+void expectGlobalError(Function test) {
+  js.context['testExpectsGlobalError'] = true;
+  try {
+    test();
+  } catch(e) {
+    rethrow;
+  } finally {
+    js.context['testExpectsGlobalError'] = false;
+  }
+  var errors = js.context['testSuppressedGlobalErrors'];
+  expect(errors['length'], 1);
+  // Clear out the errors;
+  js.context['testSuppressedGlobalErrors']['length'] = 0;
+}
diff --git a/tests/html/custom/document_register_basic_test.dart b/tests/html/custom/document_register_basic_test.dart
index c8964e5..7e094e8b 100644
--- a/tests/html/custom/document_register_basic_test.dart
+++ b/tests/html/custom/document_register_basic_test.dart
@@ -11,6 +11,7 @@
 class Foo extends HtmlElement {
   static final tag = 'x-foo';
   factory Foo() => new Element.tag(tag);
+  Foo.created() : super.created();
 
   get thisIsACustomClass => true;
 }
@@ -18,6 +19,7 @@
 class Bar extends HtmlElement {
   static final tag = 'x-bar';
   factory Bar() => new Element.tag(tag);
+  Bar.created() : super.created();
 
   get thisIsACustomClass => true;
 }
@@ -25,6 +27,7 @@
 class Baz extends Foo {
   static final tag = 'x-baz';
   factory Baz() => new Element.tag(tag);
+  Baz.created() : super.created();
 
   get thisIsAlsoACustomClass => true;
 }
diff --git a/tests/html/custom/document_register_type_extensions_test.dart b/tests/html/custom/document_register_type_extensions_test.dart
index 79b036d..3f43234 100644
--- a/tests/html/custom/document_register_type_extensions_test.dart
+++ b/tests/html/custom/document_register_type_extensions_test.dart
@@ -14,12 +14,14 @@
     '<x-foo></x-foo>',
     '<?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" /><x-foo></x-foo>'];
   factory Foo() => new Element.tag(tag);
+  Foo.created() : super.created();
 }
 
 class Bar extends InputElement {
   static const tag = 'x-bar';
   static const outerHtmlString = '<input is="x-bar">';
   factory Bar() => new Element.tag('input', tag);
+  Bar.created() : super.created();
 }
 
 class Baz extends Foo {
@@ -28,16 +30,19 @@
       '<x-baz></x-baz>',
       '<?XML:NAMESPACE PREFIX = PUBLIC NS = "URN:COMPONENT" /><x-baz></x-baz>'];
   factory Baz() => new Element.tag(tag);
+  Baz.created() : super.created();
 }
 
 class Qux extends Bar {
   static const tag = 'x-qux';
   factory Qux() => new Element.tag('input', tag);
+  Qux.created() : super.created();
 }
 
 class FooBad extends DivElement {
   static const tag = 'x-foo';
   factory FooBad() => new Element.tag('div', tag);
+  FooBad.created() : super.created();
 }
 
 main() {
diff --git a/tests/html/custom/entered_left_view_test.dart b/tests/html/custom/entered_left_view_test.dart
index 79f65c8..a523854 100644
--- a/tests/html/custom/entered_left_view_test.dart
+++ b/tests/html/custom/entered_left_view_test.dart
@@ -14,8 +14,9 @@
 var invocations = [];
 class Foo extends HtmlElement {
   factory Foo() => null;
+  Foo.created() : super.created();
 
-  void created() {
+  void createdCallback() {
     invocations.add('created');
   }
 
@@ -27,7 +28,7 @@
     invocations.add('left');
   }
 
-  void attributeChanged() {
+  void attributeChanged(String name, String oldValue, String newValue) {
     invocations.add('attribute changed');
   }
 }
@@ -62,7 +63,7 @@
   });
 
   group('standard_events', () {
-    var a = new Element.tag('x-a');
+    var a;
     setUp(() {
       invocations = [];
     });
@@ -105,7 +106,7 @@
   });
 
   group('viewless_document', () {
-    var a = docB.createElement('x-a');
+    var a;
     setUp(() {
       invocations = [];
     });
diff --git a/tests/html/custom_elements_test.dart b/tests/html/custom_elements_test.dart
index 3ad83a1..718898c 100644
--- a/tests/html/custom_elements_test.dart
+++ b/tests/html/custom_elements_test.dart
@@ -19,8 +19,10 @@
 
 class CustomType extends HtmlElement with CustomMixin{
   factory CustomType() => null;
+  CustomType.created(): super.created();
+
   bool createdCalled; // = false;
-  void created() {
+  void createdCallback() {
     createdCalled = true;
     customCreatedCount++;
   }
diff --git a/tests/html/html.status b/tests/html/html.status
index 4905e0b..5db1caa 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -13,10 +13,10 @@
 custom/document_register_type_extensions_test/namespaces: Fail # Polyfill does not support createElementNS
 custom/document_register_basic_test: Fail # Polyfill is not case-sensitive
 custom/entered_left_view_test/viewless_document: Fail # Polyfill does not handle this
+custom/attribute_changed_callback_test/unsupported_on_polyfill: Fail # Polyfill does not support
 
 [ $compiler == dart2js && $browser ]
-# Issue 9325 failures
-custom/attribute_changed_callback_test: Fail
+custom/created_callback_test: Fail # Support for created constructor.
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium) && $mode == debug && $system == macos]
 audiobuffersourcenode_test: Pass, Fail, Crash # http://crbug.com/256601
@@ -29,9 +29,9 @@
 postmessage_structured_test/typed_arrays: Fail
 xhr_test: Pass, Fail # Issue 12648
 custom/attribute_changed_callback_test: Fail # 12643
-custom/entered_left_view_test: Fail # 13313
 xhr_test/json: Fail # Issue 13069
 uri_test: Fail Issue 13581
+async_test: Fail # Background timers not implemented.
 
 [ $compiler == none && $runtime == drt && $system == windows ]
 worker_test/functional: Pass, Crash # Issue 9929.
@@ -85,8 +85,6 @@
 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
 
diff --git a/tests/html/htmloptionscollection_test.dart b/tests/html/htmloptionscollection_test.dart
index 8af54c7..9a633ab 100644
--- a/tests/html/htmloptionscollection_test.dart
+++ b/tests/html/htmloptionscollection_test.dart
@@ -33,7 +33,7 @@
 
     // OPTIONALS optionsCollection[0] = new OptionElement(value: '42', data: 'Option42');
     expect(() {
-      optionsCollection[0] = new OptionElement('Option42', '42');
+      optionsCollection[0] = new OptionElement(data: 'Option42', value: '42');
     }, throws);
   });
 }
diff --git a/tests/html/js_test.dart b/tests/html/js_test.dart
index ff6753d..290a0fb 100644
--- a/tests/html/js_test.dart
+++ b/tests/html/js_test.dart
@@ -151,6 +151,12 @@
   _injectJs();
   useHtmlConfiguration();
 
+  test('context instances should be identical', () {
+    var c1 = context;
+    var c2 = context;
+    expect(identical(c1, c2), isTrue);
+  });
+
   test('read global field', () {
     expect(context['x'], equals(42));
     expect(context['y'], isNull);
diff --git a/tests/html/selectelement_test.dart b/tests/html/selectelement_test.dart
index 717502f..f88c4af 100644
--- a/tests/html/selectelement_test.dart
+++ b/tests/html/selectelement_test.dart
@@ -16,9 +16,11 @@
     var options = [
       new OptionElement(),
       new DivElement(),
-      new OptionElement('data', 'two', false, true),
+      new OptionElement(data: 'data', value: 'two', defaultSelected: false,
+          selected: true),
       new DivElement(),
-      new OptionElement('data', 'two', false, true),
+      new OptionElement(data: 'data', value: 'two', defaultSelected: false,
+          selected: true),
       new OptionElement(),
     ];
     element.children.addAll(options);
@@ -32,9 +34,11 @@
     var options = [
       new OptionElement(),
       new DivElement(),
-      new OptionElement('data', 'two', false, true),
+      new OptionElement(data: 'data', value: 'two', defaultSelected: false,
+          selected: true),
       new DivElement(),
-      new OptionElement('data', 'two', false, true),
+      new OptionElement(data: 'data', value: 'two', defaultSelected: false,
+          selected: true),
       new OptionElement(),
     ];
     element.children.addAll(options);
@@ -47,8 +51,10 @@
     var element = new SelectElement();
     var options = [
       new OptionElement(),
-      new OptionElement('data', 'two', false, true),
-      new OptionElement('data', 'two', false, true),
+      new OptionElement(data: 'data', value: 'two', defaultSelected: false,
+          selected: true),
+      new OptionElement(data: 'data', value: 'two', defaultSelected: false,
+          selected: true),
       new OptionElement(),
     ];
     element.children.addAll(options);
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 700d27c..a74948a 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -89,9 +89,11 @@
 [ $compiler == dart2js && ( $runtime == ff || $runtime == safari || $runtime == drt || $runtime == chrome ) ]
 isolate_stress_test: Pass, Slow # Issue 10697
 
-[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
+[ $compiler == none && $runtime == drt ]
 isolate_stress_test: Skip # Issue 12537
 spawn_uri_multi_test/01: Fail # Issue 13615
+nested_spawn_stream2_test: Fail # Issue 13433
+cross_isolate_message_stream_test: Fail # Issue 13433
 
 [ $csp ]
 spawn_uri_multi_test/none: Fail # http://dartbug.com/13454
@@ -99,3 +101,6 @@
 
 [ $jscl || $runtime == ie9 ]
 spawn_uri_multi_test/none: RuntimeError # http://dartbug.com/13544
+
+[ $compiler == none && $runtime == dartium ]
+global_error_handler2_test: Fail # Issue 13719: Please triage this failure.
diff --git a/tests/language/compile_time_constant11_test.dart b/tests/language/compile_time_constant11_test.dart
new file mode 100644
index 0000000..67ff3fe
--- /dev/null
+++ b/tests/language/compile_time_constant11_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that conditional expression can be a compile-time constant.
+
+import "package:expect/expect.dart";
+
+const C1 = true;
+const C2 = false;
+
+const nephew = C1 ? C2 ? "Tick" : "Trick" : "Track";
+
+main() {
+  const a = true ? 5 : 10;
+  const b = C2 ? "Track" : C1 ? "Trick" : "Tick";
+
+  Expect.equals(5, a);
+  Expect.equals("Trick", nephew);
+  Expect.equals(nephew, b);
+  Expect.identical(nephew, b);
+  var s = const Symbol(nephew);
+  var msg = "Donald is $nephew's uncle.";
+  Expect.equals("Donald is Trick's uncle.", msg);
+}
diff --git a/tests/language/const_conditional_test.dart b/tests/language/const_conditional_test.dart
new file mode 100644
index 0000000..97d4a93
--- /dev/null
+++ b/tests/language/const_conditional_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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 conditionals as compile-time constants.
+
+import 'package:expect/expect.dart';
+
+class Marker {
+  final field;
+  const Marker(this.field);
+}
+
+var var0 = const Marker(0);
+var var1 = const Marker(1);
+const const0 = const Marker(0);
+const const1 = const Marker(1);
+
+const trueConst = true;
+const falseConst = false;
+var nonConst = true;
+const zeroConst = 0;
+
+const cond1 = trueConst ? const0 : const1;
+const cond1a = trueConst ? nonConst : const1; /// 01: compile-time error
+const cond1b = trueConst ? const0 : nonConst; /// 02: compile-time error
+
+const cond2 = falseConst ? const0 : const1;
+const cond2a = falseConst ? nonConst : const1; /// 03: compile-time error
+const cond2b = falseConst ? const0 : nonConst; /// 04: compile-time error
+
+const cond3 = nonConst ? const0 : const1; /// 05: compile-time error
+const cond3a = nonConst ? nonConst : const1; /// 06: compile-time error
+const cond3b = nonConst ? const0 : nonConst; /// 07: compile-time error
+
+const cond4 = zeroConst ? const0 : const1; /// 08: compile-time error
+const cond4a = zeroConst ? nonConst : const1; /// 09: compile-time error
+const cond4b = zeroConst ? const0 : nonConst; /// 10: compile-time error
+
+void main() {
+  Expect.identical(var0, cond1);
+  Expect.identical(nonConst, cond1a); /// 01: continued
+  Expect.identical(var0, cond1b); /// 02: continued
+
+  Expect.identical(var1, cond2);
+  Expect.identical(var1, cond2a); /// 03: continued
+  Expect.identical(nonConst, cond2b); /// 04: continued
+
+  Expect.identical(var0, cond3);  /// 05: continued
+  Expect.identical(nonConst, cond3a); /// 06: continued
+  Expect.identical(var0, cond3b); /// 07: continued
+
+  Expect.identical(var1, cond4);  /// 08: continued
+  Expect.identical(var1, cond4a); /// 09: continued
+  Expect.identical(nonConst, cond4b); /// 10: continued
+}
\ No newline at end of file
diff --git a/tests/language/constant_locals_test.dart b/tests/language/constant_locals_test.dart
new file mode 100644
index 0000000..bd85240
--- /dev/null
+++ b/tests/language/constant_locals_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that constant local variables have constant initializers.
+
+import "package:expect/expect.dart";
+
+void main() {
+  const c1; /// 01: compile-time error
+  const c2 = 0;
+  const c3 = field; /// 02: compile-time error
+  const c4 = finalField; /// 03: compile-time error
+  const c5 = constField;
+  const c6 = method(); /// 04: compile-time error
+  const c7 = new Class(); /// 05: compile-time error
+  const c8 = const Class();
+}
+
+var field = 0;
+
+final finalField = 0;
+
+const constField = 0;
+
+method() => 0;
+
+class Class {
+  const Class();
+}
\ No newline at end of file
diff --git a/tests/language/language.status b/tests/language/language.status
index e567204..bd6e7e2 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -25,6 +25,18 @@
 on_catch_malformed_type_test: Fail # Issue 8601
 mixin_forwarding_constructor2_test: Fail # Issue 13641
 
+[ $compiler == none && $runtime == vm ]
+class_keyword_test/02: MissingCompileTimeError # Issue 13627
+
+
+[ $compiler == none && $runtime == vm && $checked ]
+compile_time_constant_checked3_test/01: MissingCompileTimeError # Issue 13685
+compile_time_constant_checked3_test/02: MissingCompileTimeError # Issue 13685
+compile_time_constant_checked3_test/03: MissingCompileTimeError # Issue 13685
+compile_time_constant_checked3_test/04: MissingCompileTimeError # Issue 13685
+compile_time_constant_checked3_test/05: MissingCompileTimeError # Issue 13685
+compile_time_constant_checked3_test/06: MissingCompileTimeError # Issue 13685
+
 [ $compiler == none && $unchecked ]
 # Only checked mode reports an error on type assignment
 # problems in compile time constants.
@@ -56,3 +68,21 @@
 
 [ $compiler == dart2js && $runtime == ie9 ]
 lazy_static3_test: Fail # Issue 13469
+
+[ $compiler == none && $runtime == dartium ]
+assertion_test: Fail # Issue 13719: Please triage this failure.
+call_test: Fail # Issue 13719: Please triage this failure.
+dynamic_prefix_core_test: Fail # Issue 13719: Please triage this failure.
+first_class_types_literals_test: Fail # Issue 13719: Please triage this failure.
+generic_test: Fail # Issue 13719: Please triage this failure.
+list_literal1_test/01: Fail # Issue 13719: Please triage this failure.
+list_literal4_test: Fail # Issue 13719: Please triage this failure.
+map_literal1_test/01: Fail # Issue 13719: Please triage this failure.
+map_literal4_test: Fail # Issue 13719: Please triage this failure.
+named_parameters_type_test/01: Fail # Issue 13719: Please triage this failure.
+named_parameters_type_test/02: Fail # Issue 13719: Please triage this failure.
+named_parameters_type_test/03: Fail # Issue 13719: Please triage this failure.
+positional_parameters_type_test/01: Fail # Issue 13719: Please triage this failure.
+positional_parameters_type_test/02: Fail # Issue 13719: Please triage this failure.
+type_checks_in_factory_method_test: Fail # Issue 13719: Please triage this failure.
+vm/type_vm_test: Fail # Issue 13719: Please triage this failure.
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index d229d47..536168e 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -3,17 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dartanalyzer ]
-
-# Missing compile-time errors for parameters marked static.
-static_parameter_test/02: Fail
-static_parameter_test/03: Fail
-static_parameter_test/04: Fail
-static_parameter_test/06: Fail
-static_parameter_test/07: Fail
-static_parameter_test/08: Fail
-static_parameter_test/10: Fail
-static_parameter_test/11: Fail
-static_parameter_test/12: Fail
+switch_bad_case_test/02: Fail # missing error in double in switch case expr
 
 # Runtime negative test. No static errors or warnings.
 closure_call_wrong_argument_count_negative_test: skip
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index f43b9e8..17a459a 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -3,6 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2analyzer ]
+switch_bad_case_test/02: Fail
 
 # Missing compile-time errors for parameters marked static.
 static_parameter_test/02: Fail
@@ -123,9 +124,6 @@
 # test issue 11590, runtime only negative test
 field_method4_negative_test: fail
 
-# test issue 11591, assigning to the final variable is warning, not error
-getter_no_setter_test/01: fail
-
 # test issue 11592, Function type alias (typedef) is not a constant
 first_class_types_constants_test: fail
 
@@ -133,8 +131,6 @@
 import_combinators_negative_test: fail
 interface_static_non_final_fields_negative_test: fail
 
-instantiate_type_variable_test/01: fail # Issue 11595
-
 # test issue 11698, no setter, so warning, not error
 assign_instance_method_negative_test: fail
 
@@ -185,7 +181,6 @@
 
 # test issue 12191, ambiguous import is always warning now
 prefix3_negative_test: fail # Issue 12191
-library_ambiguous_test/00: fail # Issue 12191
 
 # test issue 12289, assignment in assert statement
 type_error_test: fail # Issue 12289
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 4bb4278..87857b1 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -5,7 +5,6 @@
 [ $compiler == dart2js || $compiler == dart2dart ]
 bad_constructor_test/05: CompileTimeError # Issue 13669
 block_scope_test: CompileTimeError # Issue 13204.
-null_test/03: MissingCompileTimeError # Issue 12445.
 black_listed_test/none: CompileTimeError # Issue 12446.
 malformed_test/05: MissingCompileTimeError # Issue 12695
 malformed_test/06: MissingCompileTimeError # Issue 12695
@@ -79,6 +78,7 @@
 mixin_mixin6_test: Fail # Issue 12605.
 
 [ $compiler == dart2js ]
+switch_bad_case_test/02: MissingCompileTimeError # switch case of type double
 malformed_test/none: RuntimeError # Issue 12695
 function_type_alias9_test/00: Crash # Issue 9792
 branch_canonicalization_test: RuntimeError # Issue 638.
@@ -130,7 +130,6 @@
 function_type_alias5_test/01: MissingCompileTimeError # Issue 12754
 function_type_alias5_test/02: MissingCompileTimeError # Issue 12754
 method_override5_test: RuntimeError # Issue 12809
-parameter_initializer6_negative_test: Fail # Issue 3502
 named_parameters_aggregated_test/03: MissingCompileTimeError # Issue 12812
 external_test/11: MissingCompileTimeError # Issue 12887
 external_test/12: MissingCompileTimeError # Issue 12887
@@ -145,8 +144,6 @@
 map_literal4_test: RuntimeError # Issue 12891
 built_in_identifier_test/01: CompileTimeError # Issue 13022
 
-const_syntax_test/03: MissingCompileTimeError # Issue 12932
-const_syntax_test/04: MissingCompileTimeError # Issue 12932
 constructor9_test/01: MissingCompileTimeError # Issue 12934
 list_literal1_test/01: MissingCompileTimeError # Issue 12993
 map_literal1_test/01: MissingCompileTimeError # Issue 12993
@@ -164,7 +161,6 @@
 final_syntax_test/03: MissingCompileTimeError # Issue 13020
 final_syntax_test/04: MissingCompileTimeError # Issue 13020
 
-assign_top_method_test: RuntimeError # Issue 13075
 null_test/none: RuntimeError  # Issue 12482
 
 
@@ -205,6 +201,7 @@
 malformed_test/none: CompileTimeError # Issue 12695
 mixin_super_constructor_named_test: Fail # Issue 12631
 mixin_super_constructor_positionals_test: Fail # Issue 12631
+switch_bad_case_test/02: Fail # missing switch type check for double
 
 built_in_identifier_prefix_test: Fail # Issue 6972
 constructor_initializer_test/none: Fail # Issue 12633
@@ -245,21 +242,6 @@
 setter_override_test/03: Fail # Issue 11496
 setter_override2_test/02: Fail # Issue 11496
 
-compile_time_constant10_test/01: Fail # Issue 5519
-compile_time_constant10_test/02: Fail # Issue 5519
-compile_time_constant_arguments_test/01: Fail # Issue 5519
-compile_time_constant_arguments_test/02: Fail # Issue 5519
-compile_time_constant_arguments_test/03: Fail # Issue 5519
-compile_time_constant_arguments_test/05: Fail # Issue 5519
-compile_time_constant_arguments_test/06: Fail # Issue 5519
-const_syntax_test/03: Fail # Issue 12933
-const_syntax_test/04: Fail # Issue 12933
-const_syntax_test/05: Fail # Issue 12933
-const_syntax_test/06: Fail # Issue 12933
-const_syntax_test/07: Fail # Issue 12933
-const_syntax_test/08: Fail # Issue 12933
-const_syntax_test/10: Fail # Issue 12933
-compile_time_constant_c_test/02: Fail # Issue 12933
 constructor9_test/01: Fail # Issue 12935
 constructor_named_arguments_test/01: Fail # Issue 5519
 final_syntax_test/01: Fail # Issue 13020
@@ -299,7 +281,6 @@
 function_type_alias5_test/00: Fail # Issue 12755
 function_type_alias5_test/01: Fail # Issue 12755
 function_type_alias5_test/02: Fail # Issue 12755
-parameter_initializer6_negative_test: Fail # Issue 3502
 
 # DartVM problem.
 constructor5_test: Fail
@@ -329,8 +310,6 @@
 compile_time_constant_checked3_test/05: Fail, OK
 compile_time_constant_checked3_test/06: Fail, OK
 
-final_is_not_const_test/01: Fail # Issue 12692
-
 [ $compiler == dart2dart && $minified ]
 super_getter_setter_test: Fail # Issue 11065.
 f_bounded_quantification4_test: Fail # Issue 12605.
diff --git a/tests/language/list_length_tracer_test.dart b/tests/language/list_length_tracer_test.dart
new file mode 100644
index 0000000..f8c1070
--- /dev/null
+++ b/tests/language/list_length_tracer_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 that dart2js' optimization on list length does not fold a
+// length getter to a constant if the receiver can be null.
+
+import "package:expect/expect.dart";
+
+var a = 42;
+var b;
+
+main() {
+  Expect.throws(() => b.length);
+  b = const [42];
+}
diff --git a/tests/language/list_tracer_call_last_test.dart b/tests/language/list_tracer_call_last_test.dart
new file mode 100644
index 0000000..dbaf136
--- /dev/null
+++ b/tests/language/list_tracer_call_last_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2js used to fail this test, by inferring that `a.last()`
+// returns the element type of the `a` list.
+
+main() {
+  var a = [() => 123];
+  if (a.last() is! num) {
+    throw 'Test failed';
+  }
+}
diff --git a/tests/language/list_tracer_closure_test.dart b/tests/language/list_tracer_closure_test.dart
new file mode 100644
index 0000000..acb226e
--- /dev/null
+++ b/tests/language/list_tracer_closure_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js' inferrer: if we closurize a method, we
+// still need to collect the users of the parameters for the trace
+// container pass to work.
+
+main() {
+  var a = new List();
+  a.add;
+  var b = new List();
+  var c = new List(1);
+  b.add(c);
+  b[0][0] = 42;
+  if (c[0] is! int) {
+    throw 'Test failed';
+  }
+}
diff --git a/tests/language/mixin_black_listed_test.dart b/tests/language/mixin_black_listed_test.dart
new file mode 100644
index 0000000..809274b
--- /dev/null
+++ b/tests/language/mixin_black_listed_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check mixin of black-listed types.
+
+import 'package:expect/expect.dart';
+
+class C {}
+class D {}
+
+class C1 extends Object
+with String /// 01: compile-time error
+{}
+
+class D1 extends Object with C
+, Null /// 02: compile-time error
+{}
+
+class E1 extends Object with
+int, /// 03: compile-time error
+C {}
+
+class F1 extends Object with C
+, double /// 04: compile-time error
+, D {}
+
+typedef C2 = Object with num; /// 05: compile-time error
+
+typedef D2 = Object with C
+, bool /// 06: compile-time error
+;
+
+typedef E2 = Object with
+String, /// 07: compile-time error
+C;
+
+typedef F2 = Object with C,
+dynamic, /// 08: compile-time error
+D;
+
+
+main() {
+  Expect.isNotNull(new C1());
+  Expect.isNotNull(new D1());
+  Expect.isNotNull(new E1());
+  Expect.isNotNull(new F1());
+  Expect.isNotNull(new C2()); /// 05: continued
+  Expect.isNotNull(new D2());
+  Expect.isNotNull(new E2());
+  Expect.isNotNull(new F2());
+}
diff --git a/tests/language/switch_bad_case_test.dart b/tests/language/switch_bad_case_test.dart
new file mode 100644
index 0000000..8211521
--- /dev/null
+++ b/tests/language/switch_bad_case_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test reporting a compile-time error if case expressions do not all have
+// the same type or are of type double.
+
+import "package:expect/expect.dart";
+
+void main() {
+  Expect.equals("IV", caesarSays(4));
+  Expect.equals(null, caesarSays(2));
+  Expect.equals(null, archimedesSays(3.14));
+}
+
+caesarSays(n) {
+  switch (n) {
+    case 1:
+      return "I";
+    case 4:
+      return "IV";
+    case "M":         /// 01: compile-time error
+      return 1000;    /// 01: continued
+  }
+  return null;
+}
+
+archimedesSays(n) {
+  switch (n) {        /// 02: continued
+    case 3.14:        /// 02: compile-time error
+      return "Pi";    /// 02: continued
+    case 2.71828:     /// 02: continued
+      return "Huh?";  /// 02: continued
+  }                   /// 02: continued
+  return null;
+}
diff --git a/tests/language/switch_int_double_test.dart b/tests/language/switch_int_double_test.dart
deleted file mode 100644
index 8ae95e2..0000000
--- a/tests/language/switch_int_double_test.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test reporting a compile-time error if case expressions do not all have
-// the same type.
-
-import "package:expect/expect.dart";
-
-void main() {
-  Expect.equals(100, test(1.0));
-  Expect.equals(75, test(0.75));
-  Expect.equals(null, test(0.5));
-}
-
-int test(num ratio) {
-  switch (ratio) {
-    case 0.75:
-      return 75;
-    case 1.0:
-      return 100;
-    case 2:       /// 01: compile-time error
-      return 200; /// 01: continued
-    case 'foo':   /// 02: compile-time error
-      return 400; /// 02: continued
-  }
-}
\ No newline at end of file
diff --git a/tests/language/vm/function_equality_vm_test.dart b/tests/language/vm/function_equality_vm_test.dart
new file mode 100644
index 0000000..4077c66
--- /dev/null
+++ b/tests/language/vm/function_equality_vm_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test function equality with null.
+
+import "package:expect/expect.dart";
+
+class A {
+  foo() { }
+}
+
+main() {
+  var a = new A();
+  var f = a.foo;
+  Expect.isFalse(f == null);
+  Expect.isFalse(null == f);
+}
+
diff --git a/tests/lib/convert/unicode_tests.dart b/tests/lib/convert/unicode_tests.dart
index 52a7b09..47bd510 100644
--- a/tests/lib/convert/unicode_tests.dart
+++ b/tests/lib/convert/unicode_tests.dart
@@ -63,6 +63,9 @@
 const SMALLEST_4_UTF8_UNIT_BYTES = const [ 0xF0, 0x90, 0x80, 0x80 ];
 const SMALLEST_4_UTF8_UNIT_STRING = "\u{10000}";
 
+const BIGGEST_4_UTF8_UNIT_BYTES = const [ 0xF4, 0x8F, 0xBF, 0xBF ];
+const BIGGEST_4_UTF8_UNIT_STRING = "\u{10FFFF}";
+
 const _TEST_PAIRS = const [
     const [ const [], "" ],
     const [ INTER_BYTES, INTER_STRING ],
@@ -78,6 +81,7 @@
     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 ],
+    const [ BIGGEST_4_UTF8_UNIT_BYTES, BIGGEST_4_UTF8_UNIT_STRING ],
     ];
 
 List<List> _expandTestPairs() {
diff --git a/tests/lib/convert/utf85_test.dart b/tests/lib/convert/utf85_test.dart
new file mode 100644
index 0000000..3b5edc0
--- /dev/null
+++ b/tests/lib/convert/utf85_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library utf8_test;
+import "package:expect/expect.dart";
+import 'dart:convert';
+
+main() {
+   for (int i = 0; i <= 0x10FFFF; i++) {
+     if (i == UNICODE_BOM_CHARACTER_RUNE) continue;
+     Expect.equals(i,
+        UTF8.decode(UTF8.encode(new String.fromCharCode(i))).runes.first);
+   }
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 4276ffc..61ba7ee 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -40,6 +40,10 @@
 mirrors/redirecting_factory_test/02: RuntimeError # Issue 6490
 mirrors/closures_test/none: RuntimeError # Issue 6490
 mirrors/library_metadata2_test/01: CompileTimeError # Issue 13633
+async/stream_controller_async_test: Pass, Fail # Issue 13608
+
+[ $compiler == dart2js && $checked ]
+mirrors/redirection_type_shuffling_test: RuntimeError # Issue 13706
 
 [ $runtime == safari ]
 mirrors/return_type_test: Pass, Timeout # Issue 12858
@@ -138,9 +142,6 @@
 mirrors/hierarchy_test: Fail # TODO(ahe): This test is slightly broken. http://dartbug.com/12464
 mirrors/mixin_test/01: Fail, OK # TODO(ahe): Slight broken test to ensure test coverage on dart2js.
 mirrors/typedef_test/01: Fail, OK # Incorrect dart2js behavior.
-mirrors/redirecting_factory_test/none: Fail # Issue 13365
-mirrors/redirecting_factory_test/01: Fail # Issue 13365
-mirrors/redirecting_factory_test/02: Fail # Issue 13365
 mirrors/closures_test/01: Fail, OK # Incorrect dart2js behavior.
 
 [ $compiler == none && $runtime == drt ]
@@ -179,11 +180,23 @@
 mirrors/typevariable_mirror_metadata_test: Fail # Issue 13510
 
 [ $compiler == dart2analyzer ]
-mirrors/library_metadata2_test/01: Fail # http://dartbug.com/12950
 mirrors/typedef_test/none: Fail # Issue 13093
 mirrors/generics_test/none: Fail # Issue 13432
+mirrors/invoke_named_test/none: Fail # http://dartbug.com/13612
 
 mirrors/parameter_metadata_test: Fail # Issue 13510
 mirrors/method_mirror_returntype_test: Fail # Issue 13510
 mirrors/function_type_mirror_test: Fail # Issue 13510
 mirrors/typevariable_mirror_metadata_test: Fail # Issue 13510
+
+[ $compiler == none && $runtime == dartium ]
+async/run_async3_test: Fail # Issue 13719: Please triage this failure.
+async/run_async4_test: Fail # Issue 13719: Please triage this failure.
+async/run_async6_test: Fail # Issue 13719: Please triage this failure.
+async/timer_not_available_test: Fail # Issue 13719: Please triage this failure.
+mirrors/closures_test/01: Fail # Issue 13719: Please triage this failure.
+mirrors/hierarchy_test: Fail # Issue 13719: Please triage this failure.
+mirrors/library_uri_io_test: Fail # Issue 13719: Please triage this failure.
+mirrors/local_isolate_test: Fail # Issue 13719: Please triage this failure.
+mirrors/mixin_test/01: Fail # Issue 13719: Please triage this failure.
+mirrors/typedef_test/01: Fail # Issue 13719: Please triage this failure.
diff --git a/tests/lib/mirrors/circular_factory_redirection_test.dart b/tests/lib/mirrors/circular_factory_redirection_test.dart
new file mode 100644
index 0000000..a7b1882
--- /dev/null
+++ b/tests/lib/mirrors/circular_factory_redirection_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+class A {
+  A();
+  A.circular() = B.circular;  /// 01: compile-time error
+  const A.circular2() = B.circular2;  /// 02: compile-time error
+}
+class B {
+  B();
+  B.circular() = C.circular;  /// 01: continued
+  const B.circular2() = C.circular2;  /// 02: continued
+}
+class C {
+  C();
+  C.circular() = A.circular;  /// 01: continued
+  const C.circular2() = A.circular2;  /// 02: continued
+}
+
+main() {
+  ClassMirror cm = reflectClass(A);
+
+  new A.circular();  /// 01: continued
+  new A.circular2();  /// 02: continued
+
+  Expect.throws(() => cm.newInstance(#circular, []),
+                (e) => e is NoSuchMethodError,
+                'Should disallow circular redirection (non-const)');
+
+  Expect.throws(() => cm.newInstance(#circular2, []),
+                (e) => e is NoSuchMethodError,
+                'Should disallow circular redirection (const)');
+}
diff --git a/tests/lib/mirrors/redirecting_factory_test.dart b/tests/lib/mirrors/redirecting_factory_test.dart
index 1d0059f..6509069 100644
--- a/tests/lib/mirrors/redirecting_factory_test.dart
+++ b/tests/lib/mirrors/redirecting_factory_test.dart
@@ -14,14 +14,14 @@
   factory Class.redirectingFactoryNoOptional(a, b) = Class.factoryNoOptional;
 
   factory Class.factoryUnnamedOptional(a, [b = 42]) => new Class<T1, T2>(a - b);
-  factory Class.redirectingFactoryUnnamedOptional(a, [b]) =
+  factory Class.redirectingFactoryUnnamedOptional(a, [b = 5]) =
       Class.factoryUnnamedOptional;
 
-  factory Class.factoryNamedOptional(a, {b: 0}) {
+  factory Class.factoryNamedOptional(a, {b: 42}) {
     return new Class<T1, T2>(a - b);
   }
 
-  factory Class.redirectingFactoryNamedOptional(a, {b: 42}) =
+  factory Class.redirectingFactoryNamedOptional(a, {b: 5}) =
       Class.factoryNamedOptional;
 
   factory Class.factoryMoreNamedOptional(a, {b: 0, c: 2}) {
diff --git a/tests/lib/mirrors/redirection_type_shuffling_test.dart b/tests/lib/mirrors/redirection_type_shuffling_test.dart
new file mode 100644
index 0000000..582b414
--- /dev/null
+++ b/tests/lib/mirrors/redirection_type_shuffling_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+class G<A extends int, B extends String> {
+  G();
+  factory G.swap() = G<B,A>;  /// static type warning
+  factory G.retain() = G<A,B>;
+}
+
+bool get inCheckedMode {
+  try {
+    var i = 1;
+    String s = i;
+    return false;
+  } catch(e) {
+    return true;
+  }
+}
+
+main() {
+  ClassMirror cm = reflect(new G<int, String>()).type;
+
+  if (inCheckedMode) {
+    Expect.throws(() => cm.newInstance(#swap, []),
+                  (e) => e is MirroredCompilationError,
+                  'Checked mode should not allow violation of type bounds');
+  } else {
+    Expect.isTrue(cm.newInstance(#swap, []).reflectee is G<String,int>);
+  }
+
+  Expect.isTrue(cm.newInstance(#retain, []).reflectee is G<int,String>);
+}
diff --git a/tests/standalone/debugger/step_in_equals_test.dart b/tests/standalone/debugger/step_in_equals_test.dart
new file mode 100644
index 0000000..0e10e5d
--- /dev/null
+++ b/tests/standalone/debugger/step_in_equals_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "debug_lib.dart";
+
+class MyClass {
+  operator ==(other) {
+    print(other);
+    return true;  // Breakpoint #3.
+  }
+}
+
+main() {
+  if (RunScript(testScript)) return;
+  var a = new MyClass();
+  var b = null;
+  var x = a == b;  // Breakpoint #1.
+  print(x);
+  b = 123;
+  a == b;  // Breakpoint #2.
+  print("after 2");
+  if (a == null) {  // Breakpoint #4.
+    throw "unreachable";
+  }
+  print("after 4");
+  if (null == a) {
+    throw "unreachable";
+  }
+  print("ok");
+}
+
+var testScript = [
+  MatchFrames(["main"]),
+  SetBreakpoint(18),
+  SetBreakpoint(21),
+  SetBreakpoint(10),
+  SetBreakpoint(23),
+  Resume(),
+  MatchFrames(["main"]),  // At breakpoint #1.
+  StepInto(),
+  MatchFrames(["main"]),  // Don't step into == method because of null.
+  Resume(),
+  MatchFrames(["main"]), // At breakpoint #2.
+  StepInto(),
+  StepInto(),
+  MatchFrames(["MyClass.==", "main"]),  // At MyClass.== entry.
+  Resume(),
+  MatchFrames(["MyClass.==", "main"]),  // At breakpoint #3.
+  Resume(),
+  MatchFrames(["main"]), // At breakpoint #4.
+  StepInto(),
+  MatchFrames(["main"]), // After breakpoint #4.
+  Step(),
+  MatchFrames(["main"]), // At null == a.
+  StepInto(),
+  MatchFrames(["main"]), // After null == a.
+  Resume()
+];
diff --git a/tests/standalone/float_array_test.dart b/tests/standalone/float_array_test.dart
index 2fe83a2..2be1711 100644
--- a/tests/standalone/float_array_test.dart
+++ b/tests/standalone/float_array_test.dart
@@ -4,6 +4,8 @@
 //
 // Dart test program for testing native float arrays.
 
+// VMOptions=--optimization_counter_threshold=10
+
 // Library tag to be able to run in html test framework.
 library FloatArrayTest;
 
@@ -186,23 +188,34 @@
   a[index] = value;
 }
 
+testPolymorphicLoad(var list) {
+  return list[0];
+}
+
 main() {
   var a32 = new Float32List(5);
-  for (int i = 0; i < 2000; i++) {
+  for (int i = 0; i < 20; i++) {
     testCreateFloat32Array();
     testSetRange32();
     testIndexOutOfRange32();
     testIndexOf32();
     storeIt32(a32, 1, 2.0);
+    testPolymorphicLoad(a32);
   }
   var a64 = new Float64List(5);
-  for (int i = 0; i < 2000; i++) {
+  for (int i = 0; i < 20; i++) {
     testCreateFloat64Array();
     testSetRange64();
     testIndexOutOfRange64();
     testIndexOf64();
     storeIt64(a64, 1, 2.0);
+    testPolymorphicLoad(a64);
   }
+  var f32x4 = new Float32x4List(5);
+  for (int i = 0; i < 20; i++) {
+    testPolymorphicLoad(f32x4);
+  }
+
   // These two take a long time in checked mode.
   testBadValues32();
   testBadValues64();
diff --git a/tests/standalone/io/directory_test.dart b/tests/standalone/io/directory_test.dart
index aaedf1c..ea1e21c 100644
--- a/tests/standalone/io/directory_test.dart
+++ b/tests/standalone/io/directory_test.dart
@@ -452,9 +452,8 @@
     var os = Platform.operatingSystem;
     if (os == "windows") nestingDepth = 2;
     if (createdDirectories.length < nestingDepth) {
-      temp = new Directory(
-          '${temp.path}/nested_temp_dir_${createdDirectories.length}_');
-      temp.createTemp().then(createPhaseCallback);
+      temp.createTemp('nested_temp_dir_${createdDirectories.length}_')
+          .then(createPhaseCallback);
     } else {
       deletePhaseCallback();
     }
diff --git a/tests/standalone/io/file_system_watcher_test.dart b/tests/standalone/io/file_system_watcher_test.dart
index fef2d6e..41f4948 100644
--- a/tests/standalone/io/file_system_watcher_test.dart
+++ b/tests/standalone/io/file_system_watcher_test.dart
@@ -29,7 +29,7 @@
     throw e;
   });
 
-  runAsync(file.createSync);
+  file.createSync();
 }
 
 
@@ -54,7 +54,7 @@
     throw e;
   });
 
-  runAsync(() => file.writeAsStringSync('a'));
+  file.writeAsStringSync('a');
 }
 
 
@@ -82,7 +82,7 @@
     throw e;
   });
 
-  runAsync(() => file.renameSync(dir.path + '/file2'));
+  file.renameSync(dir.path + '/file2');
 }
 
 
@@ -107,7 +107,7 @@
     throw e;
   });
 
-  runAsync(file.deleteSync);
+  file.deleteSync();
 }
 
 
@@ -130,10 +130,8 @@
     throw e;
   });
 
-  runAsync(() {
-    file.createSync();
-    file.writeAsStringSync('a');
-  });
+  file.createSync();
+  file.writeAsStringSync('a');
 }
 
 
@@ -175,12 +173,10 @@
     state = newState;
   });
 
-  runAsync(() {
-    file.createSync();
-    file.writeAsStringSync('a');
-    file.renameSync(file2.path);
-    file2.deleteSync();
-  });
+  file.createSync();
+  file.writeAsStringSync('a');
+  file.renameSync(file2.path);
+  file2.deleteSync();
 }
 
 
@@ -209,7 +205,7 @@
     throw e;
   });
 
-  runAsync(file.createSync());
+  file.createSync();
 }
 
 
@@ -232,7 +228,7 @@
     throw e;
   });
 
-  runAsync(file.createSync);
+  file.createSync();
 
   new Timer(const Duration(milliseconds: 300), () {
     sub.cancel();
diff --git a/tests/standalone/io/file_test.dart b/tests/standalone/io/file_test.dart
index 3b8c383..4e3cc3d 100644
--- a/tests/standalone/io/file_test.dart
+++ b/tests/standalone/io/file_test.dart
@@ -1082,6 +1082,29 @@
     });
   }
 
+  static void testDoubleAsyncOperation() {
+    asyncTestStarted();
+    var file = new File(Platform.executable).openSync();
+    var completer = new Completer();
+    int done = 0;
+    bool error = false;
+    void getLength() {
+      file.length()
+          .catchError((e) { error = true; })
+          .whenComplete(() {
+            if (++done == 2) {
+              asyncTestDone("testDoubleAsyncOperation");
+              Expect.isTrue(error);
+              file.lengthSync();
+              file.closeSync();
+            }
+          });
+    }
+    getLength();
+    getLength();
+    Expect.throws(() => file.lengthSync());
+  }
+
   static void testLastModifiedSync() {
     var modified = new File(Platform.executable).lastModifiedSync();
     Expect.isTrue(modified is DateTime);
@@ -1300,6 +1323,7 @@
       testRename();
       testRenameSync();
       testLastModified();
+      testDoubleAsyncOperation();
       asyncEnd();
     });
   }
diff --git a/tests/standalone/io/http_server_test.dart b/tests/standalone/io/http_server_test.dart
index b470b4d..f5018b4 100644
--- a/tests/standalone/io/http_server_test.dart
+++ b/tests/standalone/io/http_server_test.dart
@@ -41,6 +41,8 @@
   ServerSocket.bind("127.0.0.1", 0).then((s) {
     socket = s;
     server = new HttpServer.listenOn(socket);
+    Expect.equals(server.address.address, '127.0.0.1');
+    Expect.equals(server.address.host, '127.0.0.1');
     server.listen((HttpRequest request) {
       request.listen(
         (_) {},
@@ -51,6 +53,7 @@
       test(() {
         server.close();
         Expect.throws(() => server.port);
+        Expect.throws(() => server.address);
         socket.close();
         asyncEnd();
       });
diff --git a/tests/standalone/io/print_sync_script.dart b/tests/standalone/io/print_sync_script.dart
new file mode 100644
index 0000000..82f866b
--- /dev/null
+++ b/tests/standalone/io/print_sync_script.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.
+
+import 'dart:io';
+
+String get bigString {
+  var buffer = new StringBuffer();
+  for (var i = 0; i < 1000; i++) {
+    buffer.write(i);
+    for (var i = 0; i < 200; i++) {
+      buffer.write('=');
+    }
+    buffer.writeln();
+  }
+  return buffer.toString();
+}
+
+main() {
+  stdout;  // Be sure to mark stdout as non-blocking.
+  print(bigString);
+}
diff --git a/tests/standalone/io/print_sync_test.dart b/tests/standalone/io/print_sync_test.dart
new file mode 100644
index 0000000..05f8014
--- /dev/null
+++ b/tests/standalone/io/print_sync_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+void main() {
+  asyncStart();
+  Process.run(Platform.executable,
+              [new Uri.file(Platform.script)
+                   .resolve('print_sync_script.dart').toString()])
+      .then((out) {
+        asyncEnd();
+        Expect.equals(1002, out.stdout.split('\n').length);
+      });
+}
diff --git a/tests/standalone/io/regress_7191_script.dart b/tests/standalone/io/regress_7191_script.dart
index 9f7c780..9f6a346 100644
--- a/tests/standalone/io/regress_7191_script.dart
+++ b/tests/standalone/io/regress_7191_script.dart
@@ -16,7 +16,10 @@
       p.stderr.listen((_) { });
       // When receiving data again, kill sub-process and exit.
       subscription.onData((data) {
-        p.kill();
+        // If a SIGTERM is sent before the child-process's main is invoked,
+        // there is a change that the SIGTERM is ignore on Mac OS X. Use
+        // SIGKILL to get around the issue.
+        p.kill(ProcessSignal.SIGKILL);
         p.exitCode.then((_) => exit(0));
       });
       // Close stdout. If handles are incorrectly inherited this will
diff --git a/tests/standalone/io/secure_socket_bad_data_test.dart b/tests/standalone/io/secure_socket_bad_data_test.dart
index 0b6f813..bf7af89 100644
--- a/tests/standalone/io/secure_socket_bad_data_test.dart
+++ b/tests/standalone/io/secure_socket_bad_data_test.dart
@@ -141,17 +141,20 @@
 
 
 Future test(bool hostnameInConnect) {
-  return RawServerSocket.bind(HOST_NAME, 0)
-  .then((server) {
+  return RawServerSocket.bind(HOST_NAME, 0).then((server) {
     server.listen((client) {
       RawSecureSocket.secureServer(client, CERTIFICATE)
-      .then((secureClient) {
-        Expect.throws(() => client.add([0]));
-        return runServer(secureClient);
-      })
-      .then((_) => server.close());
+        .then((secureClient) {
+          Expect.throws(() => client.add([0]));
+          return runServer(secureClient);
+        },
+        onError: (e) {
+          Expect.isTrue(e is HandshakeException);
+          Expect.isTrue(e.toString().contains(
+              'received a record with an incorrect Message Authentication'));
+        })
+        .whenComplete(server.close);
     });
-
     return connectClient(server.port, hostnameInConnect).then(runClient);
   });
 }
diff --git a/tests/standalone/io/socket_ipv6_test.dart b/tests/standalone/io/socket_ipv6_test.dart
index bded728..e3a2e91 100644
--- a/tests/standalone/io/socket_ipv6_test.dart
+++ b/tests/standalone/io/socket_ipv6_test.dart
@@ -5,6 +5,7 @@
 import 'dart:io';
 
 import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
 
 const ANY = InternetAddressType.ANY;
 
@@ -13,6 +14,8 @@
   InternetAddress.lookup("::0", type: ANY).then((serverAddr) {
     InternetAddress.lookup("::1", type: ANY).then((clientAddr) {
         ServerSocket.bind(serverAddr.first, 0).then((server) {
+        Expect.equals('::0', server.address.host);
+        Expect.equals('::', server.address.address);
         server.listen((socket) {
           socket.destroy();
           server.close();
@@ -30,6 +33,8 @@
   asyncStart();
   InternetAddress.lookup("::0", type: ANY).then((serverAddr) {
       ServerSocket.bind(serverAddr.first, 0).then((server) {
+      Expect.equals('::0', server.address.host);
+      Expect.equals('::', server.address.address);
       server.listen((socket) {
         socket.destroy();
         server.close();
@@ -46,6 +51,8 @@
   asyncStart();
   InternetAddress.lookup("::1", type: ANY).then((clientAddr) {
       ServerSocket.bind("127.0.0.1", 0).then((server) {
+      Expect.equals('127.0.0.1', server.address.host);
+      Expect.equals('127.0.0.1', server.address.address);
       server.listen((socket) {
         throw "Unexpected socket";
       });
@@ -60,6 +67,8 @@
 void testIPv4toIPv4() {
   asyncStart();
   ServerSocket.bind("127.0.0.1", 0).then((server) {
+    Expect.equals('127.0.0.1', server.address.host);
+    Expect.equals('127.0.0.1', server.address.address);
     server.listen((socket) {
       socket.destroy();
       server.close();
@@ -87,7 +96,7 @@
 void testIPv4Lookup() {
   asyncStart();
   InternetAddress.lookup("127.0.0.1").then((list) {
-    if (list.length < 0) throw "no addresse";
+    if (list.length < 0) throw "no address";
     for (var entry in list) {
       if (entry.type != InternetAddressType.IP_V4) {
         throw "Wrong IP type";
@@ -104,7 +113,7 @@
         ServerSocket.bind(serverAddr.first, 0, v6Only: true)
             .then((server) {
               server.listen((socket) {
-                throw "Unexpcted socket";
+                throw "Unexpected socket";
               });
               Socket.connect("127.0.0.1", server.port).catchError((error) {
                 server.close();
diff --git a/tests/standalone/io/web_socket_error_test.dart b/tests/standalone/io/web_socket_error_test.dart
new file mode 100644
index 0000000..439ad1d
--- /dev/null
+++ b/tests/standalone/io/web_socket_error_test.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// VMOptions=
+// VMOptions=--short_socket_read
+// VMOptions=--short_socket_write
+// VMOptions=--short_socket_read --short_socket_write
+
+library dart.io;
+
+import "dart:async";
+import "dart:io";
+import "dart:math";
+import "dart:typed_data";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import "package:path/path.dart";
+
+part "../../../sdk/lib/io/crypto.dart";
+
+
+const String webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+const String CERT_NAME = 'localhost_cert';
+const String HOST_NAME = 'localhost';
+
+/**
+ * A SecurityConfiguration lets us run the tests over HTTP or HTTPS.
+ */
+class SecurityConfiguration {
+  final bool secure;
+
+  SecurityConfiguration({bool this.secure});
+
+  Future<HttpServer> createServer({int backlog: 0}) =>
+      secure ? HttpServer.bindSecure(HOST_NAME,
+                                     0,
+                                     backlog: backlog,
+                                     certificateName: CERT_NAME)
+             : HttpServer.bind(HOST_NAME,
+                               0,
+                               backlog: backlog);
+
+  Future<WebSocket> createClient(int port) =>
+    WebSocket.connect('${secure ? "wss" : "ws"}://$HOST_NAME:$port/');
+
+
+  void testForceCloseServerEnd(int totalConnections) {
+    createServer().then((server) {
+      server.listen((request) {
+        var response = request.response;
+        response.statusCode = HttpStatus.SWITCHING_PROTOCOLS;
+        response.headers.set(HttpHeaders.CONNECTION, "upgrade");
+        response.headers.set(HttpHeaders.UPGRADE, "websocket");
+        String key = request.headers.value("Sec-WebSocket-Key");
+        _SHA1 sha1 = new _SHA1();
+        sha1.add("$key$webSocketGUID".codeUnits);
+        String accept = _CryptoUtils.bytesToBase64(sha1.close());
+        response.headers.add("Sec-WebSocket-Accept", accept);
+        response.headers.contentLength = 0;
+        response.detachSocket().then((socket) {
+          socket.destroy();
+        });
+      });
+
+      int closeCount = 0;
+      for (int i = 0; i < totalConnections; i++) {
+        createClient(server.port).then((webSocket) {
+          webSocket.add("Hello, world!");
+          webSocket.listen(
+              (message) {
+                Expect.fail("unexpected message");
+              },
+              onDone: () {
+                closeCount++;
+                if (closeCount == totalConnections) {
+                  server.close();
+                }
+              });
+          });
+      }
+    });
+  }
+
+  void runTests() {
+    testForceCloseServerEnd(10);
+  }
+}
+
+
+void initializeSSL() {
+  var testPkcertDatabase = join(dirname(Platform.script), 'pkcert');
+  SecureSocket.initialize(database: testPkcertDatabase,
+                          password: "dartdart");
+}
+
+
+main() {
+  asyncStart();
+  new SecurityConfiguration(secure: false).runTests();
+  initializeSSL();
+  new SecurityConfiguration(secure: true).runTests();
+  asyncEnd();
+}
+
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 30a2a3a..f778bf7 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -51,11 +51,7 @@
 io/directory_non_ascii_test: Pass, Fail
 io/process_non_ascii_test: Pass, Fail
 
-[ $runtime == vm ]
-io/http_server_early_client_close_test: Crash, Pass # Issue 12982
-io/secure_socket_bad_data_test: Crash, Pass # 12982
-
-[ $compiler == none && $runtime == drt ]
+[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 typed_data_isolate_test: Skip # This test uses dart:io
 io/*: Skip # Don't run tests using dart:io in the browser
 package/*: Skip # Do not run those in Dartium.
@@ -177,3 +173,8 @@
 io/test_extension_fail_test: Fail
 io/dart_std_io_pipe_test: Fail
 io/file_read_special_device_test: Fail
+
+[ $compiler == none && $runtime == dartium ]
+assert_test: Fail # Issue 13719: Please triage this failure.
+javascript_int_overflow_literal_test/01: Fail # Issue 13719: Please triage this failure.
+javascript_int_overflow_test: Fail # Issue 13719: Please triage this failure.
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index f2e6744..ab84052 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -22,3 +22,8 @@
 
 [ $compiler == none && $runtime == drt && $system == linux ]
 png_layout_test: Fail # Issue 13540
+
+[ $compiler == none && $runtime == dartium ]
+dart2js_test: Skip # Uses dart:io.
+png_layout_test: Skip # dartium doesn't support layout tests
+txt_layout_test: Skip # dartium doesn't support layout tests
diff --git a/tools/VERSION b/tools/VERSION
index 7dc526d..0a86806 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
-MINOR 7
-BUILD 6
-PATCH 4
+MINOR 8
+BUILD 0
+PATCH 0
diff --git a/tools/bots/compiler.py b/tools/bots/compiler.py
index f4264ab..b64ed3e 100644
--- a/tools/bots/compiler.py
+++ b/tools/bots/compiler.py
@@ -20,6 +20,7 @@
 
 import bot
 
+DARTIUM_BUILDER = r'none-dartium-(linux|mac|windows)'
 DART2JS_BUILDER = (
     r'dart2js-(linux|mac|windows)(-(jsshell))?-(debug|release)(-(checked|host-checked))?(-(host-checked))?(-(minified))?(-(x64))?-?(\d*)-?(\d*)')
 WEB_BUILDER = (
@@ -45,6 +46,7 @@
 
   dart2js_pattern = re.match(DART2JS_BUILDER, builder_name)
   web_pattern = re.match(WEB_BUILDER, builder_name)
+  dartium_pattern = re.match(DARTIUM_BUILDER, builder_name)
 
   if web_pattern:
     compiler = 'dart2js'
@@ -81,6 +83,11 @@
       arch = 'x64'
     shard_index = dart2js_pattern.group(13)
     total_shards = dart2js_pattern.group(14)
+  elif dartium_pattern:
+    compiler = 'none'
+    runtime = 'dartium'
+    mode = 'release'
+    system = dartium_pattern.group(1)
   else :
     return None
 
@@ -104,7 +111,8 @@
 
 
 def NeedsXterm(compiler, runtime):
-  return runtime in ['ie9', 'ie10', 'chrome', 'safari', 'opera', 'ff', 'drt']
+  return runtime in ['ie9', 'ie10', 'chrome', 'safari', 'opera', 'ff', 'drt',
+                     'dartium']
 
 
 def TestStepName(name, flags):
@@ -117,9 +125,9 @@
 # supported platforms.
 def UseBrowserController(runtime, system):
   supported_platforms = {
-    'linux': ['ff', 'chromeOnAndroid', 'chrome'],
-    'mac': ['safari', 'chrome'],
-    'windows': ['ie9', 'ie10', 'ff', 'chrome']
+    'linux': ['ff', 'chromeOnAndroid', 'chrome', 'dartium'],
+    'mac': ['safari', 'chrome', 'dartium'],
+    'windows': ['ie9', 'ie10', 'ff', 'chrome', 'dartium']
   }
   # Platforms that we run on the fyi waterfall only.
   fyi_supported_platforms = {
@@ -187,7 +195,8 @@
     bot.RunProcess(cmd)
 
 
-def TestCompiler(runtime, mode, system, flags, is_buildbot, test_set, arch):
+def TestCompiler(runtime, mode, system, flags, is_buildbot, test_set, arch,
+                 compiler=None):
   """ test the compiler.
    Args:
      - runtime: either 'd8', 'jsshell', or one of the browsers, see GetBuildInfo
@@ -198,8 +207,12 @@
        emulating one.
      - test_set: Specification of a non standard test set, default None
      - arch: The architecture to run on.
+     - compiler: The compiler to use for test.py (default is 'dart2js').
   """
 
+  if not compiler:
+    compiler = 'dart2js'
+
   def GetPath(runtime):
     """ Helper to get the path to the Chrome or Firefox executable for a
     particular platform on the buildbot. Throws a KeyError if runtime is not
@@ -219,7 +232,8 @@
           'Local', 'Google', 'Chrome', 'Application', 'chrome.exe')}
     return path_dict[runtime]
 
-  if (runtime == 'ff' or runtime == 'chrome') and is_buildbot:
+  if (compiler == 'dart2js' and (runtime == 'ff' or runtime == 'chrome')
+      and is_buildbot):
     # Print out browser version numbers if we're running on the buildbot (where
     # we know the paths to these browser installations).
     version_query_string = '"%s" --version' % GetPath(runtime)
@@ -248,23 +262,26 @@
     TestStep("dart2js_unit", mode, system, 'none', 'vm', ['dart2js'],
              unit_test_flags, arch)
 
-  if system == 'windows' and runtime == 'ie10':
-    TestStep("dart2js", mode, system, 'dart2js', runtime, ['html'], flags, arch)
+  if compiler == 'dart2js' and system == 'windows' and runtime == 'ie10':
+    TestStep("%s-%s" % (compiler, runtime), mode, system, compiler, runtime,
+             ['html'], flags, arch)
   else:
     # Run the default set of test suites.
-    TestStep("dart2js", mode, system, 'dart2js', runtime, [], flags, arch)
+    TestStep("%s-%s" % (compiler, runtime), mode, system, compiler,
+             runtime, [], flags, arch)
 
-    # TODO(kasperl): Consider running peg and css tests too.
-    extras = ['dart2js_extra', 'dart2js_native']
-    extras_flags = flags
-    if (system == 'linux'
-        and runtime == 'd8'
-        and not '--host-checked' in extras_flags):
-      # Run the extra tests in checked mode, but only on linux/d8.
-      # 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, arch)
+    if compiler == 'dart2js':
+      # TODO(kasperl): Consider running peg and css tests too.
+      extras = ['dart2js_extra', 'dart2js_native']
+      extras_flags = flags
+      if (system == 'linux'
+          and runtime == 'd8'
+          and not '--host-checked' in extras_flags):
+        # Run the extra tests in checked mode, but only on linux/d8.
+        # 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, arch)
 
 
 def _DeleteTempWebdriverProfiles(directory):
@@ -364,13 +381,14 @@
 
   TestCompiler(build_info.runtime, build_info.mode, build_info.system,
                list(test_flags), build_info.is_buildbot, build_info.test_set,
-               build_info.arch)
+               build_info.arch, compiler=build_info.compiler)
 
   # 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.arch)
+                 build_info.test_set, build_info.arch,
+                 compiler=build_info.compiler)
 
   if build_info.runtime != 'd8':
     CleanUpTemporaryFiles(build_info.system, build_info.runtime)
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 3bb58bc..ef81ebd 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -11,7 +11,8 @@
 import monitored
 import os
 import re
-from htmlrenamer import html_interface_renames, typed_array_renames
+from htmlrenamer import custom_html_constructors, html_interface_renames, \
+    typed_array_renames
 
 _pure_interfaces = monitored.Set('generator._pure_interfaces', [
     # TODO(sra): DOMStringMap should be a class implementing Map<String,String>.
@@ -313,7 +314,8 @@
   info.idl_args = idl_args
   info.declared_name = name
   info.name = name
-  info.constructor_name = None
+  info.constructor_name = ('_' if interface.id in custom_html_constructors
+      else None)
   info.js_name = name
   info.type_name = interface.id
   info.param_infos = _BuildArguments(idl_args, interface, constructor=True)
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 7b7ca8e..97fa1ba 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -11,9 +11,9 @@
     DartDomNameOfAttribute, FindMatchingAttribute, \
     TypeOrNothing, ConvertToFuture, GetCallbackInfo
 from copy import deepcopy
-from htmlrenamer import convert_to_future_members, keep_overloaded_members, \
-    private_html_members, dom_private_html_members, renamed_html_members, renamed_overloads, \
-    removed_html_members
+from htmlrenamer import convert_to_future_members, custom_html_constructors, \
+    keep_overloaded_members, private_html_members, dom_private_html_members, renamed_html_members, \
+    renamed_overloads, removed_html_members
 import logging
 import monitored
 import sys
@@ -598,7 +598,8 @@
     if not self._members_emitter:
       return
 
-    if base_class != self.RootClassName():
+    if (base_class != self.RootClassName() and
+          self._interface.id not in custom_html_constructors):
       self._members_emitter.Emit(
           '  // To suppress missing implicit constructor warnings.\n'
           '  factory $CLASSNAME._() { '
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 791591b..7f85044 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -161,6 +161,13 @@
   'EventTarget.removeEventListener',
 ])
 
+# Classes where we have customized constructors, but we need to keep the old
+# constructor for dispatch purposes.
+custom_html_constructors = monitored.Set(
+    'htmlrenamer.custom_html_constructors', [
+  'HTMLOptionElement',
+])
+
 # Members from the standard dom that should not be exposed publicly in dart:html
 # but need to be exposed internally to implement dart:html on top of a standard
 # browser. They are exposed simply by placing an underscore in front of the
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 7c5ec12..8c5aa83 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -593,6 +593,20 @@
     self._backend.AddConstructors(
         constructors, factory_provider, factory_constructor_name)
 
+    isElement = False
+    for parent in self._database.Hierarchy(self._interface):
+      if parent.id == 'Element':
+        isElement = True
+    if isElement and self._interface.id != 'Element':
+      self._implementation_members_emitter.Emit(
+          '  /**\n'
+          '   * Constructor instantiated by the DOM when a custom element has been created.\n'
+          '   *\n'
+          '   * This can only be called by subclasses from their created constructor.\n'
+          '   */\n'
+          '  $CLASSNAME.created() : super.created();\n',
+          CLASSNAME=self._interface_type_info.implementation_name())
+
     self._backend.EmitSupportCheck()
 
     merged_interface = self._interface_type_info.merged_interface()
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index 8dbe0e2..1235e80 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -551,7 +551,8 @@
         [attr],
         'void',
         False,
-        'SetterRaisesException' in attr.ext_attrs)
+        'SetterRaisesException' in attr.ext_attrs,
+        requires_custom_element_callback=True)
 
   def AddIndexer(self, element_type):
     """Adds all the methods required to complete implementation of List."""
@@ -730,7 +731,8 @@
       arguments,
       return_type,
       return_type_is_nullable,
-      raises_dom_exception):
+      raises_dom_exception,
+      requires_custom_element_callback=False):
 
     ext_attrs = node.ext_attrs
 
@@ -789,7 +791,7 @@
     if 'Reflect' in ext_attrs:
       cpp_arguments = [self._GenerateWebCoreReflectionAttributeName(node)]
 
-    if ext_attrs.get('CustomElementCallbacks') == 'Enable':
+    if ext_attrs.get('CustomElementCallbacks') == 'Enable' or requires_custom_element_callback:
       self._cpp_impl_includes.add('"core/dom/CustomElementCallbackDispatcher.h"')
       needs_custom_element_callbacks = True
 
diff --git a/tools/dom/src/dart2js_CustomElementSupport.dart b/tools/dom/src/dart2js_CustomElementSupport.dart
index aa2c8f0..a3fa0bf 100644
--- a/tools/dom/src/dart2js_CustomElementSupport.dart
+++ b/tools/dom/src/dart2js_CustomElementSupport.dart
@@ -5,7 +5,7 @@
 part of dart.dom.html;
 
 _callCreated(receiver) {
-  return receiver.created();
+  return receiver.createdCallback();
 }
 
 _callEnteredView(receiver) {
@@ -15,6 +15,9 @@
 _callLeftView(receiver) {
   return receiver.leftView();
 }
+ _callAttributeChanged(receiver, name, oldValue, newValue) {
+  return receiver.attributeChanged(name, oldValue, newValue);
+}
 
 _makeCallbackMethod(callback) {
   return JS('',
@@ -26,6 +29,16 @@
       convertDartClosureToJS(callback, 1));
 }
 
+_makeCallbackMethod3(callback) {
+  return JS('',
+      '''((function(invokeCallback) {
+             return function(arg1, arg2, arg3) {
+               return invokeCallback(this, arg1, arg2, arg3);
+             };
+          })(#))''',
+      convertDartClosureToJS(callback, 4));
+}
+
 const _typeNameToTag = const {
   'HTMLAnchorElement': 'a',
   'HTMLAudioElement': 'audio',
@@ -91,6 +104,8 @@
       JS('=Object', '{value: #}', _makeCallbackMethod(_callEnteredView)));
   JS('void', '#.leftViewCallback = #', properties,
       JS('=Object', '{value: #}', _makeCallbackMethod(_callLeftView)));
+  JS('void', '#.attributeChangedCallback = #', properties,
+      JS('=Object', '{value: #}', _makeCallbackMethod3(_callAttributeChanged)));
 
   // TODO(blois): Bug 13220- remove once transition is complete
   JS('void', '#.enteredDocumentCallback = #', properties,
@@ -117,3 +132,8 @@
 
   JS('void', '#.register(#, #)', document, tag, options);
 }
+
+//// Called by Element.created to do validation & initialization.
+void _initializeCustomElement(Element e) {
+  // TODO(blois): Add validation that this is only in response to an upgrade.
+}
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index 8991ee1..2c82ddd 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -106,7 +106,6 @@
 
   static window() native "Utils_window";
   static forwardingPrint(String message) native "Utils_forwardingPrint";
-  static void spawnDomFunction(Function f, int replyTo) native "Utils_spawnDomFunction";
   static int _getNewIsolateId() native "Utils_getNewIsolateId";
 
   // The following methods were added for debugger integration to make working
@@ -289,6 +288,10 @@
     if (_isBuiltinType(cls)) {
       throw new UnsupportedError("Invalid custom element from $libName.");
     }
+    var className = MirrorSystem.getName(cls.simpleName);
+    if (!cls.constructors.containsKey(new Symbol('$className.created'))) {
+      throw new UnsupportedError('Class is missing constructor $className.created');
+    }
     _register(document, tag, type, extendsTagName);
   }
 
@@ -296,13 +299,8 @@
       String extendsTagName) native "Utils_register";
 
   static Element createElement(Document document, String tagName) native "Utils_createElement";
-}
 
-class _NPObject extends NativeFieldWrapperClass1 {
-  _NPObject.internal();
-  static _NPObject retrieve(String key) native "NPObject_retrieve";
-  property(String propertyName) native "NPObject_property";
-  invoke(String methodName, [List args = null]) native "NPObject_invoke";
+  static void initializeCustomElement(HtmlElement element) native "Utils_initializeCustomElement";
 }
 
 class _DOMWindowCrossFrame extends NativeFieldWrapperClass1 implements
@@ -366,79 +364,10 @@
   bool get isNotEmpty => Maps.isNotEmpty(this);
 }
 
-// TODO(vsm): Remove DOM isolate code.  This is only used to support
-// printing and timers in background isolates.  Background isolates
-// should just forward to the main DOM isolate instead of requiring a
-// special DOM isolate.
-
-_makeSendPortFuture(spawnRequest) {
-  final completer = new Completer<SendPort>.sync();
-  final port = new ReceivePort();
-  port.receive((result, _) {
-    completer.complete(result);
-    port.close();
-  });
-  // TODO: SendPort.hashCode is ugly way to access port id.
-  spawnRequest(port.toSendPort().hashCode);
-  return completer.future;
-}
-
-Future<SendPort> _spawnDomFunction(Function f) =>
-    _makeSendPortFuture((portId) { _Utils.spawnDomFunction(f, portId); });
-
-final Future<SendPort> __HELPER_ISOLATE_PORT =
-    _spawnDomFunction(_helperIsolateMain);
-
-// Tricky part.
-// Once __HELPER_ISOLATE_PORT gets resolved, it will still delay in .then
-// and to delay Timer.run is used. However, Timer.run will try to register
-// another Timer and here we got stuck: event cannot be posted as then
-// callback is not executed because it's delayed with timer.
-// Therefore once future is resolved, it's unsafe to call .then on it
-// in Timer code.
-SendPort __SEND_PORT;
-
-_sendToHelperIsolate(msg, SendPort replyTo) {
-  if (__SEND_PORT != null) {
-    __SEND_PORT.send(msg, replyTo);
-  } else {
-    __HELPER_ISOLATE_PORT.then((port) {
-      __SEND_PORT = port;
-      __SEND_PORT.send(msg, replyTo);
-    });
-  }
-}
-
-final _TIMER_REGISTRY = new Map<SendPort, Timer>();
-
-const _NEW_TIMER = 'NEW_TIMER';
-const _CANCEL_TIMER = 'CANCEL_TIMER';
-const _TIMER_PING = 'TIMER_PING';
-const _PRINT = 'PRINT';
-
-_helperIsolateMain() {
-  port.receive((msg, replyTo) {
-    final cmd = msg[0];
-    if (cmd == _NEW_TIMER) {
-      final duration = new Duration(milliseconds: msg[1]);
-      bool periodic = msg[2];
-      ping() { replyTo.send(_TIMER_PING); };
-      _TIMER_REGISTRY[replyTo] = periodic ?
-          new Timer.periodic(duration, (_) { ping(); }) :
-          new Timer(duration, ping);
-    } else if (cmd == _CANCEL_TIMER) {
-      _TIMER_REGISTRY.remove(replyTo).cancel();
-    } else if (cmd == _PRINT) {
-      final message = msg[1];
-      // TODO(antonm): we need somehow identify those isolates.
-      print('[From isolate] $message');
-    }
-  });
-}
-
 final _printClosure = window.console.log;
 final _pureIsolatePrintClosure = (s) {
-  _sendToHelperIsolate([_PRINT, s], null);
+  throw new UnimplementedError("Printing from a background isolate "
+                               "is not supported in the browser");
 };
 
 final _forwardingPrintClosure = _Utils.forwardingPrint;
@@ -477,43 +406,11 @@
   return new _Timer(milliSeconds, callback, repeating);
 };
 
-
-class _PureIsolateTimer implements Timer {
-  bool _isActive = true;
-  final ReceivePort _port = new ReceivePort();
-  SendPort _sendPort; // Effectively final.
-
-  static SendPort _SEND_PORT;
-
-  _PureIsolateTimer(int milliSeconds, callback, repeating) {
-    _sendPort = _port.toSendPort();
-    _port.receive((msg, replyTo) {
-      assert(msg == _TIMER_PING);
-      _isActive = repeating;
-      callback(this);
-      if (!repeating) _cancel();
-    });
-
-    _send([_NEW_TIMER, milliSeconds, repeating]);
-  }
-
-  void cancel() {
-    _cancel();
-    _send([_CANCEL_TIMER]);
-  }
-
-  void _cancel() {
-    _isActive = false;
-    _port.close();
-  }
-
-  _send(msg) {
-    _sendToHelperIsolate(msg, _sendPort);
-  }
-
-  bool get isActive => _isActive;
-}
-
 get _pureIsolateTimerFactoryClosure =>
     ((int milliSeconds, void callback(Timer time), bool repeating) =>
-        new _PureIsolateTimer(milliSeconds, callback, repeating));
+  throw new UnimplementedError("Timers on background isolates "
+                               "are not supported in the browser"));
+
+void _initializeCustomElement(Element e) {
+  _Utils.initializeCustomElement(e);
+}
diff --git a/tools/dom/src/native_DOMPublic.dart b/tools/dom/src/native_DOMPublic.dart
deleted file mode 100644
index f38c63d..0000000
--- a/tools/dom/src/native_DOMPublic.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of html;
-
-// testRunner implementation.
-// FIXME: provide a separate lib for testRunner.
-
-var _testRunner;
-
-TestRunner get testRunner {
-  if (_testRunner == null)
-    _testRunner = new TestRunner._(_NPObject.retrieve("testRunner"));
-  return _testRunner;
-}
-
-class TestRunner {
-  final _NPObject _npObject;
-
-  TestRunner._(this._npObject);
-
-  display() => _npObject.invoke('display');
-  dumpAsText() => _npObject.invoke('dumpAsText');
-  notifyDone() => _npObject.invoke('notifyDone');
-  setCanOpenWindows() => _npObject.invoke('setCanOpenWindows');
-  waitUntilDone() => _npObject.invoke('waitUntilDone');
-}
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index bf62f8b..554ad3f 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -119,8 +119,20 @@
 // Dart issue 1990.
 class HtmlElement extends Element native "HTMLElement" {
   factory HtmlElement() { throw new UnsupportedError("Not supported"); }
+
+  /**
+   * Constructor instantiated by the DOM when a custom element has been created.
+   *
+   * This can only be called by subclasses from their created constructor.
+   */
+  HtmlElement.created() : super.created();
 }
 
+// EntryArray type was removed, so explicitly adding it to allow support for
+// older Chrome versions.
+// Issue #12573.
+abstract class _EntryArray implements List<Entry> native "EntryArray" {}
+
 // Support for Send/ReceivePortSync.
 int _getNewIsolateId() {
   if (JS('bool', r'!window.$dart$isolate$counter')) {
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index cde3552..ca7cc03 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -81,7 +81,6 @@
 part '$AUXILIARY_DIR/dartium_KeyEvent.dart';
 part '$AUXILIARY_DIR/dartium_Platform.dart';
 
-part '$AUXILIARY_DIR/native_DOMPublic.dart';
 part '$AUXILIARY_DIR/native_DOMImplementation.dart';
 
 Window _window;
diff --git a/tools/dom/templates/html/impl/impl_Document.darttemplate b/tools/dom/templates/html/impl/impl_Document.darttemplate
index 7cc7f09..3e66c9c 100644
--- a/tools/dom/templates/html/impl/impl_Document.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Document.darttemplate
@@ -9,7 +9,6 @@
 {
 
 $!MEMBERS
-
   /**
    * Finds all descendant elements of this document that match the specified
    * group of selectors.
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 5732c1e..100e017 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -334,6 +334,30 @@
   }
 
   /**
+   * Custom element creation constructor.
+   *
+   * This constructor is used by the DOM when a custom element has been
+   * created. It can only be invoked by subclasses of Element from
+   * that classes created constructor.
+   *
+   *     class CustomElement extends Element {
+   *       factory CustomElement() => new Element.tag('x-custom');
+   *
+   *       CustomElement.created() : super.created() {
+   *          // Perform any element initialization.
+   *       }
+   *     }
+   *     document.register('x-custom', CustomElement);
+   */
+  Element.created() : super._created() {
+    // Validate that this is a custom element & perform any additional
+    // initialization.
+    _initializeCustomElement(this);
+
+    createdCallback();
+  }
+
+  /**
    * Creates the HTML element specified by the tag name.
    *
    * This is similar to [Document.createElement].
@@ -676,9 +700,12 @@
 
   /**
    * Called by the DOM when this element has been instantiated.
+   *
+   * Will be replaced by created constructor.
    */
   @Experimental()
-  void created() {}
+  @deprecated
+  void createdCallback() {}
 
   /**
    * Called by the DOM when this element has been inserted into the live
@@ -694,6 +721,11 @@
   @Experimental()
   void leftView() {}
 
+  /**
+   * Called by the DOM whenever an attribute on this has been changed.
+   */
+  void attributeChanged(String name, String oldValue, String newValue) {}
+
   // Hooks to support custom WebComponents.
 
 $if DART2JS
diff --git a/tools/dom/templates/html/impl/impl_EventTarget.darttemplate b/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
index 60f8fcc..06b24fb 100644
--- a/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
+++ b/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
@@ -60,6 +60,9 @@
  */
 $(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 
+  // Custom element created callback.
+  EventTarget._created();
+
   /**
    * This is an ease-of-use accessor for event streams which should only be
    * used when an explicit accessor is not available.
diff --git a/tools/dom/templates/html/impl/impl_HTMLOptionElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLOptionElement.darttemplate
new file mode 100644
index 0000000..b40c7be
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_HTMLOptionElement.darttemplate
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of $LIBRARYNAME;
+
+$(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+  factory OptionElement({String data, String value, bool defaultSelected, 
+      bool selected}) {
+    return new OptionElement._(data, value, defaultSelected, selected);
+  }
+$!MEMBERS
+}
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index 8f2fc4a..b93bbc7 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -201,6 +201,10 @@
 
 
 $(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
+
+  // Custom element created callback.
+  Node._created() : super._created();
+
   List<Node> get nodes {
     return new _ChildNodeListLazy(this);
   }
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index 646d6c3..642ce56 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -87,7 +87,7 @@
   }
 
   /**
-   * Creates a URL request for the specified [url].
+   * Creates and sends a URL request for the specified [url].
    *
    * By default `request` will perform an HTTP GET request, but a different
    * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the 
diff --git a/tools/full-coverage.dart b/tools/full-coverage.dart
new file mode 100644
index 0000000..b48da50
--- /dev/null
+++ b/tools/full-coverage.dart
@@ -0,0 +1,485 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "dart:convert";
+import "dart:io";
+import "dart:isolate";
+import "dart:mirrors";
+
+import "package:args/args.dart";
+import "package:path/path.dart";
+
+/// [Environment] stores gathered arguments information.
+class Environment {
+  String sdkRoot;
+  String pkgRoot;
+  var input;
+  var output;
+  int workers;
+  bool prettyPrint;
+  bool lcov;
+  bool expectMarkers;
+  bool verbose;
+}
+
+/// [Resolver] resolves imports with respect to a given environment.
+class Resolver {
+  const DART_PREFIX = "dart:";
+  const PACKAGE_PREFIX = "package:";
+  const FILE_PREFIX = "file://";
+  const HTTP_PREFIX = "http://";
+
+  Map _env;
+  List failed = [];
+
+  Resolver(this._env);
+
+  /// Returns the absolute path wrt. to the given environment or null, if the
+  /// import could not be resolved.
+  resolve(String import) {
+    if (import.startsWith(DART_PREFIX)) {
+      var slashPos = import.indexOf("/");
+      var filePath;
+      if (slashPos != -1) {
+        var path = import.substring(DART_PREFIX.length, slashPos);
+        // Drop patch files, since we don't have their source in the compiled
+        // SDK.
+        if (path.endsWith("-patch")) {
+          failed.add(import);
+          return null;
+        }
+        // Canonicalize path. For instance: _collection-dev => _collection_dev.
+        path = path.replaceAll("-", "_");
+        filePath = "${_env["sdkRoot"]}"
+                   "/${path}${import.substring(slashPos, import.length)}";
+      } else {
+        // Resolve 'dart:something' to be something/something.dart in the SDK.
+        var lib = import.substring(DART_PREFIX.length, import.length);
+        filePath = "${_env["sdkRoot"]}/${lib}/${lib}.dart";
+      }
+      return filePath;
+    }
+    if (import.startsWith(PACKAGE_PREFIX)) {
+      var filePath =
+          "${_env["pkgRoot"]}"
+          "/${import.substring(PACKAGE_PREFIX.length, import.length)}"; 
+      return filePath;
+    }
+    if (import.startsWith(FILE_PREFIX)) {
+      var filePath = fromUri(Uri.parse(import));
+      return filePath;
+    }
+    if (import.startsWith(HTTP_PREFIX)) {
+      return import;
+    }
+    // We cannot deal with anything else.
+    failed.add(import);
+    return null;
+  }
+}
+
+/// Converts the given hitmap to lcov format and appends the result to
+/// env.output.
+///
+/// Returns a [Future] that completes as soon as all map entries have been
+/// emitted. 
+Future lcov(Map hitmap) {
+  var emitOne = (key) {
+    var v = hitmap[key];
+    StringBuffer entry = new StringBuffer();
+    entry.write("SF:${key}\n");
+    v.keys.toList()
+          ..sort()
+          ..forEach((k) {
+      entry.write("DA:${k},${v[k]}\n");
+    });
+    entry.write("end_of_record\n");
+    env.output.write(entry.toString());
+    return new Future.value(null);
+  };
+
+  return Future.forEach(hitmap.keys, emitOne);
+}
+
+/// Converts the given hitmap to a pretty-print format and appends the result
+/// to env.output.
+///
+/// Returns a [Future] that completes as soon as all map entries have been
+/// emitted. 
+Future prettyPrint(Map hitMap, List failedLoads) {
+  var emitOne = (key) {
+    var v = hitMap[key];
+    var c = new Completer();
+    loadResource(key).then((lines) {
+      if (lines == null) {
+        failedLoads.add(key);
+        c.complete();
+        return;
+      }
+      env.output.write("${key}\n");
+      for (var line = 1; line <= lines.length; line++) {
+        String prefix = "       ";
+        if (v.containsKey(line)) {
+          prefix = v[line].toString();
+          StringBuffer b = new StringBuffer();
+          for (int i = prefix.length; i < 7; i++) {
+            b.write(" ");
+          }
+          b.write(prefix);
+          prefix = b.toString();
+        }
+        env.output.write("${prefix}|${lines[line-1]}\n");
+      } 
+      c.complete();
+    });
+    return c.future;
+  };
+
+  return Future.forEach(hitMap.keys, emitOne);
+}
+
+/// Load an import resource and return a [Future] with a [List] of its lines.
+/// Returns [null] instead of a list if the resource could not be loaded.
+Future<List> loadResource(String import) {
+  if (import.startsWith("http")) {
+    Completer c = new Completer();
+    HttpClient client = new HttpClient();
+    client.getUrl(Uri.parse(import))
+        .then((HttpClientRequest request) {
+          return request.close();
+        })
+        .then((HttpClientResponse response) {
+          response.transform(new StringDecoder()).toList().then((data) {
+            c.complete(data);
+            httpClient.close();
+          });
+        })
+        .catchError((e) {
+          c.complete(null);
+        });
+    return c.future;
+  } else {
+    File f = new File(import);
+    return f.readAsLines()
+        .catchError((e) {
+          return new Future.value(null);
+        });
+  }
+}
+
+/// Creates a single hitmap from a raw json object. Throws away all entries that
+/// are not resolvable.
+Map createHitmap(String rawJson, Resolver resolver) {
+  Map<String, Map<int,int>> hitMap = {};
+
+  addToMap(source, line, count) {
+    if (!hitMap[source].containsKey(line)) {
+      hitMap[source][line] = 0;
+    }
+    hitMap[source][line] += count;
+  }
+
+  JSON.decode(rawJson).forEach((Map e) {
+    String source = resolver.resolve(e["source"]);
+    if (source == null) { 
+      // Couldnt resolve import, so skip this entry.
+      return;
+    }
+    if (!hitMap.containsKey(source)) {
+      hitMap[source] = {};
+    }
+    var hits = e["hits"];
+    // hits is a flat array of the following format:
+    // [ <line|linerange>, <hitcount>,...]
+    // line: number.
+    // linerange: "<line>-<line>".
+    for (var i = 0; i < hits.length; i += 2) {
+      var k = hits[i];
+      if (k is num) {
+        // Single line.
+        addToMap(source, k, hits[i+1]);
+      }
+      if (k is String) {
+        // Linerange. We expand line ranges to actual lines at this point.
+        var splitPos = k.indexOf("-");
+        int start = int.parse(k.substring(0, splitPos));
+        int end = int.parse(k.substring(splitPos + 1, k.length));
+        for (var j = start; j <= end; j++) {
+          addToMap(source, j, hits[i+1]);
+        }
+      }
+    }
+  });
+  return hitMap;
+}
+
+/// Merges [newMap] into [result].
+mergeHitmaps(Map newMap, Map result) {
+  newMap.forEach((String file, Map v) {
+    if (result.containsKey(file)) {
+      v.forEach((int line, int cnt) {
+        if (result[file][line] == null) {
+          result[file][line] = cnt;
+        } else {
+          result[file][line] += cnt;
+        }
+      }); 
+    } else {
+      result[file] = v;
+    }
+  });
+}
+
+/// Given an absolute path absPath, this function returns a [List] of files
+/// are contained by it if it is a directory, or a [List] containing the file if
+/// it is a file.
+List filesToProcess(String absPath) {
+  if (FileSystemEntity.isDirectorySync(absPath)) {
+    Directory d = new Directory(absPath);
+    List files = [];
+    d.listSync(recursive: true).forEach((FileSystemEntity entity) {
+      if (entity is File) {
+        files.add(entity as File);
+      }
+    });
+    return files;
+  } else if (FileSystemEntity.isFileSync(absPath)) {
+    return [ new File(absPath) ];
+  } 
+}
+
+worker() {
+  final start = new DateTime.now().millisecondsSinceEpoch;
+  String me = currentMirrorSystem().isolate.debugName;
+
+  port.receive((Message message, reply) {
+    if (message.type == Message.SHUTDOWN) {
+      port.close();
+    }
+
+    if (message.type == Message.WORK) {
+      var env = message.payload[0];
+      List files = message.payload[1];
+      Resolver resolver = new Resolver(env);
+      var workerHitmap = {};
+      files.forEach((File fileEntry) {
+        // Read file sync, as it only contains 1 object.
+        String contents = fileEntry.readAsStringSync();
+        if (contents.length > 0) {
+          mergeHitmaps(createHitmap(contents, resolver), workerHitmap);
+        }
+      }); 
+      if (env["verbose"]) {
+        final end = new DateTime.now().millisecondsSinceEpoch;
+        print("worker[${me}]: Finished processing files. "
+              "Took ${end - start} ms.");
+      }
+      reply.send(new Message(Message.RESULT, [workerHitmap, resolver.failed]));
+    }
+
+  });
+}
+
+class Message {
+  static const int SHUTDOWN = 1;
+  static const int RESULT = 2;
+  static const int WORK = 3;
+
+  final int type;
+  final payload;
+
+  Message(this.type, this.payload);
+}
+
+final env = new Environment();
+
+main() {
+  parseArgs();
+
+  List files = filesToProcess(env.input);
+  int filesPerWorker = files.length ~/ env.workers;
+  List workerPorts = [];
+  int doneCnt = 0;
+
+  List failedResolves = [];
+  List failedLoads = [];
+  Map globalHitmap = {};
+  int start = new DateTime.now().millisecondsSinceEpoch;
+
+  if (env.verbose) {
+    print("Environment:");
+    print("  # files: ${files.length}");
+    print("  # workers: ${env.workers}");
+    print("  sdk-root: ${env.sdkRoot}");
+    print("  package-root: ${env.pkgRoot}");
+  }
+
+  port.receive((Message message, reply) {
+    if (message.type == Message.RESULT) {
+      mergeHitmaps(message.payload[0], globalHitmap);  
+      failedResolves.addAll(message.payload[1]);
+      doneCnt++;
+    }
+
+    // All workers are done. Process the data.
+    if (doneCnt == env.workers) {
+      workerPorts.forEach((p) => p.send(new Message(Message.SHUTDOWN, null)));
+      if (env.verbose) {
+        final end = new DateTime.now().millisecondsSinceEpoch;
+        print("Done creating a global hitmap. Took ${end - start} ms.");
+      }
+
+      Future out;
+      if (env.prettyPrint) {
+        out = prettyPrint(globalHitmap, failedLoads);
+      }
+      if (env.lcov) {
+        out = lcov(globalHitmap);
+      }
+
+      out.then((_) {
+        env.output.close().then((_) {
+          if (env.verbose) {
+            final end = new DateTime.now().millisecondsSinceEpoch;
+            print("Done flushing output. Took ${end - start} ms.");
+          }
+        });
+        port.close();
+
+        if (env.verbose) {
+          if (failedResolves.length > 0) {
+            print("Failed to resolve:");
+            failedResolves.toSet().forEach((e) {
+              print("  ${e}");
+            });
+          }
+          if (failedLoads.length > 0) {
+            print("Failed to load:");
+            failedLoads.toSet().forEach((e) {
+              print("  ${e}");
+            });
+          }
+        }
+
+      });
+    }
+  });
+
+  Map sharedEnv = {
+    "sdkRoot": env.sdkRoot,
+    "pkgRoot": env.pkgRoot,
+    "verbose": env.verbose,
+  };
+
+  // Create workers.
+  for (var i = 1; i < env.workers; i++) {
+    var p = spawnFunction(worker);
+    workerPorts.add(p);
+    var start = files.length - filesPerWorker;
+    var end = files.length;
+    var workerFiles = files.getRange(start, end).toList();
+    files.removeRange(start, end);
+    p.send(new Message(Message.WORK, [sharedEnv, workerFiles]), port);
+  }
+  // Let the last worker deal with the rest of the files (which should be only
+  // off by at max (#workers - 1).
+  var p = spawnFunction(worker);
+  workerPorts.add(p);
+  p.send(new Message(Message.WORK, [sharedEnv, files]), port);
+
+  return 0;
+}
+
+/// Checks the validity of the provided arguments. Does not initialize actual
+/// processing.
+parseArgs() {
+  var parser = new ArgParser();
+
+  parser.addOption("sdk-root", abbr: "s",
+                   help: "path to the SDK root");
+  parser.addOption("package-root", abbr: "p",
+                   help: "path to the package root",
+                   defaultsTo: ".");
+  parser.addOption("in", abbr: "i",
+                   help: "input(s): may be file or directory",
+                   defaultsTo: "stdin");
+  parser.addOption("out", abbr: "o",
+                   help: "output: may be file or stdout",
+                   defaultsTo: "stdout");
+  parser.addOption("workers", abbr: "j",
+                   help: "number of workers",
+                   defaultsTo: "1");
+  parser.addFlag("pretty-print", abbr: "r",
+                 help: "convert coverage data to pretty print format",
+                 negatable: false);
+  parser.addFlag("lcov", abbr :"l",
+                 help: "convert coverage data to lcov format",
+                 negatable: false);
+  parser.addFlag("verbose", abbr :"v",
+                 help: "verbose output",
+                 negatable: false);
+  parser.addFlag("help", abbr: "h",
+                 help: "show this help",
+                 negatable: false);
+
+  var args = parser.parse(new Options().arguments);
+
+  if (args["help"]) {
+    print("Usage: coverage [OPTION...]\n");
+    print(parser.getUsage());
+    exit(0);
+  }
+
+  if (args["sdk-root"] == null) {
+    if (Platform.environment.containsKey("SDK_ROOT")) {
+      env.sdkRoot =
+        join(absolute(normalize(Platform.environment["SDK_ROOT"])), "lib");
+    } else {
+      throw "No SDK root found, please specify one using --sdk-root.";
+    }
+  } else {
+    env.sdkRoot = join(absolute(normalize(args["sdk-root"])), "lib");
+  }
+  if (!FileSystemEntity.isDirectorySync(env.sdkRoot)) {
+    throw "Provided SDK root ${args["sdk-root"]} is not a valid SDK "
+          "top-level directory";
+  }
+
+  if (args["package-root"] == null) {
+    env.pkgRoot = absolute(normalize("./packages"));
+  } else {
+    env.pkgRoot = absolute(normalize(args["package-root"]));
+    if (!FileSystemEntity.isDirectorySync(env.pkgRoot)) {
+      throw "Provided package root ${args["package-root"]} is not directory.";
+    }
+  }
+
+  if (args["in"] == "stdin") {
+    env.input = "stdin";
+  } else {
+    env.input = absolute(normalize(args["in"]));
+    if (!FileSystemEntity.isDirectorySync(env.input) &&
+        !FileSystemEntity.isFileSync(env.input)) {
+      throw "Provided input ${args["in"]} is neither a directory, nor a file.";
+    }
+  }
+
+  if (args["out"] == "stdout") {
+    env.output = stdout;
+  } else {
+    env.output = absolute(normalize(args["out"]));
+    env.output = new File(env.output).openWrite();
+  }
+
+  if (args["pretty-print"] &&
+      args["lcov"]) {
+    throw "Choose either pretty-print or lcov output";
+  }
+
+  env.prettyPrint = args["pretty-print"];
+  env.lcov = args["lcov"];
+  env.verbose = args["verbose"];
+  env.workers = int.parse("${args["workers"]}");
+}
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index f370863..b8727ea 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -53,6 +53,8 @@
       return new Firefox();
     } else if (name == 'chrome') {
       return new Chrome();
+    } else if (name == 'dartium') {
+      return new Dartium();
     } else if (name == 'safari') {
       return new Safari();
     } else if (name.startsWith('ie')) {
@@ -63,7 +65,7 @@
   }
 
   static const List<String> SUPPORTED_BROWSERS =
-    const ['safari', 'ff', 'firefox', 'chrome', 'ie9', 'ie10'];
+    const ['safari', 'ff', 'firefox', 'chrome', 'ie9', 'ie10', 'dartium'];
 
   static const List<String> BROWSERS_WITH_WINDOW_SUPPORT =
       const ['safari', 'ff', 'firefox', 'chrome'];
@@ -109,8 +111,11 @@
    * Start the browser using the supplied argument.
    * This sets up the error handling and usage logging.
    */
-  Future<bool> startBrowser(String command, List<String> arguments) {
-    return Process.start(command, arguments).then((startedProcess) {
+  Future<bool> startBrowser(String command,
+                            List<String> arguments,
+                            {Map<String,String> environment}) {
+    return Process.start(command, arguments, environment: environment)
+        .then((startedProcess) {
       process = startedProcess;
       // Used to notify when exiting, and as a return value on calls to
       // close().
@@ -316,24 +321,25 @@
 
 
 class Chrome extends Browser {
-  static String _binary = _getBinary();
-
+  String _binary;
   String _version = "Version not found yet";
 
-  // This is extracted to a function since we may need to support several
-  // locations.
-  static String _getWindowsBinary() {
-    return "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe";
+  Chrome() {
+    _binary = _getBinary();
   }
 
-  static String _getBinary() {
-    if (Platform.isWindows) return _getWindowsBinary();
-    if (Platform.isMacOS) {
+  String _getBinary() {
+    if (Platform.isWindows) {
+      return "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe";
+    } else if (Platform.isMacOS) {
       return "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
     }
-    if (Platform.isLinux) return 'google-chrome';
+    assert(Platform.isLinux);
+    return 'google-chrome';
   }
 
+  Map<String, String> _getEnvironment() => null;
+
   Future<bool> _getVersion() {
     if (Platform.isWindows) {
       // The version flag does not work on windows.
@@ -375,7 +381,7 @@
         var args = ["--user-data-dir=${userDir.path}", url,
                     "--disable-extensions", "--disable-popup-blocking",
                     "--bwsi", "--no-first-run"];
-        return startBrowser(_binary, args);
+        return startBrowser(_binary, args, environment: _getEnvironment());
       });
     }).catchError((e) {
       _logEvent("Running $_binary --version failed with $e");
@@ -386,6 +392,27 @@
   String toString() => "Chrome";
 }
 
+class Dartium extends Chrome {
+  String _getBinary() {
+    if (Platform.operatingSystem == 'macos') {
+      return new Path('client/tests/dartium/Chromium.app/Contents/'
+                      'MacOS/Chromium').toNativePath();
+    }
+    return new Path('client/tests/dartium/chrome').toNativePath();
+  }
+
+  Map<String, String> _getEnvironment() {
+    var environment = new Map<String,String>.from(Platform.environment);
+    // By setting this environment variable, dartium will forward "print()"
+    // calls in dart to the top-level javascript function "dartPrint()" if
+    // available.
+    environment['DART_FORWARDING_PRINT'] = '1';
+    return environment;
+  }
+
+  String toString() => "Dartium";
+}
+
 class IE extends Browser {
 
   static const String binary =
@@ -619,7 +646,7 @@
   // If we do we need to provide developers with this information.
   // We don't add urls to the cache until we have run it.
   Map<int, String> testCache = new Map<int, String>();
-  List<int> doubleReportingTests = new List<int>();
+  Map<int, String> doubleReportingOutputs = new Map<int, String>();
 
   BrowserTestingServer testingServer;
 
@@ -696,7 +723,7 @@
   void handleResults(String browserId, String output, int testId) {
     var status = browserStatus[browserId];
     if (testCache.containsKey(testId)) {
-      doubleReportingTests.add(testId);
+      doubleReportingOutputs[testId] = output;
       return;
     }
 
@@ -831,15 +858,23 @@
   }
 
   void printDoubleReportingTests() {
-    if (doubleReportingTests.length == 0) return;
+    if (doubleReportingOutputs.length == 0) return;
     // TODO(ricow): die on double reporting.
     // Currently we just report this here, we could have a callback to the
     // encapsulating environment.
     print("");
     print("Double reporting tests");
-    for (var id in doubleReportingTests) {
+    for (var id in doubleReportingOutputs.keys) {
       print("  ${testCache[id]}");
     }
+
+    DebugLogger.warning("Double reporting tests:");
+    for (var id in doubleReportingOutputs.keys) {
+      DebugLogger.warning("${testCache[id]}, output: ");
+      DebugLogger.warning("${doubleReportingOutputs[id]}");
+      DebugLogger.warning("");
+      DebugLogger.warning("");
+    }
   }
 
   Future<bool> terminate() {
diff --git a/tools/testing/dart/browser_test.dart b/tools/testing/dart/browser_test.dart
index dbfd7e5..e37d029 100644
--- a/tools/testing/dart/browser_test.dart
+++ b/tools/testing/dart/browser_test.dart
@@ -55,7 +55,7 @@
 </html>
 """;
 
-String dartTestWrapper(bool usePackageImport, String libraryPathComponent) {
+String dartUnittestWrapper(bool usePackageImport, String libraryPathComponent) {
   // Tests inside "pkg" import unittest using "package:". All others use a
   // relative path. The imports need to agree, so use a matching form here.
   var unitTest;
@@ -77,3 +77,15 @@
 }
 """;
 }
+
+String dartTestWrapper(String libraryPathComponent) {
+  return """
+import '$libraryPathComponent' as test;
+
+main() {
+  print("dart-calling-main");
+  test.main();
+  print("dart-main-done");
+}
+""";
+}
\ No newline at end of file
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index dd92951..db7a6b1 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -41,6 +41,8 @@
                    '--minified'],
     const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
                    '--checked'],
+    const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk',
+                   '--use_browser_controller', '--write-debug-log'],
 ];
 
 void main() {
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index dc0f5ff..38d45a7 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -452,7 +452,7 @@
   Set<String>  _blacklistedOptions = new Set<String>.from([
     'progress', 'failure-summary', 'step_name', 'report', 'tasks', 'verbose',
     'time', 'dart', 'drt', 'dartium', 'build_directory', 'append_logs',
-    'write_debug_log', 'local_ip', 'shard', 'shards',
+    'local_ip', 'shard', 'shards',
   ]);
 
   List<String> _constructReproducingCommandArguments(Map config) {
@@ -676,7 +676,7 @@
           if (configuration['mode'] == 'debug') {
             timeout *= 2;
           }
-          if (const ['drt', 'dartium'].contains(configuration['runtime'])) {
+          if (const ['drt'].contains(configuration['runtime'])) {
             timeout *= 4; // Allow additional time for browser testing to run.
           }
           break;
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index b93c3de..0a2e31f 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -1154,14 +1154,6 @@
           return Expectation.PASS;
         }
 
-        // We're not as strict, if the exitCode indicated an uncaught exception
-        // we say it passed nonetheless
-        // TODO(kustermann): As soon as the VM team makes sure we get correct
-        // exit codes, we should remove this.
-        if (exitCode == DART_VM_EXITCODE_UNCAUGHT_EXCEPTION) {
-          return Expectation.PASS;
-        }
-
         return Expectation.MISSING_COMPILETIME_ERROR;
       }
       if (testCase.info.hasRuntimeError) {
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index e98f6f1..64a495f 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -712,6 +712,7 @@
       enqueueStandardTest(info, testName, expectations);
     } else if (TestUtils.isBrowserRuntime(configuration['runtime'])) {
       bool isWrappingRequired = configuration['compiler'] != 'dart2js';
+
       if (info.optionsFromFile['isMultiHtmlTest']) {
         // A browser multi-test has multiple expectations for one test file.
         // Find all the different sub-test expecations for one entire test file.
@@ -917,14 +918,25 @@
     return url;
   }
 
-  void _createWrapperFile(String dartWrapperFilename, dartLibraryFilename) {
+  void _createWrapperFile(String dartWrapperFilename,
+                          Path dartLibraryFilename,
+                          {bool useUnittestWrapper: false}) {
     File file = new File(dartWrapperFilename);
     RandomAccessFile dartWrapper = file.openSync(mode: FileMode.WRITE);
 
     var usePackageImport = dartLibraryFilename.segments().contains("pkg");
     var libraryPathComponent = _createUrlPathFromFile(dartLibraryFilename);
-    dartWrapper.writeStringSync(dartTestWrapper(usePackageImport,
-                                                libraryPathComponent));
+    var generatedSource;
+    if (useUnittestWrapper) {
+      // FIXME(kustermann): This is broken, we can't do unittest-based wrapping
+      // of tests (e.g. async operations are not wrapped in expectAsync()).
+      generatedSource = dartUnittestWrapper(usePackageImport,
+                                            libraryPathComponent);
+    } else {
+      generatedSource = dartTestWrapper(libraryPathComponent);
+    }
+
+    dartWrapper.writeStringSync(generatedSource);
     dartWrapper.closeSync();
   }
 
@@ -987,7 +999,6 @@
       // Use existing HTML document if available.
       String htmlPath;
       if (customHtml.existsSync()) {
-
         // If necessary, run the Polymer deploy steps.
         // TODO(jmesserly): this should be generalized for any tests that
         // require Pub deploy, not just polymer.
@@ -1028,7 +1039,13 @@
         htmlPath = '$tempDir/test.html';
         if (isWrappingRequired && !isWebTest) {
           // test.dart will import the dart test.
-          _createWrapperFile(dartWrapperFilename, filePath);
+          if (configuration['use_browser_controller'] &&
+              configuration['runtime'] == 'dartium') {
+            _createWrapperFile(dartWrapperFilename, filePath);
+          } else {
+            _createWrapperFile(
+                dartWrapperFilename, filePath, useUnittestWrapper: true);
+          }
         } else {
           dartWrapperFilename = filename;
         }
diff --git a/utils/peg/pegparser.dart b/utils/peg/pegparser.dart
index ba1526b..8666550 100644
--- a/utils/peg/pegparser.dart
+++ b/utils/peg/pegparser.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library Peg Parser;
+library PegParser;
 
 /*
  * The following functions are combinators for building Rules.
@@ -62,7 +62,7 @@
 
   // Find the range of character codes and construct an array of flags for codes
   // within the range.
-  List<int> codes = characters.codeUnits;
+  List<int> codes = characters.codeUnits.toList();
   codes.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
   int lo = codes[0];
   int hi = codes[codes.length - 1];
@@ -165,7 +165,7 @@
  * MANY is a value generating matcher.  The value is a list of the matches of
  * [rule].  The list may be empty if [:min == 0:].
  */
-_Rule MANY(rule, [separator = null, int min = 1]) {
+_Rule MANY(rule, {separator: null, int min: 1}) {
   assert(0 <= min && min <= 1);
   return new _RepeatRule(_compile(rule), _compileOptional(separator), min);
 }
@@ -274,7 +274,7 @@
       tokens.sort((a, b) =>
                   a.startsWith("'") == b.startsWith("'")
                       ? a.compareTo(b)
-                      : a.startsWith("'") ? +1 : -1);
+                      : a.startsWith("'") ? 1 : -1);
       var expected = tokens.join(' or ');
       var found = state.max_pos == state._end ? 'end of file'
           : "'${state._text[state.max_pos]}'";
@@ -314,7 +314,7 @@
 
 
 class _ParserState {
-  _ParserState(this._text, [_Rule whitespace = null]) {
+  _ParserState(this._text, {_Rule whitespace}) {
     _end = this._text.length;
     whitespaceRule = whitespace;
     max_rule = [];
diff --git a/utils/tests/peg/peg_test.dart b/utils/tests/peg/peg_test.dart
index 692dc15..b48453b 100644
--- a/utils/tests/peg/peg_test.dart
+++ b/utils/tests/peg/peg_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library peg_tests;
+import 'dart:core' hide Symbol;
 import '../../peg/pegparser.dart';
 
 testParens() {
@@ -144,7 +145,7 @@
                       ['(', expression, ')', (e) => e]
                       ]);
 
-  var postfixes = OR([['(', MANY(assignment_e, ',', 0), ')', binary('apply')],
+  var postfixes = OR([['(', MANY(assignment_e, separator: ',', min: 0), ')', binary('apply')],
                       ['++', unary('postinc')],
                       ['--', unary('postdec')],
                       ['.', id, binary('field')],
@@ -295,7 +296,7 @@
     if (exception is ParseError)
       ast = exception;
     else
-      throw;
+      rethrow;
   }
   print('${printList(ast)}');
 }
@@ -315,7 +316,13 @@
   if (expected is String)
     formatted = printList(ast);
 
-  Expect.equals(expected, formatted, "parse: $input");
+  //Expect.equals(expected, formatted, "parse: $input");
+  if (expected != formatted) {
+    throw new ArgumentError(
+        "parse: $input"
+        "\n  expected: $expected"
+        "\n     found: $formatted");
+  }
 }
 
 // Prints the list in [1,2,3] notation, including nested lists.