Versio 0.8.7.0 .

svn merge -r 29152:29340 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@29341 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 5d2879d..51c3ad8 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -1367,7 +1367,9 @@
 }
 
 It is a static warning if a getter $m_1$ overrides  (\ref{inheritanceAndOverriding}) a getter 
-$m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$.   It is a static warning if a class  declares a static getter named $v$ and also has a non-static setter named $v=$. It is a static warning if a class $C$ declares an instance getter named $v$ and an accessible static member named $v$ or $v=$ is declared in a superclass of $C$.
+$m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$.   
+
+It is a static warning if a class  declares a static getter named $v$ and also has a non-static setter named $v=$. It is a static warning if a class $C$ declares an instance getter named $v$ and an accessible static member named $v$ or $v=$ is declared in a superclass of $C$. These warnings must be issued regardless of whether the getters or setters are declared explicitly or implicitly.
 
 \subsection{Setters}
 \label{setters}
@@ -1395,7 +1397,11 @@
 %It is a compile-time error if a class has both a setter and a method with the same name. This restriction holds regardless of whether the setter is defined explicitly or implicitly, or whether the setter or the method are inherited or not.
 
 It is a static warning if a setter declares a return type other than \VOID{}.
-It is a static warning if a setter $m_1$ overrides  (\ref{inheritanceAndOverriding}) a setter $m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$. It is a static warning if a class has a setter named $v=$ with argument type $T$ and a getter named $v$ with return type $S$, and $T$ may not be assigned to $S$. It is a static warning if a class  declares a static setter named $v=$ and also has a non-static member named $v$. It is a static warning if a class $C$ declares an instance setter named $v=$ and an accessible static member named $v=$ or $v$ is declared in a superclass of $C$.
+It is a static warning if a setter $m_1$ overrides  (\ref{inheritanceAndOverriding}) a setter $m_2$ and the type of $m_1$ is not a subtype of the type of $m_2$. It is a static warning if a class has a setter named $v=$ with argument type $T$ and a getter named $v$ with return type $S$, and $T$ may not be assigned to $S$. 
+
+It is a static warning if a class  declares a static setter named $v=$ and also has a non-static member named $v$. It is a static warning if a class $C$ declares an instance setter named $v=$ and an accessible static member named $v=$ or $v$ is declared in a superclass of $C$.
+
+These warnings must be issued regardless of whether the getters or setters are declared explicitly or implicitly.
 
 \subsection{Abstract Instance Members}
 \label{abstractInstanceMembers}
@@ -5588,7 +5594,7 @@
 
 We say that a variable $v$ is known to have type $T$ whenever we allow the type of $v$ to be promoted. The exact circumstances when type promotion is allowed are given in the relevant sections of the specification (\ref{logicalBooleanExpressions}, \ref{conditional} and \ref{if}).
 
-Type promotion for a variable v is allowed only when we can deduce that such promotion is valid based on an analysis of certain boolean expressions. In such cases, we say that the boolean expression b shows that v has type T. As a rule, for all variables v and types T, a boolean expression does not show that v has type T. Those situations where an expression does show that a variable has a type are mentioned explicitly in the relevant sections of this specification (\ref{typeTest} and \ref{logicalBooleanExpressions}).
+Type promotion for a variable $v$ is allowed only when we can deduce that such promotion is valid based on an analysis of certain boolean expressions. In such cases, we say that the boolean expression $b$ shows that $v$ has type $T$. As a rule, for all variables $v$ and types $T$, a boolean expression does not show that $v$ has type $T$. Those situations where an expression does show that a variable has a type are mentioned explicitly in the relevant sections of this specification (\ref{typeTest} and \ref{logicalBooleanExpressions}).
 
 
 \subsection{Dynamic Type System}
diff --git a/pkg/analyzer/LICENSE b/pkg/analyzer/LICENSE
new file mode 100644
index 0000000..ee99930
--- /dev/null
+++ b/pkg/analyzer/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2013, the Dart project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/analyzer_experimental/README.md b/pkg/analyzer/README.md
similarity index 100%
rename from pkg/analyzer_experimental/README.md
rename to pkg/analyzer/README.md
diff --git a/pkg/analyzer_experimental/bin/analyzer.dart b/pkg/analyzer/bin/analyzer.dart
similarity index 91%
rename from pkg/analyzer_experimental/bin/analyzer.dart
rename to pkg/analyzer/bin/analyzer.dart
index 40e5a6d..2d22e44 100644
--- a/pkg/analyzer_experimental/bin/analyzer.dart
+++ b/pkg/analyzer/bin/analyzer.dart
@@ -11,13 +11,13 @@
 import 'dart:convert';
 import 'dart:io';
 
-import 'package:analyzer_experimental/src/generated/engine.dart';
-import 'package:analyzer_experimental/src/generated/error.dart';
-import 'package:analyzer_experimental/src/generated/java_core.dart' show JavaSystem;
-import 'package:analyzer_experimental/options.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart' show JavaSystem;
+import 'package:analyzer/options.dart';
 
-import 'package:analyzer_experimental/src/analyzer_impl.dart';
-import 'package:analyzer_experimental/src/error_formatter.dart';
+import 'package:analyzer/src/analyzer_impl.dart';
+import 'package:analyzer/src/error_formatter.dart';
 
 void main(args) {
   var options = CommandLineOptions.parse(args);
diff --git a/pkg/analyzer_experimental/bin/coverage.dart b/pkg/analyzer/bin/coverage.dart
similarity index 92%
rename from pkg/analyzer_experimental/bin/coverage.dart
rename to pkg/analyzer/bin/coverage.dart
index a4bb482..30efc6c 100644
--- a/pkg/analyzer_experimental/bin/coverage.dart
+++ b/pkg/analyzer/bin/coverage.dart
@@ -8,8 +8,8 @@
 
 import 'package:args/args.dart';
 
-import 'package:analyzer_experimental/src/services/runtime/log.dart' as log;
-import 'package:analyzer_experimental/src/services/runtime/coverage/coverage_impl.dart';
+import 'package:analyzer/src/services/runtime/log.dart' as log;
+import 'package:analyzer/src/services/runtime/coverage/coverage_impl.dart';
 
 
 main(args) {
diff --git a/pkg/analyzer_experimental/bin/formatter.dart b/pkg/analyzer/bin/formatter.dart
similarity index 98%
rename from pkg/analyzer_experimental/bin/formatter.dart
rename to pkg/analyzer/bin/formatter.dart
index ad5f4cd..5693e9c 100755
--- a/pkg/analyzer_experimental/bin/formatter.dart
+++ b/pkg/analyzer/bin/formatter.dart
@@ -10,7 +10,7 @@
 import 'package:args/args.dart';
 import 'package:path/path.dart' as path;
 
-import 'package:analyzer_experimental/src/services/formatter_impl.dart';
+import 'package:analyzer/src/services/formatter_impl.dart';
 
 
 const BINARY_NAME = 'dartfmt';
diff --git a/pkg/analyzer_experimental/example/parser_driver.dart b/pkg/analyzer/example/parser_driver.dart
similarity index 75%
rename from pkg/analyzer_experimental/example/parser_driver.dart
rename to pkg/analyzer/example/parser_driver.dart
index e69c33b..aa87f11 100644
--- a/pkg/analyzer_experimental/example/parser_driver.dart
+++ b/pkg/analyzer/example/parser_driver.dart
@@ -4,13 +4,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer_experimental/src/generated/ast.dart';
-import 'package:analyzer_experimental/src/generated/error.dart';
-import 'package:analyzer_experimental/src/generated/parser.dart';
-import 'package:analyzer_experimental/src/generated/scanner.dart';
-
 import 'dart:io';
 
+import 'package:analyzer/src/generated/java_core.dart' show CharSequence;
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+
 
 main() {
 
@@ -31,7 +32,8 @@
 _parse(File file) {
   var src = file.readAsStringSync();
   var errorListener = new _ErrorCollector();
-  var scanner = new StringScanner(null, src, errorListener);
+  var reader = new CharSequenceReader(new CharSequence(src));
+  var scanner = new Scanner(null, reader, errorListener);
   var token = scanner.tokenize();
   var parser = new Parser(null, errorListener);
   var unit = parser.parseCompilationUnit(token);
diff --git a/pkg/analyzer_experimental/example/resolver_driver.dart b/pkg/analyzer/example/resolver_driver.dart
similarity index 78%
rename from pkg/analyzer_experimental/example/resolver_driver.dart
rename to pkg/analyzer/example/resolver_driver.dart
index 2207cf1..0a20171 100644
--- a/pkg/analyzer_experimental/example/resolver_driver.dart
+++ b/pkg/analyzer/example/resolver_driver.dart
@@ -4,13 +4,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer_experimental/src/generated/java_io.dart';
-import 'package:analyzer_experimental/src/generated/source_io.dart';
-import 'package:analyzer_experimental/src/generated/ast.dart';
-import 'package:analyzer_experimental/src/generated/sdk.dart' show DartSdk;
-import 'package:analyzer_experimental/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
-import 'package:analyzer_experimental/src/generated/element.dart';
-import 'package:analyzer_experimental/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
+import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
 
 import 'dart:io';
 
diff --git a/pkg/analyzer_experimental/example/scanner_driver.dart b/pkg/analyzer/example/scanner_driver.dart
similarity index 74%
rename from pkg/analyzer_experimental/example/scanner_driver.dart
rename to pkg/analyzer/example/scanner_driver.dart
index 346eb61..27782d0 100644
--- a/pkg/analyzer_experimental/example/scanner_driver.dart
+++ b/pkg/analyzer/example/scanner_driver.dart
@@ -4,10 +4,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer_experimental/src/generated/scanner.dart';
-
 import 'dart:io';
 
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/java_core.dart' show CharSequence;
+
 main() {
 
   print('working dir ${new File('.').fullPathSync()}');
@@ -26,7 +27,8 @@
 
 _scan(File file) {
   var src = file.readAsStringSync();
-  var scanner = new StringScanner(null, src, null);
+  var reader = new CharSequenceReader(new CharSequence(src));
+  var scanner = new Scanner(null, reader, null);
   var token = scanner.tokenize();
   while (token.type != TokenType.EOF) {
     print(token);
diff --git a/pkg/analyzer_experimental/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
similarity index 87%
rename from pkg/analyzer_experimental/lib/analyzer.dart
rename to pkg/analyzer/lib/analyzer.dart
index 6424cbf..be32717 100644
--- a/pkg/analyzer_experimental/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -8,6 +8,7 @@
 
 import 'package:path/path.dart' as pathos;
 
+import 'src/generated/java_core.dart' show CharSequence;
 import 'src/error.dart';
 import 'src/generated/ast.dart';
 import 'src/generated/error.dart';
@@ -23,7 +24,7 @@
 
 /// Parses a Dart file into an AST.
 CompilationUnit parseDartFile(String path) {
-  var contents = new File(path).readAsStringSync();
+  String contents = new File(path).readAsStringSync();
   var errorCollector = new _ErrorCollector();
   var sourceFactory = new SourceFactory.con2([new FileUriResolver()]);
 
@@ -36,7 +37,8 @@
     throw new ArgumentError("Source $source doesn't exist");
   }
 
-  var scanner = new StringScanner(source, contents, errorCollector);
+  var reader = new CharSequenceReader(new CharSequence(contents));
+  var scanner = new Scanner(source, reader, errorCollector);
   var token = scanner.tokenize();
   var parser = new Parser(source, errorCollector);
   var unit = parser.parseCompilationUnit(token);
@@ -55,7 +57,8 @@
   if (name == null) name = '<unknown source>';
   var source = new StringSource(contents, name);
   var errorCollector = new _ErrorCollector();
-  var scanner = new StringScanner(source, contents, errorCollector);
+  var reader = new CharSequenceReader(new CharSequence(contents));
+  var scanner = new Scanner(source, reader, errorCollector);
   var token = scanner.tokenize();
   var parser = new Parser(source, errorCollector);
   var unit = parser.parseCompilationUnit(token);
diff --git a/pkg/analyzer_experimental/lib/formatter.dart b/pkg/analyzer/lib/formatter.dart
similarity index 80%
rename from pkg/analyzer_experimental/lib/formatter.dart
rename to pkg/analyzer/lib/formatter.dart
index f98d266..5139cde 100644
--- a/pkg/analyzer_experimental/lib/formatter.dart
+++ b/pkg/analyzer/lib/formatter.dart
@@ -4,5 +4,5 @@
 
 library formatter;
 
-export 'package:analyzer_experimental/src/services/formatter_impl.dart'
+export 'package:analyzer/src/services/formatter_impl.dart'
   show CodeFormatter, FormatterOptions, FormattedSource, CodeKind;
\ No newline at end of file
diff --git a/pkg/analyzer_experimental/lib/options.dart b/pkg/analyzer/lib/options.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/options.dart
rename to pkg/analyzer/lib/options.dart
diff --git a/pkg/analyzer_experimental/lib/src/analyzer_impl.dart b/pkg/analyzer/lib/src/analyzer_impl.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/analyzer_impl.dart
rename to pkg/analyzer/lib/src/analyzer_impl.dart
diff --git a/pkg/analyzer_experimental/lib/src/error.dart b/pkg/analyzer/lib/src/error.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/error.dart
rename to pkg/analyzer/lib/src/error.dart
diff --git a/pkg/analyzer_experimental/lib/src/error_formatter.dart b/pkg/analyzer/lib/src/error_formatter.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/error_formatter.dart
rename to pkg/analyzer/lib/src/error_formatter.dart
diff --git a/pkg/analyzer_experimental/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
similarity index 94%
rename from pkg/analyzer_experimental/lib/src/generated/ast.dart
rename to pkg/analyzer/lib/src/generated/ast.dart
index e377a46..1c1f428 100644
--- a/pkg/analyzer_experimental/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -8,6 +8,7 @@
 import 'scanner.dart';
 import 'engine.dart' show AnalysisEngine;
 import 'utilities_dart.dart';
+import 'utilities_collection.dart' show TokenMap;
 import 'element.dart';
 /**
  * The abstract class `ASTNode` defines the behavior common to all nodes in the AST structure
@@ -14625,6 +14626,418 @@
   }
 }
 /**
+ * Instances of the class `IncrementalASTCloner` implement an object that will clone any AST
+ * structure that it visits. The cloner will clone the structure, replacing the specified ASTNode
+ * with a new ASTNode, mapping the old token stream to a new token stream, and preserving resolution
+ * results.
+ */
+class IncrementalASTCloner implements ASTVisitor<ASTNode> {
+
+  /**
+   * The node to be replaced during the cloning process.
+   */
+  ASTNode _oldNode;
+
+  /**
+   * The replacement node used during the cloning process.
+   */
+  ASTNode _newNode;
+
+  /**
+   * A mapping of old tokens to new tokens used during the cloning process.
+   */
+  TokenMap _tokenMap;
+
+  /**
+   * Construct a new instance that will replace `oldNode` with `newNode` in the process
+   * of cloning an existing AST structure.
+   *
+   * @param oldNode the node to be replaced
+   * @param newNode the replacement node
+   * @param tokenMap a mapping of old tokens to new tokens (not `null`)
+   */
+  IncrementalASTCloner(ASTNode oldNode, ASTNode newNode, TokenMap tokenMap) {
+    this._oldNode = oldNode;
+    this._newNode = newNode;
+    this._tokenMap = tokenMap;
+  }
+  AdjacentStrings visitAdjacentStrings(AdjacentStrings node) => new AdjacentStrings.full(clone5(node.strings));
+  Annotation visitAnnotation(Annotation node) {
+    Annotation copy = new Annotation.full(map(node.atSign), clone4(node.name), map(node.period), clone4(node.constructorName), clone4(node.arguments));
+    copy.element = node.element;
+    return copy;
+  }
+  ArgumentDefinitionTest visitArgumentDefinitionTest(ArgumentDefinitionTest node) {
+    ArgumentDefinitionTest copy = new ArgumentDefinitionTest.full(map(node.question), clone4(node.identifier));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  ArgumentList visitArgumentList(ArgumentList node) => new ArgumentList.full(map(node.leftParenthesis), clone5(node.arguments), map(node.rightParenthesis));
+  AsExpression visitAsExpression(AsExpression node) {
+    AsExpression copy = new AsExpression.full(clone4(node.expression), map(node.asOperator), clone4(node.type));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  ASTNode visitAssertStatement(AssertStatement node) => new AssertStatement.full(map(node.keyword), map(node.leftParenthesis), clone4(node.condition), map(node.rightParenthesis), map(node.semicolon));
+  AssignmentExpression visitAssignmentExpression(AssignmentExpression node) {
+    AssignmentExpression copy = new AssignmentExpression.full(clone4(node.leftHandSide), map(node.operator), clone4(node.rightHandSide));
+    copy.propagatedElement = node.propagatedElement;
+    copy.staticElement = node.staticElement;
+    return copy;
+  }
+  BinaryExpression visitBinaryExpression(BinaryExpression node) {
+    BinaryExpression copy = new BinaryExpression.full(clone4(node.leftOperand), map(node.operator), clone4(node.rightOperand));
+    copy.propagatedElement = node.propagatedElement;
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  Block visitBlock(Block node) => new Block.full(map(node.leftBracket), clone5(node.statements), map(node.rightBracket));
+  BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) => new BlockFunctionBody.full(clone4(node.block));
+  BooleanLiteral visitBooleanLiteral(BooleanLiteral node) {
+    BooleanLiteral copy = new BooleanLiteral.full(map(node.literal), node.value);
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  BreakStatement visitBreakStatement(BreakStatement node) => new BreakStatement.full(map(node.keyword), clone4(node.label), map(node.semicolon));
+  CascadeExpression visitCascadeExpression(CascadeExpression node) {
+    CascadeExpression copy = new CascadeExpression.full(clone4(node.target), clone5(node.cascadeSections));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  CatchClause visitCatchClause(CatchClause node) => new CatchClause.full(map(node.onKeyword), clone4(node.exceptionType), map(node.catchKeyword), map(node.leftParenthesis), clone4(node.exceptionParameter), map(node.comma), clone4(node.stackTraceParameter), map(node.rightParenthesis), clone4(node.body));
+  ClassDeclaration visitClassDeclaration(ClassDeclaration node) {
+    ClassDeclaration copy = new ClassDeclaration.full(clone4(node.documentationComment), clone5(node.metadata), map(node.abstractKeyword), map(node.classKeyword), clone4(node.name), clone4(node.typeParameters), clone4(node.extendsClause), clone4(node.withClause), clone4(node.implementsClause), map(node.leftBracket), clone5(node.members), map(node.rightBracket));
+    copy.nativeClause = clone4(node.nativeClause);
+    return copy;
+  }
+  ClassTypeAlias visitClassTypeAlias(ClassTypeAlias node) => new ClassTypeAlias.full(clone4(node.documentationComment), clone5(node.metadata), map(node.keyword), clone4(node.name), clone4(node.typeParameters), map(node.equals), map(node.abstractKeyword), clone4(node.superclass), clone4(node.withClause), clone4(node.implementsClause), map(node.semicolon));
+  Comment visitComment(Comment node) {
+    if (node.isDocumentation) {
+      return Comment.createDocumentationComment2(map2(node.tokens), clone5(node.references));
+    } else if (node.isBlock) {
+      return Comment.createBlockComment(map2(node.tokens));
+    }
+    return Comment.createEndOfLineComment(map2(node.tokens));
+  }
+  CommentReference visitCommentReference(CommentReference node) => new CommentReference.full(map(node.newKeyword), clone4(node.identifier));
+  CompilationUnit visitCompilationUnit(CompilationUnit node) {
+    CompilationUnit copy = new CompilationUnit.full(map(node.beginToken), clone4(node.scriptTag), clone5(node.directives), clone5(node.declarations), map(node.endToken));
+    copy.lineInfo = node.lineInfo;
+    copy.element = node.element;
+    return copy;
+  }
+  ConditionalExpression visitConditionalExpression(ConditionalExpression node) {
+    ConditionalExpression copy = new ConditionalExpression.full(clone4(node.condition), map(node.question), clone4(node.thenExpression), map(node.colon), clone4(node.elseExpression));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  ConstructorDeclaration visitConstructorDeclaration(ConstructorDeclaration node) {
+    ConstructorDeclaration copy = new ConstructorDeclaration.full(clone4(node.documentationComment), clone5(node.metadata), map(node.externalKeyword), map(node.constKeyword), map(node.factoryKeyword), clone4(node.returnType), map(node.period), clone4(node.name), clone4(node.parameters), map(node.separator), clone5(node.initializers), clone4(node.redirectedConstructor), clone4(node.body));
+    copy.element = node.element;
+    return copy;
+  }
+  ConstructorFieldInitializer visitConstructorFieldInitializer(ConstructorFieldInitializer node) => new ConstructorFieldInitializer.full(map(node.keyword), map(node.period), clone4(node.fieldName), map(node.equals), clone4(node.expression));
+  ConstructorName visitConstructorName(ConstructorName node) {
+    ConstructorName copy = new ConstructorName.full(clone4(node.type), map(node.period), clone4(node.name));
+    copy.staticElement = node.staticElement;
+    return copy;
+  }
+  ContinueStatement visitContinueStatement(ContinueStatement node) => new ContinueStatement.full(map(node.keyword), clone4(node.label), map(node.semicolon));
+  DeclaredIdentifier visitDeclaredIdentifier(DeclaredIdentifier node) => new DeclaredIdentifier.full(clone4(node.documentationComment), clone5(node.metadata), map(node.keyword), clone4(node.type), clone4(node.identifier));
+  DefaultFormalParameter visitDefaultFormalParameter(DefaultFormalParameter node) => new DefaultFormalParameter.full(clone4(node.parameter), node.kind, map(node.separator), clone4(node.defaultValue));
+  DoStatement visitDoStatement(DoStatement node) => new DoStatement.full(map(node.doKeyword), clone4(node.body), map(node.whileKeyword), map(node.leftParenthesis), clone4(node.condition), map(node.rightParenthesis), map(node.semicolon));
+  DoubleLiteral visitDoubleLiteral(DoubleLiteral node) {
+    DoubleLiteral copy = new DoubleLiteral.full(map(node.literal), node.value);
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  EmptyFunctionBody visitEmptyFunctionBody(EmptyFunctionBody node) => new EmptyFunctionBody.full(map(node.semicolon));
+  EmptyStatement visitEmptyStatement(EmptyStatement node) => new EmptyStatement.full(map(node.semicolon));
+  ExportDirective visitExportDirective(ExportDirective node) {
+    ExportDirective copy = new ExportDirective.full(clone4(node.documentationComment), clone5(node.metadata), map(node.keyword), clone4(node.uri), clone5(node.combinators), map(node.semicolon));
+    copy.element = node.element;
+    return copy;
+  }
+  ExpressionFunctionBody visitExpressionFunctionBody(ExpressionFunctionBody node) => new ExpressionFunctionBody.full(map(node.functionDefinition), clone4(node.expression), map(node.semicolon));
+  ExpressionStatement visitExpressionStatement(ExpressionStatement node) => new ExpressionStatement.full(clone4(node.expression), map(node.semicolon));
+  ExtendsClause visitExtendsClause(ExtendsClause node) => new ExtendsClause.full(map(node.keyword), clone4(node.superclass));
+  FieldDeclaration visitFieldDeclaration(FieldDeclaration node) => new FieldDeclaration.full(clone4(node.documentationComment), clone5(node.metadata), map(node.staticKeyword), clone4(node.fields), map(node.semicolon));
+  FieldFormalParameter visitFieldFormalParameter(FieldFormalParameter node) => new FieldFormalParameter.full(clone4(node.documentationComment), clone5(node.metadata), map(node.keyword), clone4(node.type), map(node.thisToken), map(node.period), clone4(node.identifier), clone4(node.parameters));
+  ForEachStatement visitForEachStatement(ForEachStatement node) {
+    DeclaredIdentifier loopVariable = node.loopVariable;
+    if (loopVariable == null) {
+      return new ForEachStatement.con2_full(map(node.forKeyword), map(node.leftParenthesis), clone4(node.identifier), map(node.inKeyword), clone4(node.iterator), map(node.rightParenthesis), clone4(node.body));
+    }
+    return new ForEachStatement.con1_full(map(node.forKeyword), map(node.leftParenthesis), clone4(loopVariable), map(node.inKeyword), clone4(node.iterator), map(node.rightParenthesis), clone4(node.body));
+  }
+  FormalParameterList visitFormalParameterList(FormalParameterList node) => new FormalParameterList.full(map(node.leftParenthesis), clone5(node.parameters), map(node.leftDelimiter), map(node.rightDelimiter), map(node.rightParenthesis));
+  ForStatement visitForStatement(ForStatement node) => new ForStatement.full(map(node.forKeyword), map(node.leftParenthesis), clone4(node.variables), clone4(node.initialization), map(node.leftSeparator), clone4(node.condition), map(node.rightSeparator), clone5(node.updaters), map(node.rightParenthesis), clone4(node.body));
+  FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) => new FunctionDeclaration.full(clone4(node.documentationComment), clone5(node.metadata), map(node.externalKeyword), clone4(node.returnType), map(node.propertyKeyword), clone4(node.name), clone4(node.functionExpression));
+  FunctionDeclarationStatement visitFunctionDeclarationStatement(FunctionDeclarationStatement node) => new FunctionDeclarationStatement.full(clone4(node.functionDeclaration));
+  FunctionExpression visitFunctionExpression(FunctionExpression node) {
+    FunctionExpression copy = new FunctionExpression.full(clone4(node.parameters), clone4(node.body));
+    copy.element = node.element;
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  FunctionExpressionInvocation visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    FunctionExpressionInvocation copy = new FunctionExpressionInvocation.full(clone4(node.function), clone4(node.argumentList));
+    copy.propagatedElement = node.propagatedElement;
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  FunctionTypeAlias visitFunctionTypeAlias(FunctionTypeAlias node) => new FunctionTypeAlias.full(clone4(node.documentationComment), clone5(node.metadata), map(node.keyword), clone4(node.returnType), clone4(node.name), clone4(node.typeParameters), clone4(node.parameters), map(node.semicolon));
+  FunctionTypedFormalParameter visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) => new FunctionTypedFormalParameter.full(clone4(node.documentationComment), clone5(node.metadata), clone4(node.returnType), clone4(node.identifier), clone4(node.parameters));
+  HideCombinator visitHideCombinator(HideCombinator node) => new HideCombinator.full(map(node.keyword), clone5(node.hiddenNames));
+  IfStatement visitIfStatement(IfStatement node) => new IfStatement.full(map(node.ifKeyword), map(node.leftParenthesis), clone4(node.condition), map(node.rightParenthesis), clone4(node.thenStatement), map(node.elseKeyword), clone4(node.elseStatement));
+  ImplementsClause visitImplementsClause(ImplementsClause node) => new ImplementsClause.full(map(node.keyword), clone5(node.interfaces));
+  ImportDirective visitImportDirective(ImportDirective node) => new ImportDirective.full(clone4(node.documentationComment), clone5(node.metadata), map(node.keyword), clone4(node.uri), map(node.asToken), clone4(node.prefix), clone5(node.combinators), map(node.semicolon));
+  IndexExpression visitIndexExpression(IndexExpression node) {
+    Token period = map(node.period);
+    IndexExpression copy;
+    if (period == null) {
+      copy = new IndexExpression.forTarget_full(clone4(node.target), map(node.leftBracket), clone4(node.index), map(node.rightBracket));
+    } else {
+      copy = new IndexExpression.forCascade_full(period, map(node.leftBracket), clone4(node.index), map(node.rightBracket));
+    }
+    copy.auxiliaryElements = node.auxiliaryElements;
+    copy.propagatedElement = node.propagatedElement;
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  InstanceCreationExpression visitInstanceCreationExpression(InstanceCreationExpression node) {
+    InstanceCreationExpression copy = new InstanceCreationExpression.full(map(node.keyword), clone4(node.constructorName), clone4(node.argumentList));
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  IntegerLiteral visitIntegerLiteral(IntegerLiteral node) {
+    IntegerLiteral copy = new IntegerLiteral.full(map(node.literal), node.value);
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  InterpolationExpression visitInterpolationExpression(InterpolationExpression node) => new InterpolationExpression.full(map(node.leftBracket), clone4(node.expression), map(node.rightBracket));
+  InterpolationString visitInterpolationString(InterpolationString node) => new InterpolationString.full(map(node.contents), node.value);
+  IsExpression visitIsExpression(IsExpression node) {
+    IsExpression copy = new IsExpression.full(clone4(node.expression), map(node.isOperator), map(node.notOperator), clone4(node.type));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  Label visitLabel(Label node) => new Label.full(clone4(node.label), map(node.colon));
+  LabeledStatement visitLabeledStatement(LabeledStatement node) => new LabeledStatement.full(clone5(node.labels), clone4(node.statement));
+  LibraryDirective visitLibraryDirective(LibraryDirective node) => new LibraryDirective.full(clone4(node.documentationComment), clone5(node.metadata), map(node.libraryToken), clone4(node.name), map(node.semicolon));
+  LibraryIdentifier visitLibraryIdentifier(LibraryIdentifier node) {
+    LibraryIdentifier copy = new LibraryIdentifier.full(clone5(node.components));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  ListLiteral visitListLiteral(ListLiteral node) {
+    ListLiteral copy = new ListLiteral.full(map(node.constKeyword), clone4(node.typeArguments), map(node.leftBracket), clone5(node.elements), map(node.rightBracket));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  MapLiteral visitMapLiteral(MapLiteral node) {
+    MapLiteral copy = new MapLiteral.full(map(node.constKeyword), clone4(node.typeArguments), map(node.leftBracket), clone5(node.entries), map(node.rightBracket));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  MapLiteralEntry visitMapLiteralEntry(MapLiteralEntry node) => new MapLiteralEntry.full(clone4(node.key), map(node.separator), clone4(node.value));
+  MethodDeclaration visitMethodDeclaration(MethodDeclaration node) => new MethodDeclaration.full(clone4(node.documentationComment), clone5(node.metadata), map(node.externalKeyword), map(node.modifierKeyword), clone4(node.returnType), map(node.propertyKeyword), map(node.operatorKeyword), clone4(node.name), clone4(node.parameters), clone4(node.body));
+  MethodInvocation visitMethodInvocation(MethodInvocation node) {
+    MethodInvocation copy = new MethodInvocation.full(clone4(node.target), map(node.period), clone4(node.methodName), clone4(node.argumentList));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  NamedExpression visitNamedExpression(NamedExpression node) {
+    NamedExpression copy = new NamedExpression.full(clone4(node.name), clone4(node.expression));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  ASTNode visitNativeClause(NativeClause node) => new NativeClause.full(map(node.keyword), clone4(node.name));
+  NativeFunctionBody visitNativeFunctionBody(NativeFunctionBody node) => new NativeFunctionBody.full(map(node.nativeToken), clone4(node.stringLiteral), map(node.semicolon));
+  NullLiteral visitNullLiteral(NullLiteral node) {
+    NullLiteral copy = new NullLiteral.full(map(node.literal));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  ParenthesizedExpression visitParenthesizedExpression(ParenthesizedExpression node) {
+    ParenthesizedExpression copy = new ParenthesizedExpression.full(map(node.leftParenthesis), clone4(node.expression), map(node.rightParenthesis));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  PartDirective visitPartDirective(PartDirective node) {
+    PartDirective copy = new PartDirective.full(clone4(node.documentationComment), clone5(node.metadata), map(node.partToken), clone4(node.uri), map(node.semicolon));
+    copy.element = node.element;
+    return copy;
+  }
+  PartOfDirective visitPartOfDirective(PartOfDirective node) {
+    PartOfDirective copy = new PartOfDirective.full(clone4(node.documentationComment), clone5(node.metadata), map(node.partToken), map(node.ofToken), clone4(node.libraryName), map(node.semicolon));
+    copy.element = node.element;
+    return copy;
+  }
+  PostfixExpression visitPostfixExpression(PostfixExpression node) {
+    PostfixExpression copy = new PostfixExpression.full(clone4(node.operand), map(node.operator));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  PrefixedIdentifier visitPrefixedIdentifier(PrefixedIdentifier node) {
+    PrefixedIdentifier copy = new PrefixedIdentifier.full(clone4(node.prefix), map(node.period), clone4(node.identifier));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  PrefixExpression visitPrefixExpression(PrefixExpression node) {
+    PrefixExpression copy = new PrefixExpression.full(map(node.operator), clone4(node.operand));
+    copy.propagatedElement = node.propagatedElement;
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  PropertyAccess visitPropertyAccess(PropertyAccess node) {
+    PropertyAccess copy = new PropertyAccess.full(clone4(node.target), map(node.operator), clone4(node.propertyName));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  RedirectingConstructorInvocation visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
+    RedirectingConstructorInvocation copy = new RedirectingConstructorInvocation.full(map(node.keyword), map(node.period), clone4(node.constructorName), clone4(node.argumentList));
+    copy.staticElement = node.staticElement;
+    return copy;
+  }
+  RethrowExpression visitRethrowExpression(RethrowExpression node) {
+    RethrowExpression copy = new RethrowExpression.full(map(node.keyword));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  ReturnStatement visitReturnStatement(ReturnStatement node) => new ReturnStatement.full(map(node.keyword), clone4(node.expression), map(node.semicolon));
+  ScriptTag visitScriptTag(ScriptTag node) => new ScriptTag.full(map(node.scriptTag));
+  ShowCombinator visitShowCombinator(ShowCombinator node) => new ShowCombinator.full(map(node.keyword), clone5(node.shownNames));
+  SimpleFormalParameter visitSimpleFormalParameter(SimpleFormalParameter node) => new SimpleFormalParameter.full(clone4(node.documentationComment), clone5(node.metadata), map(node.keyword), clone4(node.type), clone4(node.identifier));
+  SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) {
+    SimpleIdentifier copy = new SimpleIdentifier.full(map(node.token));
+    copy.auxiliaryElements = node.auxiliaryElements;
+    copy.propagatedElement = node.propagatedElement;
+    copy.propagatedType = node.propagatedType;
+    copy.staticElement = node.staticElement;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  SimpleStringLiteral visitSimpleStringLiteral(SimpleStringLiteral node) {
+    SimpleStringLiteral copy = new SimpleStringLiteral.full(map(node.literal), node.value);
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  StringInterpolation visitStringInterpolation(StringInterpolation node) {
+    StringInterpolation copy = new StringInterpolation.full(clone5(node.elements));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  SuperConstructorInvocation visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    SuperConstructorInvocation copy = new SuperConstructorInvocation.full(map(node.keyword), map(node.period), clone4(node.constructorName), clone4(node.argumentList));
+    copy.staticElement = node.staticElement;
+    return copy;
+  }
+  SuperExpression visitSuperExpression(SuperExpression node) {
+    SuperExpression copy = new SuperExpression.full(map(node.keyword));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  SwitchCase visitSwitchCase(SwitchCase node) => new SwitchCase.full(clone5(node.labels), map(node.keyword), clone4(node.expression), map(node.colon), clone5(node.statements));
+  SwitchDefault visitSwitchDefault(SwitchDefault node) => new SwitchDefault.full(clone5(node.labels), map(node.keyword), map(node.colon), clone5(node.statements));
+  SwitchStatement visitSwitchStatement(SwitchStatement node) => new SwitchStatement.full(map(node.keyword), map(node.leftParenthesis), clone4(node.expression), map(node.rightParenthesis), map(node.leftBracket), clone5(node.members), map(node.rightBracket));
+  ASTNode visitSymbolLiteral(SymbolLiteral node) {
+    SymbolLiteral copy = new SymbolLiteral.full(map(node.poundSign), map2(node.components));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  ThisExpression visitThisExpression(ThisExpression node) {
+    ThisExpression copy = new ThisExpression.full(map(node.keyword));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  ThrowExpression visitThrowExpression(ThrowExpression node) {
+    ThrowExpression copy = new ThrowExpression.full(map(node.keyword), clone4(node.expression));
+    copy.propagatedType = node.propagatedType;
+    copy.staticType = node.staticType;
+    return copy;
+  }
+  TopLevelVariableDeclaration visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) => new TopLevelVariableDeclaration.full(clone4(node.documentationComment), clone5(node.metadata), clone4(node.variables), map(node.semicolon));
+  TryStatement visitTryStatement(TryStatement node) => new TryStatement.full(map(node.tryKeyword), clone4(node.body), clone5(node.catchClauses), map(node.finallyKeyword), clone4(node.finallyBlock));
+  TypeArgumentList visitTypeArgumentList(TypeArgumentList node) => new TypeArgumentList.full(map(node.leftBracket), clone5(node.arguments), map(node.rightBracket));
+  TypeName visitTypeName(TypeName node) {
+    TypeName copy = new TypeName.full(clone4(node.name), clone4(node.typeArguments));
+    copy.type = node.type;
+    return copy;
+  }
+  TypeParameter visitTypeParameter(TypeParameter node) => new TypeParameter.full(clone4(node.documentationComment), clone5(node.metadata), clone4(node.name), map(node.keyword), clone4(node.bound));
+  TypeParameterList visitTypeParameterList(TypeParameterList node) => new TypeParameterList.full(map(node.leftBracket), clone5(node.typeParameters), map(node.rightBracket));
+  VariableDeclaration visitVariableDeclaration(VariableDeclaration node) => new VariableDeclaration.full(null, clone5(node.metadata), clone4(node.name), map(node.equals), clone4(node.initializer));
+  VariableDeclarationList visitVariableDeclarationList(VariableDeclarationList node) => new VariableDeclarationList.full(null, clone5(node.metadata), map(node.keyword), clone4(node.type), clone5(node.variables));
+  VariableDeclarationStatement visitVariableDeclarationStatement(VariableDeclarationStatement node) => new VariableDeclarationStatement.full(clone4(node.variables), map(node.semicolon));
+  WhileStatement visitWhileStatement(WhileStatement node) => new WhileStatement.full(map(node.keyword), map(node.leftParenthesis), clone4(node.condition), map(node.rightParenthesis), clone4(node.body));
+  WithClause visitWithClause(WithClause node) => new WithClause.full(map(node.withKeyword), clone5(node.mixinTypes));
+  ASTNode clone4(ASTNode node) {
+    if (node == null) {
+      return null;
+    }
+    if (identical(node, _oldNode)) {
+      return _newNode as ASTNode;
+    }
+    return node.accept(this) as ASTNode;
+  }
+  List clone5(NodeList nodes) {
+    List clonedNodes = new List();
+    for (ASTNode node in nodes) {
+      clonedNodes.add(clone4(node));
+    }
+    return clonedNodes;
+  }
+  Token map(Token oldToken) {
+    if (oldToken == null) {
+      return null;
+    }
+    return _tokenMap.get(oldToken);
+  }
+  List<Token> map2(List<Token> oldTokens) {
+    List<Token> newTokens = new List<Token>(oldTokens.length);
+    for (int index = 0; index < newTokens.length; index++) {
+      newTokens[index] = map(oldTokens[index]);
+    }
+    return newTokens;
+  }
+}
+/**
  * Traverse the AST from initial child node to successive parents, building a collection of local
  * variable and parameter names visible to the initial child node. In case of name shadowing, the
  * first name seen is the most specific one so names are not redefined.
diff --git a/pkg/analyzer_experimental/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
similarity index 99%
rename from pkg/analyzer_experimental/lib/src/generated/constant.dart
rename to pkg/analyzer/lib/src/generated/constant.dart
index 12b536f..014d829 100644
--- a/pkg/analyzer_experimental/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -1453,7 +1453,7 @@
     }
     Object leftValue = leftOperand.value;
     if (leftValue is bool) {
-      if (((leftValue as bool))) {
+      if (leftValue as bool) {
         return booleanConversion(node.rightOperand, value);
       }
       return RESULT_FALSE;
@@ -1661,7 +1661,7 @@
    */
   EvaluationResultImpl booleanConversion(ASTNode node, Object value) {
     if (value is bool) {
-      if (((value as bool))) {
+      if (value as bool) {
         return RESULT_TRUE;
       } else {
         return RESULT_FALSE;
diff --git a/pkg/analyzer_experimental/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
similarity index 97%
rename from pkg/analyzer_experimental/lib/src/generated/element.dart
rename to pkg/analyzer/lib/src/generated/element.dart
index 06744c1..a43b3cb 100644
--- a/pkg/analyzer_experimental/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -1319,13 +1319,6 @@
   bool get isAbstract;
 
   /**
-   * Return `true` if this setter for final variable, so it causes warning when used.
-   *
-   * @return `true` if this accessor is excluded setter
-   */
-  bool get isExcludedSetter;
-
-  /**
    * Return `true` if this accessor represents a getter.
    *
    * @return `true` if this accessor represents a getter
@@ -2336,7 +2329,6 @@
   LibraryElement get enclosingElement => super.enclosingElement as LibraryElement;
   List<FunctionElement> get functions => _functions;
   List<FunctionTypeAliasElement> get functionTypeAliases => _typeAliases;
-  String get identifier => source.encoding;
   ElementKind get kind => ElementKind.COMPILATION_UNIT;
   Source get source => _source;
   List<TopLevelVariableElement> get topLevelVariables => _variables;
@@ -2445,6 +2437,7 @@
       builder.append(_source.fullName);
     }
   }
+  String get identifier => source.encoding;
 }
 /**
  * Instances of the class `ConstFieldElementImpl` implement a `FieldElement` for a
@@ -2766,7 +2759,15 @@
     }
     return context.computeDocumentationComment(this);
   }
-  bool operator ==(Object object) => object != null && object.runtimeType == runtimeType && ((object as Element)).location == location;
+  bool operator ==(Object object) {
+    if (identical(this, object)) {
+      return true;
+    }
+    if (object == null || hashCode != object.hashCode) {
+      return false;
+    }
+    return object.runtimeType == runtimeType && ((object as Element)).location == location;
+  }
   Element getAncestor(Type elementClass) {
     Element ancestor = _enclosingElement;
     while (ancestor != null && !isInstanceOf(ancestor, elementClass)) {
@@ -2914,8 +2915,8 @@
    *
    * @param element the enclosing element of this element
    */
-  void set enclosingElement(ElementImpl element) {
-    _enclosingElement = element;
+  void set enclosingElement(Element element) {
+    _enclosingElement = element as ElementImpl;
   }
 
   /**
@@ -2970,6 +2971,9 @@
     this.components = decode(encoding);
   }
   bool operator ==(Object object) {
+    if (identical(this, object)) {
+      return true;
+    }
     if (object is! ElementLocationImpl) {
       return false;
     }
@@ -2979,16 +2983,16 @@
     if (otherComponents.length != length) {
       return false;
     }
-    if (length > 0 && !equalSourceComponents(components[0], otherComponents[0])) {
-      return false;
+    for (int i = length - 1; i >= 2; i--) {
+      if (components[i] != otherComponents[i]) {
+        return false;
+      }
     }
     if (length > 1 && !equalSourceComponents(components[1], otherComponents[1])) {
       return false;
     }
-    for (int i = 2; i < length; i++) {
-      if (components[i] != otherComponents[i]) {
-        return false;
-      }
+    if (length > 0 && !equalSourceComponents(components[0], otherComponents[0])) {
+      return false;
     }
     return true;
   }
@@ -3083,10 +3087,14 @@
     } else if (right == null) {
       return false;
     }
-    if (left.length <= 1 || right.length <= 1) {
+    int leftLength = left.length;
+    int rightLength = right.length;
+    if (leftLength != rightLength) {
+      return false;
+    } else if (leftLength <= 1 || rightLength <= 1) {
       return left == right;
     }
-    return left.substring(1) == right.substring(1);
+    return javaStringRegionMatches(left, 1, right, 1, leftLength - 1);
   }
 
   /**
@@ -3532,7 +3540,6 @@
    */
   FunctionElementImpl.con2(int nameOffset) : super.con2("", nameOffset);
   accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
-  String get identifier => "${name}@${nameOffset}";
   ElementKind get kind => ElementKind.FUNCTION;
   SourceRange get visibleRange {
     if (_visibleRangeLength < 0) {
@@ -3561,6 +3568,7 @@
     }
     super.appendTo(builder);
   }
+  String get identifier => "${name}@${nameOffset}";
 }
 /**
  * Instances of the class `FunctionTypeAliasElementImpl` implement a
@@ -4145,7 +4153,6 @@
     return new List.from(libraries);
   }
   List<ExportElement> get exports => _exports;
-  String get identifier => _definingCompilationUnit.source.encoding;
   List<LibraryElement> get importedLibraries {
     Set<LibraryElement> libraries = new Set<LibraryElement>();
     for (ImportElement element in _imports) {
@@ -4264,6 +4271,7 @@
     safelyVisitChildren(_imports, visitor);
     safelyVisitChildren(_parts, visitor);
   }
+  String get identifier => _definingCompilationUnit.source.encoding;
 
   /**
    * Answer `true` if the receiver directly or indirectly imports the dart:html libraries.
@@ -4302,6 +4310,11 @@
 class LocalVariableElementImpl extends VariableElementImpl implements LocalVariableElement {
 
   /**
+   * Is `true` if this variable is potentially mutated somewhere in its scope.
+   */
+  bool _isPotentiallyMutated2 = false;
+
+  /**
    * The offset to the beginning of the visible range for this element.
    */
   int _visibleRangeOffset = 0;
@@ -4331,6 +4344,14 @@
     }
     return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
   }
+  bool get isPotentiallyMutated => _isPotentiallyMutated2;
+
+  /**
+   * Specifies that this variable is potentially mutated somewhere in its scope.
+   */
+  void markPotentiallyMutated() {
+    _isPotentiallyMutated2 = true;
+  }
 
   /**
    * Set the visible range for this element to the range starting at the given offset with the given
@@ -4590,6 +4611,11 @@
 class ParameterElementImpl extends VariableElementImpl implements ParameterElement {
 
   /**
+   * Is `true` if this variable is potentially mutated somewhere in its scope.
+   */
+  bool _isPotentiallyMutated3 = false;
+
+  /**
    * An array containing all of the parameters defined by this parameter element. There will only be
    * parameters if this parameter is a function typed parameter.
    */
@@ -4659,6 +4685,14 @@
     return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
   }
   bool get isInitializingFormal => false;
+  bool get isPotentiallyMutated => _isPotentiallyMutated3;
+
+  /**
+   * Specifies that this variable is potentially mutated somewhere in its scope.
+   */
+  void markPotentiallyMutated() {
+    _isPotentiallyMutated3 = true;
+  }
 
   /**
    * Set the range of the default value for this parameter to the range starting at the given offset
@@ -4838,7 +4872,6 @@
   }
   PropertyInducingElement get variable => _variable;
   bool get isAbstract => hasModifier(Modifier.ABSTRACT);
-  bool get isExcludedSetter => isSetter && _variable.isFinal;
   bool get isGetter => hasModifier(Modifier.GETTER);
   bool get isSetter => hasModifier(Modifier.SETTER);
   bool get isStatic => hasModifier(Modifier.STATIC);
@@ -5158,6 +5191,14 @@
   bool get isFinal => hasModifier(Modifier.FINAL);
 
   /**
+   * Return `true` if this variable is potentially mutated somewhere in its scope. This
+   * information is only available for local variables (including parameters).
+   *
+   * @return `true` if this variable is potentially mutated somewhere in its scope
+   */
+  bool get isPotentiallyMutated => false;
+
+  /**
    * Set whether this variable is const to correspond to the given value.
    *
    * @param isConst `true` if the variable is const
@@ -5717,7 +5758,6 @@
     return variable;
   }
   bool get isAbstract => baseElement.isAbstract;
-  bool get isExcludedSetter => baseElement.isExcludedSetter;
   bool get isGetter => baseElement.isGetter;
   bool get isSetter => baseElement.isSetter;
   String toString() {
@@ -5820,7 +5860,12 @@
   }
   bool operator ==(Object object) => object is DynamicTypeImpl;
   bool get isDynamic => true;
-  bool isMoreSpecificThan(Type2 type) => false;
+  bool isMoreSpecificThan(Type2 type) {
+    if (identical(this, type)) {
+      return true;
+    }
+    return false;
+  }
   bool isSubtypeOf(Type2 type) => true;
   bool isSupertypeOf(Type2 type) => true;
   Type2 substitute2(List<Type2> argumentTypes, List<Type2> parameterTypes) {
@@ -5892,7 +5937,7 @@
       return false;
     }
     FunctionTypeImpl otherType = object as FunctionTypeImpl;
-    return element == otherType.element && JavaArrays.equals(normalParameterTypes, otherType.normalParameterTypes) && JavaArrays.equals(optionalParameterTypes, otherType.optionalParameterTypes) && equals2(namedParameterTypes, otherType.namedParameterTypes) && returnType == otherType.returnType;
+    return (element == otherType.element) && JavaArrays.equals(normalParameterTypes, otherType.normalParameterTypes) && JavaArrays.equals(optionalParameterTypes, otherType.optionalParameterTypes) && equals2(namedParameterTypes, otherType.namedParameterTypes) && (returnType == otherType.returnType);
   }
   String get displayName {
     String name = this.name;
@@ -6041,6 +6086,91 @@
     return element.hashCode;
   }
   bool isAssignableTo(Type2 type) => this.isSubtypeOf(type);
+  bool isMoreSpecificThan(Type2 type) {
+    if (type == null) {
+      return false;
+    } else if (identical(this, type) || type.isDynamic || type.isDartCoreFunction || type.isObject) {
+      return true;
+    } else if (type is! FunctionType) {
+      return false;
+    } else if (this == type) {
+      return true;
+    }
+    FunctionType t = this;
+    FunctionType s = type as FunctionType;
+    List<Type2> tTypes = t.normalParameterTypes;
+    List<Type2> tOpTypes = t.optionalParameterTypes;
+    List<Type2> sTypes = s.normalParameterTypes;
+    List<Type2> sOpTypes = s.optionalParameterTypes;
+    if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
+      return false;
+    }
+    if (t.namedParameterTypes.length > 0) {
+      if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
+        return false;
+      } else if (t.normalParameterTypes.length > 0) {
+        for (int i = 0; i < tTypes.length; i++) {
+          if (!tTypes[i].isMoreSpecificThan(sTypes[i])) {
+            return false;
+          }
+        }
+      }
+      Map<String, Type2> namedTypesT = t.namedParameterTypes;
+      Map<String, Type2> namedTypesS = s.namedParameterTypes;
+      if (namedTypesT.length < namedTypesS.length) {
+        return false;
+      }
+      JavaIterator<MapEntry<String, Type2>> iteratorS = new JavaIterator(getMapEntrySet(namedTypesS));
+      while (iteratorS.hasNext) {
+        MapEntry<String, Type2> entryS = iteratorS.next();
+        Type2 typeT = namedTypesT[entryS.getKey()];
+        if (typeT == null) {
+          return false;
+        }
+        if (!typeT.isMoreSpecificThan(entryS.getValue())) {
+          return false;
+        }
+      }
+    } else if (s.namedParameterTypes.length > 0) {
+      return false;
+    } else {
+      int tArgLength = tTypes.length + tOpTypes.length;
+      int sArgLength = sTypes.length + sOpTypes.length;
+      if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
+        return false;
+      }
+      if (tOpTypes.length == 0 && sOpTypes.length == 0) {
+        for (int i = 0; i < sTypes.length; i++) {
+          if (!tTypes[i].isMoreSpecificThan(sTypes[i])) {
+            return false;
+          }
+        }
+      } else {
+        List<Type2> tAllTypes = new List<Type2>(sArgLength);
+        for (int i = 0; i < tTypes.length; i++) {
+          tAllTypes[i] = tTypes[i];
+        }
+        for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
+          tAllTypes[i] = tOpTypes[j];
+        }
+        List<Type2> sAllTypes = new List<Type2>(sArgLength);
+        for (int i = 0; i < sTypes.length; i++) {
+          sAllTypes[i] = sTypes[i];
+        }
+        for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
+          sAllTypes[i] = sOpTypes[j];
+        }
+        for (int i = 0; i < sAllTypes.length; i++) {
+          if (!tAllTypes[i].isMoreSpecificThan(sAllTypes[i])) {
+            return false;
+          }
+        }
+      }
+    }
+    Type2 tRetType = t.returnType;
+    Type2 sRetType = s.returnType;
+    return sRetType.isVoid || tRetType.isMoreSpecificThan(sRetType);
+  }
   bool isSubtypeOf(Type2 type) {
     if (type == null) {
       return false;
@@ -6082,7 +6212,7 @@
         if (typeT == null) {
           return false;
         }
-        if (!entryS.getValue().isAssignableTo(typeT)) {
+        if (!typeT.isAssignableTo(entryS.getValue())) {
           return false;
         }
       }
@@ -6096,7 +6226,7 @@
       }
       if (tOpTypes.length == 0 && sOpTypes.length == 0) {
         for (int i = 0; i < sTypes.length; i++) {
-          if (!sTypes[i].isAssignableTo(tTypes[i])) {
+          if (!tTypes[i].isAssignableTo(sTypes[i])) {
             return false;
           }
         }
@@ -6116,13 +6246,15 @@
           sAllTypes[i] = sOpTypes[j];
         }
         for (int i = 0; i < sAllTypes.length; i++) {
-          if (!sAllTypes[i].isAssignableTo(tAllTypes[i])) {
+          if (!tAllTypes[i].isAssignableTo(sAllTypes[i])) {
             return false;
           }
         }
       }
     }
-    return s.returnType == VoidTypeImpl.instance || t.returnType.isAssignableTo(s.returnType);
+    Type2 tRetType = t.returnType;
+    Type2 sRetType = s.returnType;
+    return sRetType.isVoid || tRetType.isAssignableTo(sRetType);
   }
 
   /**
@@ -6422,7 +6554,7 @@
       return false;
     }
     InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
-    return element == otherType.element && JavaArrays.equals(_typeArguments, otherType._typeArguments);
+    return (element == otherType.element) && JavaArrays.equals(_typeArguments, otherType._typeArguments);
   }
   List<PropertyAccessorElement> get accessors {
     List<PropertyAccessorElement> accessors = element.accessors;
@@ -6983,7 +7115,7 @@
    * @param element the element representing the declaration of the type parameter
    */
   TypeParameterTypeImpl(TypeParameterElement element) : super(element, element.name);
-  bool operator ==(Object object) => object is TypeParameterTypeImpl && element == ((object as TypeParameterTypeImpl)).element;
+  bool operator ==(Object object) => object is TypeParameterTypeImpl && (element == ((object as TypeParameterTypeImpl)).element);
   TypeParameterElement get element => super.element as TypeParameterElement;
   int get hashCode => element.hashCode;
   bool isMoreSpecificThan(Type2 s) {
diff --git a/pkg/analyzer_experimental/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
similarity index 97%
rename from pkg/analyzer_experimental/lib/src/generated/engine.dart
rename to pkg/analyzer/lib/src/generated/engine.dart
index 3217940..518e52e 100644
--- a/pkg/analyzer_experimental/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -8,7 +8,7 @@
 import 'instrumentation.dart';
 import 'error.dart';
 import 'source.dart';
-import 'scanner.dart' show Token, CharBufferScanner, StringScanner;
+import 'scanner.dart' show Token, Scanner, CharSequenceReader;
 import 'ast.dart';
 import 'parser.dart' show Parser;
 import 'sdk.dart' show DartSdk;
@@ -1479,6 +1479,21 @@
   SourceKind get kind => _sourceKind;
 
   /**
+   * Answer an array of library sources containing the receiver's source.
+   */
+  List<Source> get librariesContaining {
+    DartEntryImpl_ResolutionState state = _resolutionState;
+    List<Source> result = new List<Source>();
+    while (state != null) {
+      if (state._librarySource != null) {
+        result.add(state._librarySource);
+      }
+      state = state._nextState;
+    }
+    return new List.from(result);
+  }
+
+  /**
    * Return a compilation unit that has not been accessed by any other client and can therefore
    * safely be modified by the reconciler.
    *
@@ -1664,27 +1679,26 @@
     _parsedUnit = null;
     _parsedUnitAccessed = false;
     _parsedUnitState = CacheState.INVALID;
-    invalidateAllResolutionInformation();
+    discardCachedResolutionInformation();
   }
 
   /**
    * Invalidate all of the resolution information associated with the compilation unit.
    */
   void invalidateAllResolutionInformation() {
-    _element = null;
-    _elementState = CacheState.INVALID;
-    _includedParts = Source.EMPTY_ARRAY;
-    _includedPartsState = CacheState.INVALID;
-    _exportedLibraries = Source.EMPTY_ARRAY;
-    _exportedLibrariesState = CacheState.INVALID;
-    _importedLibraries = Source.EMPTY_ARRAY;
-    _importedLibrariesState = CacheState.INVALID;
-    _bitmask = 0;
-    _clientServerState = CacheState.INVALID;
-    _launchableState = CacheState.INVALID;
-    _publicNamespace = null;
-    _publicNamespaceState = CacheState.INVALID;
-    _resolutionState.invalidateAllResolutionInformation();
+    if (identical(_parsedUnitState, CacheState.FLUSHED)) {
+      DartEntryImpl_ResolutionState state = _resolutionState;
+      while (state != null) {
+        if (identical(state._resolvedUnitState, CacheState.VALID)) {
+          _parsedUnit = state._resolvedUnit;
+          _parsedUnitAccessed = true;
+          _parsedUnitState = CacheState.VALID;
+          break;
+        }
+        state = state._nextState;
+      }
+    }
+    discardCachedResolutionInformation();
   }
   bool get isRefactoringSafe {
     DartEntryImpl_ResolutionState state = _resolutionState;
@@ -2049,6 +2063,26 @@
   }
 
   /**
+   * Invalidate all of the resolution information associated with the compilation unit.
+   */
+  void discardCachedResolutionInformation() {
+    _element = null;
+    _elementState = CacheState.INVALID;
+    _includedParts = Source.EMPTY_ARRAY;
+    _includedPartsState = CacheState.INVALID;
+    _exportedLibraries = Source.EMPTY_ARRAY;
+    _exportedLibrariesState = CacheState.INVALID;
+    _importedLibraries = Source.EMPTY_ARRAY;
+    _importedLibrariesState = CacheState.INVALID;
+    _bitmask = 0;
+    _clientServerState = CacheState.INVALID;
+    _launchableState = CacheState.INVALID;
+    _publicNamespace = null;
+    _publicNamespaceState = CacheState.INVALID;
+    _resolutionState.invalidateAllResolutionInformation();
+  }
+
+  /**
    * Return a resolution state for the specified library, creating one as necessary.
    *
    * @param librarySource the library source (not `null`)
@@ -2903,6 +2937,12 @@
   AnalysisContextImpl_AnalysisTaskResultRecorder _resultRecorder;
 
   /**
+   * Cached information used in incremental analysis or `null` if none. Synchronize against
+   * [cacheLock] before accessing this field.
+   */
+  IncrementalAnalysisCache _incrementalAnalysisCache;
+
+  /**
    * Initialize a newly created analysis context.
    */
   AnalysisContextImpl() : super() {
@@ -3509,16 +3549,31 @@
   }
   void setChangedContents(Source source, String contents, int offset, int oldLength, int newLength) {
     {
-      if (_sourceFactory.setContents(source, contents)) {
+      String originalContents = _sourceFactory.setContents(source, contents);
+      if (originalContents == null) {
+        if (contents != null) {
+          _incrementalAnalysisCache = IncrementalAnalysisCache.update(_incrementalAnalysisCache, source, originalContents, contents, offset, oldLength, newLength, getReadableSourceEntry(source));
+          sourceChanged(source);
+        }
+      } else if (originalContents != contents) {
+        _incrementalAnalysisCache = IncrementalAnalysisCache.update(_incrementalAnalysisCache, source, originalContents, contents, offset, oldLength, newLength, getReadableSourceEntry(source));
         sourceChanged(source);
+      } else if (contents == null) {
+        _incrementalAnalysisCache = IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
       }
     }
   }
   void setContents(Source source, String contents) {
     {
-      if (_sourceFactory.setContents(source, contents)) {
+      String originalContents = _sourceFactory.setContents(source, contents);
+      if (originalContents == null) {
+        if (contents != null) {
+          sourceChanged(source);
+        }
+      } else if (originalContents != contents) {
         sourceChanged(source);
       }
+      _incrementalAnalysisCache = IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
     }
   }
   void set sourceFactory(SourceFactory factory) {
@@ -4864,6 +4919,8 @@
         if (thrownException == null) {
           htmlCopy.setValue(HtmlEntry.ELEMENT, task.element);
           htmlCopy.setValue(HtmlEntry.RESOLUTION_ERRORS, task.resolutionErrors);
+          ChangeNoticeImpl notice = getNotice(source);
+          notice.setErrors(htmlCopy.allErrors, htmlCopy.getValue(SourceEntry.LINE_INFO));
         } else {
           htmlCopy.recordResolutionError();
         }
@@ -5239,6 +5296,9 @@
   void setErrors(List<AnalysisError> errors, LineInfo lineInfo) {
     this._errors = errors;
     this._lineInfo = lineInfo;
+    if (lineInfo == null) {
+      AnalysisEngine.instance.logger.logError2("No line info: ${_source}", new JavaException());
+    }
   }
   String toString() => "Changes for ${_source.fullName}";
 }
@@ -5497,6 +5557,95 @@
   }
 }
 /**
+ * Instances of the class `IncrementalAnalysisCache` hold information used to perform
+ * incremental analysis.
+ *
+ * @see AnalysisContextImpl#setChangedContents(Source, String, int, int, int)
+ */
+class IncrementalAnalysisCache {
+
+  /**
+   * Determine if the cache should be cleared.
+   *
+   * @param cache the prior cache or `null` if none
+   * @param source the source being updated (not `null`)
+   * @return the cache used for incremental analysis or `null` if incremental analysis cannot
+   *         be performed
+   */
+  static IncrementalAnalysisCache clear(IncrementalAnalysisCache cache, Source source) {
+    if (cache == null || cache.source == source) {
+      return null;
+    }
+    return cache;
+  }
+
+  /**
+   * Determine if incremental analysis can be performed from the given information.
+   *
+   * @param cache the prior cache or `null` if none
+   * @param source the source being updated (not `null`)
+   * @param oldContents the original source contents prior to this update (not `null`)
+   * @param newContents the new contents after this incremental change (not `null`)
+   * @param offset the offset at which the change occurred
+   * @param oldLength the length of the text being replaced
+   * @param newLength the length of the replacement text
+   * @param sourceEntry the cached entry for the given source or `null` if none
+   * @return the cache used for incremental analysis or `null` if incremental analysis cannot
+   *         be performed
+   */
+  static IncrementalAnalysisCache update(IncrementalAnalysisCache cache, Source source, String oldContents, String newContents, int offset, int oldLength, int newLength, SourceEntry sourceEntry) {
+    if (cache == null || cache.source != source) {
+      if (sourceEntry is! DartEntryImpl) {
+        return null;
+      }
+      DartEntryImpl dartEntry = sourceEntry as DartEntryImpl;
+      List<Source> librarySources = dartEntry.librariesContaining;
+      if (librarySources.length != 1) {
+        return null;
+      }
+      Source librarySource = librarySources[0];
+      if (librarySource == null) {
+        return null;
+      }
+      CompilationUnit unit = dartEntry.getValue2(DartEntry.RESOLVED_UNIT, librarySource);
+      if (unit == null) {
+        return null;
+      }
+      if (oldContents == null) {
+        if (oldLength != 0) {
+          return null;
+        }
+        oldContents = "${newContents.substring(0, offset)}${newContents.substring(offset + newLength)}";
+      }
+      return new IncrementalAnalysisCache(librarySource, source, unit, oldContents, newContents, offset, oldLength, newLength);
+    }
+    if (cache.offset > offset || offset > cache.offset + cache.newLength) {
+      return null;
+    }
+    cache.newContents = newContents;
+    cache.newLength += newLength - oldLength;
+    return cache;
+  }
+  Source librarySource;
+  Source source;
+  String oldContents;
+  CompilationUnit resolvedUnit;
+  String newContents;
+  int offset = 0;
+  int oldLength = 0;
+  int newLength = 0;
+  IncrementalAnalysisCache(Source librarySource, Source source, CompilationUnit resolvedUnit, String oldContents, String newContents, int offset, int oldLength, int newLength) {
+    this.librarySource = librarySource;
+    this.source = source;
+    this.resolvedUnit = resolvedUnit;
+    this.oldContents = oldContents;
+    this.newContents = newContents;
+    this.offset = offset;
+    this.oldLength = oldLength;
+    this.newLength = newLength;
+  }
+}
+/**
  * Instances of the class `InstrumentedAnalysisContextImpl` implement an
  * [AnalysisContext] by recording instrumentation data and delegating to
  * another analysis context to do the non-instrumentation work.
@@ -6156,7 +6305,7 @@
   /**
    * A HashMap of lists containing the errors that were collected, keyed by each [Source].
    */
-  Map<Source, List<AnalysisError>> _errors = new Map<Source, List<AnalysisError>>();
+  Map<Source, Set<AnalysisError>> _errors = new Map<Source, Set<AnalysisError>>();
 
   /**
    * Add all of the errors recorded by the given listener to this listener.
@@ -6175,13 +6324,13 @@
    * @return an array of errors (not `null`, contains no `null`s)
    */
   List<AnalysisError> get errors {
-    Iterable<MapEntry<Source, List<AnalysisError>>> entrySet = getMapEntrySet(_errors);
+    Iterable<MapEntry<Source, Set<AnalysisError>>> entrySet = getMapEntrySet(_errors);
     int numEntries = entrySet.length;
     if (numEntries == 0) {
       return AnalysisError.NO_ERRORS;
     }
     List<AnalysisError> resultList = new List<AnalysisError>();
-    for (MapEntry<Source, List<AnalysisError>> entry in entrySet) {
+    for (MapEntry<Source, Set<AnalysisError>> entry in entrySet) {
       resultList.addAll(entry.getValue());
     }
     return new List.from(resultList);
@@ -6195,21 +6344,21 @@
    * @return the errors collected by the listener for the passed [Source]
    */
   List<AnalysisError> getErrors2(Source source) {
-    List<AnalysisError> errorsForSource = _errors[source];
+    Set<AnalysisError> errorsForSource = _errors[source];
     if (errorsForSource == null) {
       return AnalysisError.NO_ERRORS;
     } else {
       return new List.from(errorsForSource);
     }
   }
-  void onError(AnalysisError event) {
-    Source source = event.source;
-    List<AnalysisError> errorsForSource = _errors[source];
+  void onError(AnalysisError error) {
+    Source source = error.source;
+    Set<AnalysisError> errorsForSource = _errors[source];
     if (_errors[source] == null) {
-      errorsForSource = new List<AnalysisError>();
+      errorsForSource = new Set<AnalysisError>();
       _errors[source] = errorsForSource;
     }
-    errorsForSource.add(event);
+    javaSetAdd(errorsForSource, error);
   }
 }
 /**
@@ -6768,7 +6917,7 @@
     List<Token> token = [null];
     TimeCounter_TimeCounterHandle timeCounterScan = PerformanceStatistics.scan.start();
     try {
-      Source_ContentReceiver receiver = new Source_ContentReceiver_9(this, errorListener, token);
+      Source_ContentReceiver receiver = new Source_ContentReceiver_11(this, errorListener, token);
       try {
         source.getContents(receiver);
       } on JavaException catch (exception) {
@@ -6851,20 +7000,20 @@
     return new List.from(sources);
   }
 }
-class Source_ContentReceiver_9 implements Source_ContentReceiver {
+class Source_ContentReceiver_11 implements Source_ContentReceiver {
   final ParseDartTask ParseDartTask_this;
   RecordingErrorListener errorListener;
   List<Token> token;
-  Source_ContentReceiver_9(this.ParseDartTask_this, this.errorListener, this.token);
+  Source_ContentReceiver_11(this.ParseDartTask_this, this.errorListener, this.token);
   void accept(CharBuffer contents, int modificationTime) {
     ParseDartTask_this.modificationTime = modificationTime;
-    CharBufferScanner scanner = new CharBufferScanner(ParseDartTask_this.source, contents, errorListener);
+    Scanner scanner = new Scanner(ParseDartTask_this.source, new CharSequenceReader(contents), errorListener);
     token[0] = scanner.tokenize();
     ParseDartTask_this.lineInfo = new LineInfo(scanner.lineStarts);
   }
   void accept2(String contents, int modificationTime) {
     ParseDartTask_this.modificationTime = modificationTime;
-    StringScanner scanner = new StringScanner(ParseDartTask_this.source, contents, errorListener);
+    Scanner scanner = new Scanner(ParseDartTask_this.source, new CharSequenceReader(new CharSequence(contents)), errorListener);
     token[0] = scanner.tokenize();
     ParseDartTask_this.lineInfo = new LineInfo(scanner.lineStarts);
   }
@@ -6958,17 +7107,17 @@
    */
   List<Source> get librarySources {
     List<Source> libraries = new List<Source>();
-    htmlUnit.accept(new RecursiveXmlVisitor_10(this, libraries));
+    htmlUnit.accept(new RecursiveXmlVisitor_12(this, libraries));
     if (libraries.isEmpty) {
       return Source.EMPTY_ARRAY;
     }
     return new List.from(libraries);
   }
 }
-class RecursiveXmlVisitor_10 extends RecursiveXmlVisitor<Object> {
+class RecursiveXmlVisitor_12 extends RecursiveXmlVisitor<Object> {
   final ParseHtmlTask ParseHtmlTask_this;
   List<Source> libraries;
-  RecursiveXmlVisitor_10(this.ParseHtmlTask_this, this.libraries) : super();
+  RecursiveXmlVisitor_12(this.ParseHtmlTask_this, this.libraries) : super();
   Object visitXmlTagNode(XmlTagNode node) {
     if (javaStringEqualsIgnoreCase(node.tag.lexeme, ParseHtmlTask._TAG_SCRIPT)) {
       bool isDartScript = false;
diff --git a/pkg/analyzer_experimental/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
similarity index 92%
rename from pkg/analyzer_experimental/lib/src/generated/error.dart
rename to pkg/analyzer/lib/src/generated/error.dart
index 98fb095..6fc95e0 100644
--- a/pkg/analyzer_experimental/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -320,6 +320,31 @@
       this.correction = JavaString.format(correctionTemplate, arguments);
     }
   }
+  bool operator ==(Object obj) {
+    if (identical(obj, this)) {
+      return true;
+    }
+    if (obj is! AnalysisError) {
+      return false;
+    }
+    AnalysisError other = obj as AnalysisError;
+    if (errorCode != other.errorCode) {
+      return false;
+    }
+    if (offset != other.offset || length != other.length) {
+      return false;
+    }
+    if (isStaticOnly != other.isStaticOnly) {
+      return false;
+    }
+    if (message != other.message) {
+      return false;
+    }
+    if (source != other.source) {
+      return false;
+    }
+    return true;
+  }
 
   /**
    * Return the value of the given property, or `null` if the given property is not defined
@@ -999,10 +1024,16 @@
   static final CompileTimeErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER = new CompileTimeErrorCode.con1('DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER', 37, "Default values aren't allowed in function type parameters");
 
   /**
+   * 7.6.2 Factories: It is a compile-time error if <i>k</i> explicitly specifies a default value
+   * for an optional parameter.
+   */
+  static final CompileTimeErrorCode DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR = new CompileTimeErrorCode.con1('DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR', 38, "Default values aren't allowed in factory constructors that redirect to another constructor");
+
+  /**
    * 3.1 Scoping: It is a compile-time error if there is more than one entity with the same name
    * declared in the same scope.
    */
-  static final CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_DEFAULT = new CompileTimeErrorCode.con1('DUPLICATE_CONSTRUCTOR_DEFAULT', 38, "The default constructor is already defined");
+  static final CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_DEFAULT = new CompileTimeErrorCode.con1('DUPLICATE_CONSTRUCTOR_DEFAULT', 39, "The default constructor is already defined");
 
   /**
    * 3.1 Scoping: It is a compile-time error if there is more than one entity with the same name
@@ -1010,7 +1041,7 @@
    *
    * @param duplicateName the name of the duplicate entity
    */
-  static final CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_NAME = new CompileTimeErrorCode.con1('DUPLICATE_CONSTRUCTOR_NAME', 39, "The constructor with name '%s' is already defined");
+  static final CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_NAME = new CompileTimeErrorCode.con1('DUPLICATE_CONSTRUCTOR_NAME', 40, "The constructor with name '%s' is already defined");
 
   /**
    * 3.1 Scoping: It is a compile-time error if there is more than one entity with the same name
@@ -1023,7 +1054,7 @@
    *
    * @param duplicateName the name of the duplicate entity
    */
-  static final CompileTimeErrorCode DUPLICATE_DEFINITION = new CompileTimeErrorCode.con1('DUPLICATE_DEFINITION', 40, "The name '%s' is already defined");
+  static final CompileTimeErrorCode DUPLICATE_DEFINITION = new CompileTimeErrorCode.con1('DUPLICATE_DEFINITION', 41, "The name '%s' is already defined");
 
   /**
    * 7. Classes: It is a compile-time error if a class has an instance member and a static member
@@ -1035,21 +1066,21 @@
    * @param name the name of the conflicting members
    * @see #DUPLICATE_DEFINITION
    */
-  static final CompileTimeErrorCode DUPLICATE_DEFINITION_INHERITANCE = new CompileTimeErrorCode.con1('DUPLICATE_DEFINITION_INHERITANCE', 41, "The name '%s' is already defined in '%s'");
+  static final CompileTimeErrorCode DUPLICATE_DEFINITION_INHERITANCE = new CompileTimeErrorCode.con1('DUPLICATE_DEFINITION_INHERITANCE', 42, "The name '%s' is already defined in '%s'");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a compile-time error if <i>q<sub>i</sub> =
    * q<sub>j</sub></i> for any <i>i != j</i> [where <i>q<sub>i</sub></i> is the label for a named
    * argument].
    */
-  static final CompileTimeErrorCode DUPLICATE_NAMED_ARGUMENT = new CompileTimeErrorCode.con1('DUPLICATE_NAMED_ARGUMENT', 42, "The argument for the named parameter '%s' was already specified");
+  static final CompileTimeErrorCode DUPLICATE_NAMED_ARGUMENT = new CompileTimeErrorCode.con1('DUPLICATE_NAMED_ARGUMENT', 43, "The argument for the named parameter '%s' was already specified");
 
   /**
    * SDK implementation libraries can be exported only by other SDK libraries.
    *
    * @param uri the uri pointing to a library
    */
-  static final CompileTimeErrorCode EXPORT_INTERNAL_LIBRARY = new CompileTimeErrorCode.con1('EXPORT_INTERNAL_LIBRARY', 43, "The library '%s' is internal and cannot be exported");
+  static final CompileTimeErrorCode EXPORT_INTERNAL_LIBRARY = new CompileTimeErrorCode.con1('EXPORT_INTERNAL_LIBRARY', 44, "The library '%s' is internal and cannot be exported");
 
   /**
    * 14.2 Exports: It is a compile-time error if the compilation unit found at the specified URI is
@@ -1057,7 +1088,7 @@
    *
    * @param uri the uri pointing to a non-library declaration
    */
-  static final CompileTimeErrorCode EXPORT_OF_NON_LIBRARY = new CompileTimeErrorCode.con1('EXPORT_OF_NON_LIBRARY', 44, "The exported library '%s' must not have a part-of directive");
+  static final CompileTimeErrorCode EXPORT_OF_NON_LIBRARY = new CompileTimeErrorCode.con1('EXPORT_OF_NON_LIBRARY', 45, "The exported library '%s' must not have a part-of directive");
 
   /**
    * 7.9 Superclasses: It is a compile-time error if the extends clause of a class <i>C</i> includes
@@ -1065,7 +1096,7 @@
    *
    * @param typeName the name of the superclass that was not found
    */
-  static final CompileTimeErrorCode EXTENDS_NON_CLASS = new CompileTimeErrorCode.con1('EXTENDS_NON_CLASS', 45, "Classes can only extend other classes");
+  static final CompileTimeErrorCode EXTENDS_NON_CLASS = new CompileTimeErrorCode.con1('EXTENDS_NON_CLASS', 46, "Classes can only extend other classes");
 
   /**
    * 12.2 Null: It is a compile-time error for a class to attempt to extend or implement Null.
@@ -1084,7 +1115,7 @@
    * @param typeName the name of the type that cannot be extended
    * @see #IMPLEMENTS_DISALLOWED_CLASS
    */
-  static final CompileTimeErrorCode EXTENDS_DISALLOWED_CLASS = new CompileTimeErrorCode.con1('EXTENDS_DISALLOWED_CLASS', 46, "Classes cannot extend '%s'");
+  static final CompileTimeErrorCode EXTENDS_DISALLOWED_CLASS = new CompileTimeErrorCode.con1('EXTENDS_DISALLOWED_CLASS', 47, "Classes cannot extend '%s'");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt; h</i> or if <i>m &gt;
@@ -1096,21 +1127,21 @@
    * @param requiredCount the maximum number of positional arguments
    * @param argumentCount the actual number of positional arguments given
    */
-  static final CompileTimeErrorCode EXTRA_POSITIONAL_ARGUMENTS = new CompileTimeErrorCode.con1('EXTRA_POSITIONAL_ARGUMENTS', 47, "%d positional arguments expected, but %d found");
+  static final CompileTimeErrorCode EXTRA_POSITIONAL_ARGUMENTS = new CompileTimeErrorCode.con1('EXTRA_POSITIONAL_ARGUMENTS', 48, "%d positional arguments expected, but %d found");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile time
    * error if more than one initializer corresponding to a given instance variable appears in
    * <i>k</i>'s list.
    */
-  static final CompileTimeErrorCode FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS = new CompileTimeErrorCode.con1('FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS', 48, "The field '%s' cannot be initialized twice in the same constructor");
+  static final CompileTimeErrorCode FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS = new CompileTimeErrorCode.con1('FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS', 49, "The field '%s' cannot be initialized twice in the same constructor");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile time
    * error if <i>k</i>'s initializer list contains an initializer for a variable that is initialized
    * by means of an initializing formal of <i>k</i>.
    */
-  static final CompileTimeErrorCode FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER = new CompileTimeErrorCode.con1('FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER', 49, "Fields cannot be initialized in both the parameter list and the initializers");
+  static final CompileTimeErrorCode FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER = new CompileTimeErrorCode.con1('FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER', 50, "Fields cannot be initialized in both the parameter list and the initializers");
 
   /**
    * 5 Variables: It is a compile-time error if a final instance variable that has is initialized by
@@ -1119,19 +1150,19 @@
    *
    * @param name the name of the field in question
    */
-  static final CompileTimeErrorCode FINAL_INITIALIZED_MULTIPLE_TIMES = new CompileTimeErrorCode.con1('FINAL_INITIALIZED_MULTIPLE_TIMES', 50, "'%s' is a final field and so can only be set once");
+  static final CompileTimeErrorCode FINAL_INITIALIZED_MULTIPLE_TIMES = new CompileTimeErrorCode.con1('FINAL_INITIALIZED_MULTIPLE_TIMES', 51, "'%s' is a final field and so can only be set once");
 
   /**
    * 7.6.1 Generative Constructors: It is a compile-time error if an initializing formal is used by
    * a function other than a non-redirecting generative constructor.
    */
-  static final CompileTimeErrorCode FIELD_INITIALIZER_FACTORY_CONSTRUCTOR = new CompileTimeErrorCode.con1('FIELD_INITIALIZER_FACTORY_CONSTRUCTOR', 51, "Initializing formal fields cannot be used in factory constructors");
+  static final CompileTimeErrorCode FIELD_INITIALIZER_FACTORY_CONSTRUCTOR = new CompileTimeErrorCode.con1('FIELD_INITIALIZER_FACTORY_CONSTRUCTOR', 52, "Initializing formal fields cannot be used in factory constructors");
 
   /**
    * 7.6.1 Generative Constructors: It is a compile-time error if an initializing formal is used by
    * a function other than a non-redirecting generative constructor.
    */
-  static final CompileTimeErrorCode FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR = new CompileTimeErrorCode.con1('FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR', 52, "Initializing formal fields can only be used in constructors");
+  static final CompileTimeErrorCode FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR = new CompileTimeErrorCode.con1('FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR', 53, "Initializing formal fields can only be used in constructors");
 
   /**
    * 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
@@ -1140,7 +1171,7 @@
    * 7.6.1 Generative Constructors: It is a compile-time error if an initializing formal is used by
    * a function other than a non-redirecting generative constructor.
    */
-  static final CompileTimeErrorCode FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR = new CompileTimeErrorCode.con1('FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR', 53, "The redirecting constructor cannot have a field initializer");
+  static final CompileTimeErrorCode FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR = new CompileTimeErrorCode.con1('FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR', 54, "The redirecting constructor cannot have a field initializer");
 
   /**
    * 7.2 Getters: It is a compile-time error if a class has both a getter and a method with the same
@@ -1148,7 +1179,7 @@
    *
    * @param name the conflicting name of the getter and method
    */
-  static final CompileTimeErrorCode GETTER_AND_METHOD_WITH_SAME_NAME = new CompileTimeErrorCode.con1('GETTER_AND_METHOD_WITH_SAME_NAME', 54, "'%s' cannot be used to name a getter, there is already a method with the same name");
+  static final CompileTimeErrorCode GETTER_AND_METHOD_WITH_SAME_NAME = new CompileTimeErrorCode.con1('GETTER_AND_METHOD_WITH_SAME_NAME', 55, "'%s' cannot be used to name a getter, there is already a method with the same name");
 
   /**
    * 12.2 Null: It is a compile-time error for a class to attempt to extend or implement Null.
@@ -1167,13 +1198,13 @@
    * @param typeName the name of the type that cannot be implemented
    * @see #EXTENDS_DISALLOWED_CLASS
    */
-  static final CompileTimeErrorCode IMPLEMENTS_DISALLOWED_CLASS = new CompileTimeErrorCode.con1('IMPLEMENTS_DISALLOWED_CLASS', 55, "Classes cannot implement '%s'");
+  static final CompileTimeErrorCode IMPLEMENTS_DISALLOWED_CLASS = new CompileTimeErrorCode.con1('IMPLEMENTS_DISALLOWED_CLASS', 56, "Classes cannot implement '%s'");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the implements clause of a class includes
    * type dynamic.
    */
-  static final CompileTimeErrorCode IMPLEMENTS_DYNAMIC = new CompileTimeErrorCode.con1('IMPLEMENTS_DYNAMIC', 56, "Classes cannot implement 'dynamic'");
+  static final CompileTimeErrorCode IMPLEMENTS_DYNAMIC = new CompileTimeErrorCode.con1('IMPLEMENTS_DYNAMIC', 57, "Classes cannot implement 'dynamic'");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the implements clause of a class <i>C</i>
@@ -1182,7 +1213,7 @@
    *
    * @param typeName the name of the interface that was not found
    */
-  static final CompileTimeErrorCode IMPLEMENTS_NON_CLASS = new CompileTimeErrorCode.con1('IMPLEMENTS_NON_CLASS', 57, "Classes can only implement other classes");
+  static final CompileTimeErrorCode IMPLEMENTS_NON_CLASS = new CompileTimeErrorCode.con1('IMPLEMENTS_NON_CLASS', 58, "Classes can only implement other classes");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if a type <i>T</i> appears more than once in
@@ -1190,7 +1221,7 @@
    *
    * @param className the name of the class that is implemented more than once
    */
-  static final CompileTimeErrorCode IMPLEMENTS_REPEATED = new CompileTimeErrorCode.con1('IMPLEMENTS_REPEATED', 58, "'%s' can only be implemented once");
+  static final CompileTimeErrorCode IMPLEMENTS_REPEATED = new CompileTimeErrorCode.con1('IMPLEMENTS_REPEATED', 59, "'%s' can only be implemented once");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the superclass of a class <i>C</i> appears
@@ -1198,7 +1229,7 @@
    *
    * @param className the name of the class that appears in both "extends" and "implements" clauses
    */
-  static final CompileTimeErrorCode IMPLEMENTS_SUPER_CLASS = new CompileTimeErrorCode.con1('IMPLEMENTS_SUPER_CLASS', 59, "'%s' cannot be used in both 'extends' and 'implements' clauses");
+  static final CompileTimeErrorCode IMPLEMENTS_SUPER_CLASS = new CompileTimeErrorCode.con1('IMPLEMENTS_SUPER_CLASS', 60, "'%s' cannot be used in both 'extends' and 'implements' clauses");
 
   /**
    * 7.6.1 Generative Constructors: Note that <b>this</b> is not in scope on the right hand side of
@@ -1210,14 +1241,14 @@
    *
    * @param name the name of the type in question
    */
-  static final CompileTimeErrorCode IMPLICIT_THIS_REFERENCE_IN_INITIALIZER = new CompileTimeErrorCode.con1('IMPLICIT_THIS_REFERENCE_IN_INITIALIZER', 60, "Only static members can be accessed in initializers");
+  static final CompileTimeErrorCode IMPLICIT_THIS_REFERENCE_IN_INITIALIZER = new CompileTimeErrorCode.con1('IMPLICIT_THIS_REFERENCE_IN_INITIALIZER', 61, "Only static members can be accessed in initializers");
 
   /**
    * SDK implementation libraries can be imported only by other SDK libraries.
    *
    * @param uri the uri pointing to a library
    */
-  static final CompileTimeErrorCode IMPORT_INTERNAL_LIBRARY = new CompileTimeErrorCode.con1('IMPORT_INTERNAL_LIBRARY', 61, "The library '%s' is internal and cannot be imported");
+  static final CompileTimeErrorCode IMPORT_INTERNAL_LIBRARY = new CompileTimeErrorCode.con1('IMPORT_INTERNAL_LIBRARY', 62, "The library '%s' is internal and cannot be imported");
 
   /**
    * 14.1 Imports: It is a compile-time error if the compilation unit found at the specified URI is
@@ -1225,7 +1256,7 @@
    *
    * @param uri the uri pointing to a non-library declaration
    */
-  static final CompileTimeErrorCode IMPORT_OF_NON_LIBRARY = new CompileTimeErrorCode.con1('IMPORT_OF_NON_LIBRARY', 62, "The imported library '%s' must not have a part-of directive");
+  static final CompileTimeErrorCode IMPORT_OF_NON_LIBRARY = new CompileTimeErrorCode.con1('IMPORT_OF_NON_LIBRARY', 63, "The imported library '%s' must not have a part-of directive");
 
   /**
    * 13.9 Switch: It is a compile-time error if values of the expressions <i>e<sub>k</sub></i> are
@@ -1234,7 +1265,7 @@
    * @param expressionSource the expression source code that is the unexpected type
    * @param expectedType the name of the expected type
    */
-  static final CompileTimeErrorCode INCONSISTENT_CASE_EXPRESSION_TYPES = new CompileTimeErrorCode.con1('INCONSISTENT_CASE_EXPRESSION_TYPES', 63, "Case expressions must have the same types, '%s' is not a %s'");
+  static final CompileTimeErrorCode INCONSISTENT_CASE_EXPRESSION_TYPES = new CompileTimeErrorCode.con1('INCONSISTENT_CASE_EXPRESSION_TYPES', 64, "Case expressions must have the same types, '%s' is not a %s'");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile-time
@@ -1245,7 +1276,7 @@
    *          immediately enclosing class
    * @see #INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD
    */
-  static final CompileTimeErrorCode INITIALIZER_FOR_NON_EXISTANT_FIELD = new CompileTimeErrorCode.con1('INITIALIZER_FOR_NON_EXISTANT_FIELD', 64, "'%s' is not a variable in the enclosing class");
+  static final CompileTimeErrorCode INITIALIZER_FOR_NON_EXISTANT_FIELD = new CompileTimeErrorCode.con1('INITIALIZER_FOR_NON_EXISTANT_FIELD', 65, "'%s' is not a variable in the enclosing class");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile-time
@@ -1256,7 +1287,7 @@
    *          enclosing class
    * @see #INITIALIZING_FORMAL_FOR_STATIC_FIELD
    */
-  static final CompileTimeErrorCode INITIALIZER_FOR_STATIC_FIELD = new CompileTimeErrorCode.con1('INITIALIZER_FOR_STATIC_FIELD', 65, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
+  static final CompileTimeErrorCode INITIALIZER_FOR_STATIC_FIELD = new CompileTimeErrorCode.con1('INITIALIZER_FOR_STATIC_FIELD', 66, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
 
   /**
    * 7.6.1 Generative Constructors: An initializing formal has the form <i>this.id</i>. It is a
@@ -1268,7 +1299,7 @@
    * @see #INITIALIZING_FORMAL_FOR_STATIC_FIELD
    * @see #INITIALIZER_FOR_NON_EXISTANT_FIELD
    */
-  static final CompileTimeErrorCode INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD = new CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD', 66, "'%s' is not a variable in the enclosing class");
+  static final CompileTimeErrorCode INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD = new CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD', 67, "'%s' is not a variable in the enclosing class");
 
   /**
    * 7.6.1 Generative Constructors: An initializing formal has the form <i>this.id</i>. It is a
@@ -1279,20 +1310,20 @@
    *          enclosing class
    * @see #INITIALIZER_FOR_STATIC_FIELD
    */
-  static final CompileTimeErrorCode INITIALIZING_FORMAL_FOR_STATIC_FIELD = new CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_STATIC_FIELD', 67, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
+  static final CompileTimeErrorCode INITIALIZING_FORMAL_FOR_STATIC_FIELD = new CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_STATIC_FIELD', 68, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
 
   /**
    * 12.30 Identifier Reference: Otherwise, e is equivalent to the property extraction
    * <b>this</b>.<i>id</i>.
    */
-  static final CompileTimeErrorCode INSTANCE_MEMBER_ACCESS_FROM_STATIC = new CompileTimeErrorCode.con1('INSTANCE_MEMBER_ACCESS_FROM_STATIC', 68, "Instance member cannot be accessed from static method");
+  static final CompileTimeErrorCode INSTANCE_MEMBER_ACCESS_FROM_STATIC = new CompileTimeErrorCode.con1('INSTANCE_MEMBER_ACCESS_FROM_STATIC', 69, "Instance member cannot be accessed from static method");
 
   /**
    * 11 Metadata: Metadata consists of a series of annotations, each of which begin with the
    * character @, followed by a constant expression that must be either a reference to a
    * compile-time constant variable, or a call to a constant constructor.
    */
-  static final CompileTimeErrorCode INVALID_ANNOTATION = new CompileTimeErrorCode.con1('INVALID_ANNOTATION', 69, "Annotation can be only constant variable or constant constructor invocation");
+  static final CompileTimeErrorCode INVALID_ANNOTATION = new CompileTimeErrorCode.con1('INVALID_ANNOTATION', 70, "Annotation can be only constant variable or constant constructor invocation");
 
   /**
    * TODO(brianwilkerson) Remove this when we have decided on how to report errors in compile-time
@@ -1300,26 +1331,26 @@
    *
    * See TODOs in ConstantVisitor
    */
-  static final CompileTimeErrorCode INVALID_CONSTANT = new CompileTimeErrorCode.con1('INVALID_CONSTANT', 70, "Invalid constant value");
+  static final CompileTimeErrorCode INVALID_CONSTANT = new CompileTimeErrorCode.con1('INVALID_CONSTANT', 71, "Invalid constant value");
 
   /**
    * 7.6 Constructors: It is a compile-time error if the name of a constructor is not a constructor
    * name.
    */
-  static final CompileTimeErrorCode INVALID_CONSTRUCTOR_NAME = new CompileTimeErrorCode.con1('INVALID_CONSTRUCTOR_NAME', 71, "Invalid constructor name");
+  static final CompileTimeErrorCode INVALID_CONSTRUCTOR_NAME = new CompileTimeErrorCode.con1('INVALID_CONSTRUCTOR_NAME', 72, "Invalid constructor name");
 
   /**
    * 7.6.2 Factories: It is a compile-time error if <i>M</i> is not the name of the immediately
    * enclosing class.
    */
-  static final CompileTimeErrorCode INVALID_FACTORY_NAME_NOT_A_CLASS = new CompileTimeErrorCode.con1('INVALID_FACTORY_NAME_NOT_A_CLASS', 72, "The name of the immediately enclosing class expected");
+  static final CompileTimeErrorCode INVALID_FACTORY_NAME_NOT_A_CLASS = new CompileTimeErrorCode.con1('INVALID_FACTORY_NAME_NOT_A_CLASS', 73, "The name of the immediately enclosing class expected");
 
   /**
    * 12.10 This: It is a compile-time error if this appears in a top-level function or variable
    * initializer, in a factory constructor, or in a static method or variable initializer, or in the
    * initializer of an instance variable.
    */
-  static final CompileTimeErrorCode INVALID_REFERENCE_TO_THIS = new CompileTimeErrorCode.con1('INVALID_REFERENCE_TO_THIS', 73, "Invalid reference to 'this' expression");
+  static final CompileTimeErrorCode INVALID_REFERENCE_TO_THIS = new CompileTimeErrorCode.con1('INVALID_REFERENCE_TO_THIS', 74, "Invalid reference to 'this' expression");
 
   /**
    * 12.6 Lists: It is a compile time error if the type argument of a constant list literal includes
@@ -1327,7 +1358,7 @@
    *
    * @name the name of the type parameter
    */
-  static final CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST = new CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_LIST', 74, "Constant list literals cannot include a type parameter as a type argument, such as '%s'");
+  static final CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST = new CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_LIST', 75, "Constant list literals cannot include a type parameter as a type argument, such as '%s'");
 
   /**
    * 12.7 Maps: It is a compile time error if the type arguments of a constant map literal include a
@@ -1335,7 +1366,7 @@
    *
    * @name the name of the type parameter
    */
-  static final CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP = new CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_MAP', 75, "Constant map literals cannot include a type parameter as a type argument, such as '%s'");
+  static final CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP = new CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_MAP', 76, "Constant map literals cannot include a type parameter as a type argument, such as '%s'");
 
   /**
    * 14.2 Exports: It is a compile-time error if the compilation unit found at the specified URI is
@@ -1350,7 +1381,7 @@
    * @param uri the URI that is invalid
    * @see #URI_DOES_NOT_EXIST
    */
-  static final CompileTimeErrorCode INVALID_URI = new CompileTimeErrorCode.con1('INVALID_URI', 76, "Invalid URI syntax: '%s'");
+  static final CompileTimeErrorCode INVALID_URI = new CompileTimeErrorCode.con1('INVALID_URI', 77, "Invalid URI syntax: '%s'");
 
   /**
    * 13.13 Break: It is a compile-time error if no such statement <i>s<sub>E</sub></i> exists within
@@ -1361,7 +1392,7 @@
    *
    * @param labelName the name of the unresolvable label
    */
-  static final CompileTimeErrorCode LABEL_IN_OUTER_SCOPE = new CompileTimeErrorCode.con1('LABEL_IN_OUTER_SCOPE', 77, "Cannot reference label '%s' declared in an outer method");
+  static final CompileTimeErrorCode LABEL_IN_OUTER_SCOPE = new CompileTimeErrorCode.con1('LABEL_IN_OUTER_SCOPE', 78, "Cannot reference label '%s' declared in an outer method");
 
   /**
    * 13.13 Break: It is a compile-time error if no such statement <i>s<sub>E</sub></i> exists within
@@ -1372,7 +1403,7 @@
    *
    * @param labelName the name of the unresolvable label
    */
-  static final CompileTimeErrorCode LABEL_UNDEFINED = new CompileTimeErrorCode.con1('LABEL_UNDEFINED', 78, "Cannot reference undefined label '%s'");
+  static final CompileTimeErrorCode LABEL_UNDEFINED = new CompileTimeErrorCode.con1('LABEL_UNDEFINED', 79, "Cannot reference undefined label '%s'");
 
   /**
    * 12.6 Lists: A run-time list literal &lt;<i>E</i>&gt; [<i>e<sub>1</sub></i> ...
@@ -1388,7 +1419,7 @@
    * It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 &lt;=
    * j &lt;= m</i>.
    */
-  static final CompileTimeErrorCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = new CompileTimeErrorCode.con1('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE', 79, "The element type '%s' cannot be assigned to the list type '%s'");
+  static final CompileTimeErrorCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = new CompileTimeErrorCode.con1('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE', 80, "The element type '%s' cannot be assigned to the list type '%s'");
 
   /**
    * 12.7 Map: A run-time map literal &lt;<i>K</i>, <i>V</i>&gt; [<i>k<sub>1</sub></i> :
@@ -1404,7 +1435,7 @@
    * It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 &lt;=
    * j &lt;= m</i>.
    */
-  static final CompileTimeErrorCode MAP_KEY_TYPE_NOT_ASSIGNABLE = new CompileTimeErrorCode.con1('MAP_KEY_TYPE_NOT_ASSIGNABLE', 80, "The element type '%s' cannot be assigned to the map key type '%s'");
+  static final CompileTimeErrorCode MAP_KEY_TYPE_NOT_ASSIGNABLE = new CompileTimeErrorCode.con1('MAP_KEY_TYPE_NOT_ASSIGNABLE', 81, "The element type '%s' cannot be assigned to the map key type '%s'");
 
   /**
    * 12.7 Map: A run-time map literal &lt;<i>K</i>, <i>V</i>&gt; [<i>k<sub>1</sub></i> :
@@ -1420,13 +1451,13 @@
    * It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 &lt;=
    * j &lt;= m</i>.
    */
-  static final CompileTimeErrorCode MAP_VALUE_TYPE_NOT_ASSIGNABLE = new CompileTimeErrorCode.con1('MAP_VALUE_TYPE_NOT_ASSIGNABLE', 81, "The element type '%s' cannot be assigned to the map value type '%s'");
+  static final CompileTimeErrorCode MAP_VALUE_TYPE_NOT_ASSIGNABLE = new CompileTimeErrorCode.con1('MAP_VALUE_TYPE_NOT_ASSIGNABLE', 82, "The element type '%s' cannot be assigned to the map value type '%s'");
 
   /**
    * 7 Classes: It is a compile time error if a class <i>C</i> declares a member with the same name
    * as <i>C</i>.
    */
-  static final CompileTimeErrorCode MEMBER_WITH_CLASS_NAME = new CompileTimeErrorCode.con1('MEMBER_WITH_CLASS_NAME', 82, "Class members cannot have the same name as the enclosing class");
+  static final CompileTimeErrorCode MEMBER_WITH_CLASS_NAME = new CompileTimeErrorCode.con1('MEMBER_WITH_CLASS_NAME', 83, "Class members cannot have the same name as the enclosing class");
 
   /**
    * 7.2 Getters: It is a compile-time error if a class has both a getter and a method with the same
@@ -1434,17 +1465,17 @@
    *
    * @param name the conflicting name of the getter and method
    */
-  static final CompileTimeErrorCode METHOD_AND_GETTER_WITH_SAME_NAME = new CompileTimeErrorCode.con1('METHOD_AND_GETTER_WITH_SAME_NAME', 83, "'%s' cannot be used to name a method, there is already a getter with the same name");
+  static final CompileTimeErrorCode METHOD_AND_GETTER_WITH_SAME_NAME = new CompileTimeErrorCode.con1('METHOD_AND_GETTER_WITH_SAME_NAME', 84, "'%s' cannot be used to name a method, there is already a getter with the same name");
 
   /**
    * 12.1 Constants: A constant expression is ... a constant list literal.
    */
-  static final CompileTimeErrorCode MISSING_CONST_IN_LIST_LITERAL = new CompileTimeErrorCode.con1('MISSING_CONST_IN_LIST_LITERAL', 84, "List literals must be prefixed with 'const' when used as a constant expression");
+  static final CompileTimeErrorCode MISSING_CONST_IN_LIST_LITERAL = new CompileTimeErrorCode.con1('MISSING_CONST_IN_LIST_LITERAL', 85, "List literals must be prefixed with 'const' when used as a constant expression");
 
   /**
    * 12.1 Constants: A constant expression is ... a constant map literal.
    */
-  static final CompileTimeErrorCode MISSING_CONST_IN_MAP_LITERAL = new CompileTimeErrorCode.con1('MISSING_CONST_IN_MAP_LITERAL', 85, "Map literals must be prefixed with 'const' when used as a constant expression");
+  static final CompileTimeErrorCode MISSING_CONST_IN_MAP_LITERAL = new CompileTimeErrorCode.con1('MISSING_CONST_IN_MAP_LITERAL', 86, "Map literals must be prefixed with 'const' when used as a constant expression");
 
   /**
    * 9 Mixins: It is a compile-time error if a declared or derived mixin explicitly declares a
@@ -1452,7 +1483,7 @@
    *
    * @param typeName the name of the mixin that is invalid
    */
-  static final CompileTimeErrorCode MIXIN_DECLARES_CONSTRUCTOR = new CompileTimeErrorCode.con1('MIXIN_DECLARES_CONSTRUCTOR', 86, "The class '%s' cannot be used as a mixin because it declares a constructor");
+  static final CompileTimeErrorCode MIXIN_DECLARES_CONSTRUCTOR = new CompileTimeErrorCode.con1('MIXIN_DECLARES_CONSTRUCTOR', 87, "The class '%s' cannot be used as a mixin because it declares a constructor");
 
   /**
    * 9 Mixins: It is a compile-time error if a mixin is derived from a class whose superclass is not
@@ -1460,7 +1491,7 @@
    *
    * @param typeName the name of the mixin that is invalid
    */
-  static final CompileTimeErrorCode MIXIN_INHERITS_FROM_NOT_OBJECT = new CompileTimeErrorCode.con1('MIXIN_INHERITS_FROM_NOT_OBJECT', 87, "The class '%s' cannot be used as a mixin because it extends a class other than Object");
+  static final CompileTimeErrorCode MIXIN_INHERITS_FROM_NOT_OBJECT = new CompileTimeErrorCode.con1('MIXIN_INHERITS_FROM_NOT_OBJECT', 88, "The class '%s' cannot be used as a mixin because it extends a class other than Object");
 
   /**
    * 12.2 Null: It is a compile-time error for a class to attempt to extend or implement Null.
@@ -1479,43 +1510,43 @@
    * @param typeName the name of the type that cannot be extended
    * @see #IMPLEMENTS_DISALLOWED_CLASS
    */
-  static final CompileTimeErrorCode MIXIN_OF_DISALLOWED_CLASS = new CompileTimeErrorCode.con1('MIXIN_OF_DISALLOWED_CLASS', 88, "Classes cannot mixin '%s'");
+  static final CompileTimeErrorCode MIXIN_OF_DISALLOWED_CLASS = new CompileTimeErrorCode.con1('MIXIN_OF_DISALLOWED_CLASS', 89, "Classes cannot mixin '%s'");
 
   /**
    * 9.1 Mixin Application: It is a compile-time error if <i>M</i> does not denote a class or mixin
    * available in the immediately enclosing scope.
    */
-  static final CompileTimeErrorCode MIXIN_OF_NON_CLASS = new CompileTimeErrorCode.con1('MIXIN_OF_NON_CLASS', 89, "Classes can only mixin other classes");
+  static final CompileTimeErrorCode MIXIN_OF_NON_CLASS = new CompileTimeErrorCode.con1('MIXIN_OF_NON_CLASS', 90, "Classes can only mixin other classes");
 
   /**
    * 9 Mixins: It is a compile-time error if a declared or derived mixin refers to super.
    */
-  static final CompileTimeErrorCode MIXIN_REFERENCES_SUPER = new CompileTimeErrorCode.con1('MIXIN_REFERENCES_SUPER', 90, "The class '%s' cannot be used as a mixin because it references 'super'");
+  static final CompileTimeErrorCode MIXIN_REFERENCES_SUPER = new CompileTimeErrorCode.con1('MIXIN_REFERENCES_SUPER', 91, "The class '%s' cannot be used as a mixin because it references 'super'");
 
   /**
    * 9.1 Mixin Application: It is a compile-time error if <i>S</i> does not denote a class available
    * in the immediately enclosing scope.
    */
-  static final CompileTimeErrorCode MIXIN_WITH_NON_CLASS_SUPERCLASS = new CompileTimeErrorCode.con1('MIXIN_WITH_NON_CLASS_SUPERCLASS', 91, "Mixin can only be applied to class");
+  static final CompileTimeErrorCode MIXIN_WITH_NON_CLASS_SUPERCLASS = new CompileTimeErrorCode.con1('MIXIN_WITH_NON_CLASS_SUPERCLASS', 92, "Mixin can only be applied to class");
 
   /**
    * 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
    * only action is to invoke another generative constructor.
    */
-  static final CompileTimeErrorCode MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS = new CompileTimeErrorCode.con1('MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS', 92, "Constructor may have at most one 'this' redirection");
+  static final CompileTimeErrorCode MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS = new CompileTimeErrorCode.con1('MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS', 93, "Constructor may have at most one 'this' redirection");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. Then <i>k</i> may
    * include at most one superinitializer in its initializer list or a compile time error occurs.
    */
-  static final CompileTimeErrorCode MULTIPLE_SUPER_INITIALIZERS = new CompileTimeErrorCode.con1('MULTIPLE_SUPER_INITIALIZERS', 93, "Constructor may have at most one 'super' initializer");
+  static final CompileTimeErrorCode MULTIPLE_SUPER_INITIALIZERS = new CompileTimeErrorCode.con1('MULTIPLE_SUPER_INITIALIZERS', 94, "Constructor may have at most one 'super' initializer");
 
   /**
    * 11 Metadata: Metadata consists of a series of annotations, each of which begin with the
    * character @, followed by a constant expression that must be either a reference to a
    * compile-time constant variable, or a call to a constant constructor.
    */
-  static final CompileTimeErrorCode NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS = new CompileTimeErrorCode.con1('NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS', 94, "Annotation creation must have arguments");
+  static final CompileTimeErrorCode NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS = new CompileTimeErrorCode.con1('NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS', 95, "Annotation creation must have arguments");
 
   /**
    * 7.6.1 Generative Constructors: If no superinitializer is provided, an implicit superinitializer
@@ -1525,7 +1556,7 @@
    * 7.6.1 Generative constructors. It is a compile-time error if class <i>S</i> does not declare a
    * generative constructor named <i>S</i> (respectively <i>S.id</i>)
    */
-  static final CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT = new CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT', 95, "The class '%s' does not have a default constructor");
+  static final CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT = new CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT', 96, "The class '%s' does not have a default constructor");
 
   /**
    * 7.6 Constructors: Iff no constructor is specified for a class <i>C</i>, it implicitly has a
@@ -1534,13 +1565,13 @@
    * 7.6.1 Generative constructors. It is a compile-time error if class <i>S</i> does not declare a
    * generative constructor named <i>S</i> (respectively <i>S.id</i>)
    */
-  static final CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT = new CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT', 96, "The class '%s' does not have a default constructor");
+  static final CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT = new CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT', 97, "The class '%s' does not have a default constructor");
 
   /**
    * 13.2 Expression Statements: It is a compile-time error if a non-constant map literal that has
    * no explicit type arguments appears in a place where a statement is expected.
    */
-  static final CompileTimeErrorCode NON_CONST_MAP_AS_EXPRESSION_STATEMENT = new CompileTimeErrorCode.con1('NON_CONST_MAP_AS_EXPRESSION_STATEMENT', 97, "A non-constant map literal without type arguments cannot be used as an expression statement");
+  static final CompileTimeErrorCode NON_CONST_MAP_AS_EXPRESSION_STATEMENT = new CompileTimeErrorCode.con1('NON_CONST_MAP_AS_EXPRESSION_STATEMENT', 98, "A non-constant map literal without type arguments cannot be used as an expression statement");
 
   /**
    * 13.9 Switch: Given a switch statement of the form <i>switch (e) { label<sub>11</sub> &hellip;
@@ -1551,44 +1582,44 @@
    * s<sub>n</sub>}</i>, it is a compile-time error if the expressions <i>e<sub>k</sub></i> are not
    * compile-time constants, for all <i>1 &lt;= k &lt;= n</i>.
    */
-  static final CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION = new CompileTimeErrorCode.con1('NON_CONSTANT_CASE_EXPRESSION', 98, "Case expressions must be constant");
+  static final CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION = new CompileTimeErrorCode.con1('NON_CONSTANT_CASE_EXPRESSION', 99, "Case expressions must be constant");
 
   /**
    * 6.2.2 Optional Formals: It is a compile-time error if the default value of an optional
    * parameter is not a compile-time constant.
    */
-  static final CompileTimeErrorCode NON_CONSTANT_DEFAULT_VALUE = new CompileTimeErrorCode.con1('NON_CONSTANT_DEFAULT_VALUE', 99, "Default values of an optional parameter must be constant");
+  static final CompileTimeErrorCode NON_CONSTANT_DEFAULT_VALUE = new CompileTimeErrorCode.con1('NON_CONSTANT_DEFAULT_VALUE', 100, "Default values of an optional parameter must be constant");
 
   /**
    * 12.6 Lists: It is a compile time error if an element of a constant list literal is not a
    * compile-time constant.
    */
-  static final CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT = new CompileTimeErrorCode.con1('NON_CONSTANT_LIST_ELEMENT', 100, "'const' lists must have all constant values");
+  static final CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT = new CompileTimeErrorCode.con1('NON_CONSTANT_LIST_ELEMENT', 101, "'const' lists must have all constant values");
 
   /**
    * 12.7 Maps: It is a compile time error if either a key or a value of an entry in a constant map
    * literal is not a compile-time constant.
    */
-  static final CompileTimeErrorCode NON_CONSTANT_MAP_KEY = new CompileTimeErrorCode.con1('NON_CONSTANT_MAP_KEY', 101, "The keys in a map must be constant");
+  static final CompileTimeErrorCode NON_CONSTANT_MAP_KEY = new CompileTimeErrorCode.con1('NON_CONSTANT_MAP_KEY', 102, "The keys in a map must be constant");
 
   /**
    * 12.7 Maps: It is a compile time error if either a key or a value of an entry in a constant map
    * literal is not a compile-time constant.
    */
-  static final CompileTimeErrorCode NON_CONSTANT_MAP_VALUE = new CompileTimeErrorCode.con1('NON_CONSTANT_MAP_VALUE', 102, "The values in a 'const' map must be constant");
+  static final CompileTimeErrorCode NON_CONSTANT_MAP_VALUE = new CompileTimeErrorCode.con1('NON_CONSTANT_MAP_VALUE', 103, "The values in a 'const' map must be constant");
 
   /**
    * 11 Metadata: Metadata consists of a series of annotations, each of which begin with the
    * character @, followed by a constant expression that must be either a reference to a
    * compile-time constant variable, or a call to a constant constructor.
    */
-  static final CompileTimeErrorCode NON_CONSTANT_ANNOTATION_CONSTRUCTOR = new CompileTimeErrorCode.con1('NON_CONSTANT_ANNOTATION_CONSTRUCTOR', 103, "Annotation creation can use only 'const' constructor");
+  static final CompileTimeErrorCode NON_CONSTANT_ANNOTATION_CONSTRUCTOR = new CompileTimeErrorCode.con1('NON_CONSTANT_ANNOTATION_CONSTRUCTOR', 104, "Annotation creation can use only 'const' constructor");
 
   /**
    * 7.6.3 Constant Constructors: Any expression that appears within the initializer list of a
    * constant constructor must be a potentially constant expression, or a compile-time error occurs.
    */
-  static final CompileTimeErrorCode NON_CONSTANT_VALUE_IN_INITIALIZER = new CompileTimeErrorCode.con1('NON_CONSTANT_VALUE_IN_INITIALIZER', 104, "Initializer expressions in constant constructors must be constants");
+  static final CompileTimeErrorCode NON_CONSTANT_VALUE_IN_INITIALIZER = new CompileTimeErrorCode.con1('NON_CONSTANT_VALUE_IN_INITIALIZER', 105, "Initializer expressions in constant constructors must be constants");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m < h</i> or if <i>m > n</i>.
@@ -1599,7 +1630,7 @@
    * @param requiredCount the expected number of required arguments
    * @param argumentCount the actual number of positional arguments given
    */
-  static final CompileTimeErrorCode NOT_ENOUGH_REQUIRED_ARGUMENTS = new CompileTimeErrorCode.con1('NOT_ENOUGH_REQUIRED_ARGUMENTS', 105, "%d required argument(s) expected, but %d found");
+  static final CompileTimeErrorCode NOT_ENOUGH_REQUIRED_ARGUMENTS = new CompileTimeErrorCode.con1('NOT_ENOUGH_REQUIRED_ARGUMENTS', 106, "%d required argument(s) expected, but %d found");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
@@ -1607,17 +1638,17 @@
    * a compile-time error if class <i>S</i> does not declare a generative constructor named <i>S</i>
    * (respectively <i>S.id</i>)
    */
-  static final CompileTimeErrorCode NON_GENERATIVE_CONSTRUCTOR = new CompileTimeErrorCode.con1('NON_GENERATIVE_CONSTRUCTOR', 106, "The generative constructor '%s' expected, but factory found");
+  static final CompileTimeErrorCode NON_GENERATIVE_CONSTRUCTOR = new CompileTimeErrorCode.con1('NON_GENERATIVE_CONSTRUCTOR', 107, "The generative constructor '%s' expected, but factory found");
 
   /**
    * 7.9 Superclasses: It is a compile-time error to specify an extends clause for class Object.
    */
-  static final CompileTimeErrorCode OBJECT_CANNOT_EXTEND_ANOTHER_CLASS = new CompileTimeErrorCode.con1('OBJECT_CANNOT_EXTEND_ANOTHER_CLASS', 107, "");
+  static final CompileTimeErrorCode OBJECT_CANNOT_EXTEND_ANOTHER_CLASS = new CompileTimeErrorCode.con1('OBJECT_CANNOT_EXTEND_ANOTHER_CLASS', 108, "");
 
   /**
    * 7.1.1 Operators: It is a compile-time error to declare an optional parameter in an operator.
    */
-  static final CompileTimeErrorCode OPTIONAL_PARAMETER_IN_OPERATOR = new CompileTimeErrorCode.con1('OPTIONAL_PARAMETER_IN_OPERATOR', 108, "Optional parameters are not allowed when defining an operator");
+  static final CompileTimeErrorCode OPTIONAL_PARAMETER_IN_OPERATOR = new CompileTimeErrorCode.con1('OPTIONAL_PARAMETER_IN_OPERATOR', 109, "Optional parameters are not allowed when defining an operator");
 
   /**
    * 14.3 Parts: It is a compile time error if the contents of the URI are not a valid part
@@ -1625,25 +1656,25 @@
    *
    * @param uri the uri pointing to a non-library declaration
    */
-  static final CompileTimeErrorCode PART_OF_NON_PART = new CompileTimeErrorCode.con1('PART_OF_NON_PART', 109, "The included part '%s' must have a part-of directive");
+  static final CompileTimeErrorCode PART_OF_NON_PART = new CompileTimeErrorCode.con1('PART_OF_NON_PART', 110, "The included part '%s' must have a part-of directive");
 
   /**
    * 14.1 Imports: It is a compile-time error if the current library declares a top-level member
    * named <i>p</i>.
    */
-  static final CompileTimeErrorCode PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER = new CompileTimeErrorCode.con1('PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER', 110, "The name '%s' is already used as an import prefix and cannot be used to name a top-level element");
+  static final CompileTimeErrorCode PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER = new CompileTimeErrorCode.con1('PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER', 111, "The name '%s' is already used as an import prefix and cannot be used to name a top-level element");
 
   /**
    * 6.2.2 Optional Formals: It is a compile-time error if the name of a named optional parameter
    * begins with an '_' character.
    */
-  static final CompileTimeErrorCode PRIVATE_OPTIONAL_PARAMETER = new CompileTimeErrorCode.con1('PRIVATE_OPTIONAL_PARAMETER', 111, "Named optional parameters cannot start with an underscore");
+  static final CompileTimeErrorCode PRIVATE_OPTIONAL_PARAMETER = new CompileTimeErrorCode.con1('PRIVATE_OPTIONAL_PARAMETER', 112, "Named optional parameters cannot start with an underscore");
 
   /**
    * 12.1 Constants: It is a compile-time error if the value of a compile-time constant expression
    * depends on itself.
    */
-  static final CompileTimeErrorCode RECURSIVE_COMPILE_TIME_CONSTANT = new CompileTimeErrorCode.con1('RECURSIVE_COMPILE_TIME_CONSTANT', 112, "");
+  static final CompileTimeErrorCode RECURSIVE_COMPILE_TIME_CONSTANT = new CompileTimeErrorCode.con1('RECURSIVE_COMPILE_TIME_CONSTANT', 113, "");
 
   /**
    * 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
@@ -1654,13 +1685,13 @@
    *
    * https://code.google.com/p/dart/issues/detail?id=954
    */
-  static final CompileTimeErrorCode RECURSIVE_CONSTRUCTOR_REDIRECT = new CompileTimeErrorCode.con1('RECURSIVE_CONSTRUCTOR_REDIRECT', 113, "Cycle in redirecting generative constructors");
+  static final CompileTimeErrorCode RECURSIVE_CONSTRUCTOR_REDIRECT = new CompileTimeErrorCode.con1('RECURSIVE_CONSTRUCTOR_REDIRECT', 114, "Cycle in redirecting generative constructors");
 
   /**
    * 7.6.2 Factories: It is a compile-time error if a redirecting factory constructor redirects to
    * itself, either directly or indirectly via a sequence of redirections.
    */
-  static final CompileTimeErrorCode RECURSIVE_FACTORY_REDIRECT = new CompileTimeErrorCode.con1('RECURSIVE_FACTORY_REDIRECT', 114, "Cycle in redirecting factory constructors");
+  static final CompileTimeErrorCode RECURSIVE_FACTORY_REDIRECT = new CompileTimeErrorCode.con1('RECURSIVE_FACTORY_REDIRECT', 115, "Cycle in redirecting factory constructors");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
@@ -1673,7 +1704,7 @@
    * @param className the name of the class that implements itself recursively
    * @param strImplementsPath a string representation of the implements loop
    */
-  static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE = new CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE', 115, "'%s' cannot be a superinterface of itself: %s");
+  static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE = new CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE', 116, "'%s' cannot be a superinterface of itself: %s");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
@@ -1685,7 +1716,7 @@
    *
    * @param className the name of the class that implements itself recursively
    */
-  static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS = new CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS', 116, "'%s' cannot extend itself");
+  static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS = new CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS', 117, "'%s' cannot extend itself");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
@@ -1697,31 +1728,37 @@
    *
    * @param className the name of the class that implements itself recursively
    */
-  static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS = new CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS', 117, "'%s' cannot implement itself");
+  static final CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS = new CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS', 118, "'%s' cannot implement itself");
 
   /**
    * 7.6.2 Factories: It is a compile-time error if <i>k</i> is prefixed with the const modifier but
    * <i>k'</i> is not a constant constructor.
    */
-  static final CompileTimeErrorCode REDIRECT_TO_NON_CONST_CONSTRUCTOR = new CompileTimeErrorCode.con1('REDIRECT_TO_NON_CONST_CONSTRUCTOR', 118, "Constant factory constructor cannot delegate to a non-constant constructor");
+  static final CompileTimeErrorCode REDIRECT_TO_NON_CONST_CONSTRUCTOR = new CompileTimeErrorCode.con1('REDIRECT_TO_NON_CONST_CONSTRUCTOR', 119, "Constant factory constructor cannot delegate to a non-constant constructor");
 
   /**
    * 13.3 Local Variable Declaration: It is a compile-time error if <i>e</i> refers to the name
    * <i>v</i> or the name <i>v=</i>.
    */
-  static final CompileTimeErrorCode REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER = new CompileTimeErrorCode.con1('REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER', 119, "The name '%s' cannot be referenced in the initializer of a variable with the same name");
+  static final CompileTimeErrorCode REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER = new CompileTimeErrorCode.con1('REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER', 120, "The name '%s' cannot be referenced in the initializer of a variable with the same name");
+
+  /**
+   * 5 Variables: A local variable may only be referenced at a source code location that is after
+   * its initializer, if any, is complete, or a compile-time error occurs.
+   */
+  static final CompileTimeErrorCode REFERENCED_BEFORE_DECLARATION = new CompileTimeErrorCode.con1('REFERENCED_BEFORE_DECLARATION', 121, "Local variables cannot be referenced before they are declared");
 
   /**
    * 12.8.1 Rethrow: It is a compile-time error if an expression of the form <i>rethrow;</i> is not
    * enclosed within a on-catch clause.
    */
-  static final CompileTimeErrorCode RETHROW_OUTSIDE_CATCH = new CompileTimeErrorCode.con1('RETHROW_OUTSIDE_CATCH', 120, "rethrow must be inside of a catch clause");
+  static final CompileTimeErrorCode RETHROW_OUTSIDE_CATCH = new CompileTimeErrorCode.con1('RETHROW_OUTSIDE_CATCH', 122, "rethrow must be inside of a catch clause");
 
   /**
    * 13.11 Return: It is a compile-time error if a return statement of the form <i>return e;</i>
    * appears in a generative constructor.
    */
-  static final CompileTimeErrorCode RETURN_IN_GENERATIVE_CONSTRUCTOR = new CompileTimeErrorCode.con1('RETURN_IN_GENERATIVE_CONSTRUCTOR', 121, "Constructors cannot return a value");
+  static final CompileTimeErrorCode RETURN_IN_GENERATIVE_CONSTRUCTOR = new CompileTimeErrorCode.con1('RETURN_IN_GENERATIVE_CONSTRUCTOR', 123, "Constructors cannot return a value");
 
   /**
    * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
@@ -1731,19 +1768,19 @@
    * initializer list, in class Object, in a factory constructor, or in a static method or variable
    * initializer.
    */
-  static final CompileTimeErrorCode SUPER_IN_INVALID_CONTEXT = new CompileTimeErrorCode.con1('SUPER_IN_INVALID_CONTEXT', 122, "Invalid context for 'super' invocation");
+  static final CompileTimeErrorCode SUPER_IN_INVALID_CONTEXT = new CompileTimeErrorCode.con1('SUPER_IN_INVALID_CONTEXT', 124, "Invalid context for 'super' invocation");
 
   /**
    * 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
    * only action is to invoke another generative constructor.
    */
-  static final CompileTimeErrorCode SUPER_IN_REDIRECTING_CONSTRUCTOR = new CompileTimeErrorCode.con1('SUPER_IN_REDIRECTING_CONSTRUCTOR', 123, "The redirecting constructor cannot have a 'super' initializer");
+  static final CompileTimeErrorCode SUPER_IN_REDIRECTING_CONSTRUCTOR = new CompileTimeErrorCode.con1('SUPER_IN_REDIRECTING_CONSTRUCTOR', 125, "The redirecting constructor cannot have a 'super' initializer");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile-time
    * error if a generative constructor of class Object includes a superinitializer.
    */
-  static final CompileTimeErrorCode SUPER_INITIALIZER_IN_OBJECT = new CompileTimeErrorCode.con1('SUPER_INITIALIZER_IN_OBJECT', 124, "");
+  static final CompileTimeErrorCode SUPER_INITIALIZER_IN_OBJECT = new CompileTimeErrorCode.con1('SUPER_INITIALIZER_IN_OBJECT', 126, "");
 
   /**
    * 12.11 Instance Creation: It is a static type warning if any of the type arguments to a
@@ -1762,19 +1799,19 @@
    * @param boundingTypeName the name of the bounding type
    * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
    */
-  static final CompileTimeErrorCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS = new CompileTimeErrorCode.con1('TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', 125, "'%s' does not extend '%s'");
+  static final CompileTimeErrorCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS = new CompileTimeErrorCode.con1('TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', 127, "'%s' does not extend '%s'");
 
   /**
-   * 15.3.1 Typedef: It is a compile-time error if a typedef refers to itself via a chain of
-   * references that does not include a class declaration.
+   * 15.3.1 Typedef: Any self reference, either directly, or recursively via another typedef, is a
+   * compile time error.
    */
-  static final CompileTimeErrorCode TYPE_ALIAS_CANNOT_REFERENCE_ITSELF = new CompileTimeErrorCode.con1('TYPE_ALIAS_CANNOT_REFERENCE_ITSELF', 126, "Type alias can reference itself only via the bounds of its generic parameters");
+  static final CompileTimeErrorCode TYPE_ALIAS_CANNOT_REFERENCE_ITSELF = new CompileTimeErrorCode.con1('TYPE_ALIAS_CANNOT_REFERENCE_ITSELF', 128, "Type alias cannot reference itself directly or recursively via another typedef");
 
   /**
    * 12.11.2 Const: It is a compile-time error if <i>T</i> is not a class accessible in the current
    * scope, optionally followed by type arguments.
    */
-  static final CompileTimeErrorCode UNDEFINED_CLASS = new CompileTimeErrorCode.con1('UNDEFINED_CLASS', 127, "Undefined class '%s'");
+  static final CompileTimeErrorCode UNDEFINED_CLASS = new CompileTimeErrorCode.con1('UNDEFINED_CLASS', 129, "Undefined class '%s'");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
@@ -1782,7 +1819,7 @@
    * a compile-time error if class <i>S</i> does not declare a generative constructor named <i>S</i>
    * (respectively <i>S.id</i>)
    */
-  static final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER = new CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER', 128, "The class '%s' does not have a generative constructor '%s'");
+  static final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER = new CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER', 130, "The class '%s' does not have a generative constructor '%s'");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
@@ -1790,7 +1827,7 @@
    * a compile-time error if class <i>S</i> does not declare a generative constructor named <i>S</i>
    * (respectively <i>S.id</i>)
    */
-  static final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = new CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT', 129, "The class '%s' does not have a default generative constructor");
+  static final CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = new CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT', 131, "The class '%s' does not have a default generative constructor");
 
   /**
    * 12.14.3 Unqualified Invocation: If there exists a lexically visible declaration named
@@ -1800,7 +1837,7 @@
    *
    * @param methodName the name of the method that is undefined
    */
-  static final CompileTimeErrorCode UNDEFINED_FUNCTION = new CompileTimeErrorCode.con1('UNDEFINED_FUNCTION', 130, "The function '%s' is not defined");
+  static final CompileTimeErrorCode UNDEFINED_FUNCTION = new CompileTimeErrorCode.con1('UNDEFINED_FUNCTION', 132, "The function '%s' is not defined");
 
   /**
    * 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub></i>, <i>1<=i<=l</i>,
@@ -1812,7 +1849,7 @@
    *
    * @param name the name of the requested named parameter
    */
-  static final CompileTimeErrorCode UNDEFINED_NAMED_PARAMETER = new CompileTimeErrorCode.con1('UNDEFINED_NAMED_PARAMETER', 131, "The named parameter '%s' is not defined");
+  static final CompileTimeErrorCode UNDEFINED_NAMED_PARAMETER = new CompileTimeErrorCode.con1('UNDEFINED_NAMED_PARAMETER', 133, "The named parameter '%s' is not defined");
 
   /**
    * 14.2 Exports: It is a compile-time error if the compilation unit found at the specified URI is
@@ -1827,7 +1864,7 @@
    * @param uri the URI pointing to a non-existent file
    * @see #INVALID_URI
    */
-  static final CompileTimeErrorCode URI_DOES_NOT_EXIST = new CompileTimeErrorCode.con1('URI_DOES_NOT_EXIST', 132, "Target of URI does not exist: '%s'");
+  static final CompileTimeErrorCode URI_DOES_NOT_EXIST = new CompileTimeErrorCode.con1('URI_DOES_NOT_EXIST', 134, "Target of URI does not exist: '%s'");
 
   /**
    * 14.1 Imports: It is a compile-time error if <i>x</i> is not a compile-time constant, or if
@@ -1839,7 +1876,7 @@
    * 14.5 URIs: It is a compile-time error if the string literal <i>x</i> that describes a URI is
    * not a compile-time constant, or if <i>x</i> involves string interpolation.
    */
-  static final CompileTimeErrorCode URI_WITH_INTERPOLATION = new CompileTimeErrorCode.con1('URI_WITH_INTERPOLATION', 133, "URIs cannot use string interpolation");
+  static final CompileTimeErrorCode URI_WITH_INTERPOLATION = new CompileTimeErrorCode.con1('URI_WITH_INTERPOLATION', 135, "URIs cannot use string interpolation");
 
   /**
    * 7.1.1 Operators: It is a compile-time error if the arity of the user-declared operator []= is
@@ -1852,7 +1889,7 @@
    * @param expectedNumberOfParameters the number of parameters expected
    * @param actualNumberOfParameters the number of parameters found in the operator declaration
    */
-  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR = new CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR', 134, "Operator '%s' should declare exactly %d parameter(s), but %d found");
+  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR = new CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR', 136, "Operator '%s' should declare exactly %d parameter(s), but %d found");
 
   /**
    * 7.1.1 Operators: It is a compile time error if the arity of the user-declared operator - is not
@@ -1860,13 +1897,13 @@
    *
    * @param actualNumberOfParameters the number of parameters found in the operator declaration
    */
-  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS = new CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS', 135, "Operator '-' should declare 0 or 1 parameter, but %d found");
+  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS = new CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS', 137, "Operator '-' should declare 0 or 1 parameter, but %d found");
 
   /**
    * 7.3 Setters: It is a compile-time error if a setter's formal parameter list does not include
    * exactly one required formal parameter <i>p</i>.
    */
-  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER = new CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER', 136, "Setters should declare exactly one required parameter");
+  static final CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER = new CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER', 138, "Setters should declare exactly one required parameter");
   static final List<CompileTimeErrorCode> values = [
       AMBIGUOUS_EXPORT,
       ARGUMENT_DEFINITION_TEST_NON_PARAMETER,
@@ -1906,6 +1943,7 @@
       CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
       DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS,
       DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
+      DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
       DUPLICATE_CONSTRUCTOR_DEFAULT,
       DUPLICATE_CONSTRUCTOR_NAME,
       DUPLICATE_DEFINITION,
@@ -1988,6 +2026,7 @@
       RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS,
       REDIRECT_TO_NON_CONST_CONSTRUCTOR,
       REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER,
+      REFERENCED_BEFORE_DECLARATION,
       RETHROW_OUTSIDE_CATCH,
       RETURN_IN_GENERATIVE_CONSTRUCTOR,
       SUPER_IN_INVALID_CONTEXT,
@@ -2195,47 +2234,10 @@
   static final StaticWarningCode CAST_TO_NON_TYPE = new StaticWarningCode.con1('CAST_TO_NON_TYPE', 6, "The name '%s' is not a type and cannot be used in an 'as' expression");
 
   /**
-   * 16.1.2 Comments: A token of the form <i>[new c](uri)</i> will be replaced by a link in the
-   * formatted output. The link will point at the constructor named <i>c</i> in <i>L</i>. The title
-   * of the link will be <i>c</i>. It is a static warning if uri is not the URI of a dart library
-   * <i>L</i>, or if <i>c</i> is not the name of a constructor of a class declared in the exported
-   * namespace of <i>L</i>.
-   */
-  static final StaticWarningCode COMMENT_REFERENCE_CONSTRUCTOR_NOT_VISIBLE = new StaticWarningCode.con1('COMMENT_REFERENCE_CONSTRUCTOR_NOT_VISIBLE', 7, "");
-
-  /**
-   * 16.1.2 Comments: A token of the form <i>[id](uri)</i> will be replaced by a link in the
-   * formatted output. The link will point at the declaration named <i>id</i> in <i>L</i>. The title
-   * of the link will be <i>id</i>. It is a static warning if uri is not the URI of a dart library
-   * <i>L</i>, or if <i>id</i> is not a name declared in the exported namespace of <i>L</i>.
-   */
-  static final StaticWarningCode COMMENT_REFERENCE_IDENTIFIER_NOT_VISIBLE = new StaticWarningCode.con1('COMMENT_REFERENCE_IDENTIFIER_NOT_VISIBLE', 8, "");
-
-  /**
-   * 16.1.2 Comments: It is a static warning if <i>c</i> does not denote a constructor that
-   * available in the scope of the documentation comment.
-   */
-  static final StaticWarningCode COMMENT_REFERENCE_UNDECLARED_CONSTRUCTOR = new StaticWarningCode.con1('COMMENT_REFERENCE_UNDECLARED_CONSTRUCTOR', 9, "");
-
-  /**
-   * 16.1.2 Comments: It is a static warning if <i>id</i> does not denote a declaration that
-   * available in the scope of the documentation comment.
-   */
-  static final StaticWarningCode COMMENT_REFERENCE_UNDECLARED_IDENTIFIER = new StaticWarningCode.con1('COMMENT_REFERENCE_UNDECLARED_IDENTIFIER', 10, "");
-
-  /**
-   * 16.1.2 Comments: A token of the form <i>[id](uri)</i> will be replaced by a link in the
-   * formatted output. The link will point at the declaration named <i>id</i> in <i>L</i>. The title
-   * of the link will be <i>id</i>. It is a static warning if uri is not the URI of a dart library
-   * <i>L</i>, or if <i>id</i> is not a name declared in the exported namespace of <i>L</i>.
-   */
-  static final StaticWarningCode COMMENT_REFERENCE_URI_NOT_LIBRARY = new StaticWarningCode.con1('COMMENT_REFERENCE_URI_NOT_LIBRARY', 11, "");
-
-  /**
    * 7.4 Abstract Instance Members: It is a static warning if an abstract member is declared or
    * inherited in a concrete class.
    */
-  static final StaticWarningCode CONCRETE_CLASS_WITH_ABSTRACT_MEMBER = new StaticWarningCode.con1('CONCRETE_CLASS_WITH_ABSTRACT_MEMBER', 12, "'%s' must have a method body because '%s' is not abstract");
+  static final StaticWarningCode CONCRETE_CLASS_WITH_ABSTRACT_MEMBER = new StaticWarningCode.con1('CONCRETE_CLASS_WITH_ABSTRACT_MEMBER', 7, "'%s' must have a method body because '%s' is not abstract");
 
   /**
    * 14.1 Imports: If a name <i>N</i> is referenced by a library <i>L</i> and <i>N</i> would be
@@ -2250,7 +2252,7 @@
    * @param sdkLibraryName the name of the dart: library that the element is found
    * @param otherLibraryName the name of the non-dart: library that the element is found
    */
-  static final StaticWarningCode CONFLICTING_DART_IMPORT = new StaticWarningCode.con1('CONFLICTING_DART_IMPORT', 13, "Element '%s' from SDK library '%s' is implicitly hidden by '%s'");
+  static final StaticWarningCode CONFLICTING_DART_IMPORT = new StaticWarningCode.con1('CONFLICTING_DART_IMPORT', 8, "Element '%s' from SDK library '%s' is implicitly hidden by '%s'");
 
   /**
    * 7.2 Getters: It is a static warning if a class <i>C</i> declares an instance getter named
@@ -2259,7 +2261,7 @@
    *
    * @param superName the name of the super class declaring a static member
    */
-  static final StaticWarningCode CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER = new StaticWarningCode.con1('CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER', 14, "Superclass '%s' declares static member with the same name");
+  static final StaticWarningCode CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER = new StaticWarningCode.con1('CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER', 9, "Superclass '%s' declares static member with the same name");
 
   /**
    * 7.3 Setters: It is a static warning if a class <i>C</i> declares an instance setter named
@@ -2268,31 +2270,31 @@
    *
    * @param superName the name of the super class declaring a static member
    */
-  static final StaticWarningCode CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER = new StaticWarningCode.con1('CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER', 15, "Superclass '%s' declares static member with the same name");
+  static final StaticWarningCode CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER = new StaticWarningCode.con1('CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER', 10, "Superclass '%s' declares static member with the same name");
 
   /**
    * 7.2 Getters: It is a static warning if a class declares a static getter named <i>v</i> and also
    * has a non-static setter named <i>v=</i>.
    */
-  static final StaticWarningCode CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER = new StaticWarningCode.con1('CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER', 16, "Class '%s' declares non-static setter with the same name");
+  static final StaticWarningCode CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER = new StaticWarningCode.con1('CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER', 11, "Class '%s' declares non-static setter with the same name");
 
   /**
    * 7.3 Setters: It is a static warning if a class declares a static setter named <i>v=</i> and
    * also has a non-static member named <i>v</i>.
    */
-  static final StaticWarningCode CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER = new StaticWarningCode.con1('CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER', 17, "Class '%s' declares non-static member with the same name");
+  static final StaticWarningCode CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER = new StaticWarningCode.con1('CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER', 12, "Class '%s' declares non-static member with the same name");
 
   /**
    * 12.11.2 Const: Given an instance creation expression of the form <i>const q(a<sub>1</sub>,
    * &hellip; a<sub>n</sub>)</i> it is a static warning if <i>q</i> is the constructor of an
    * abstract class but <i>q</i> is not a factory constructor.
    */
-  static final StaticWarningCode CONST_WITH_ABSTRACT_CLASS = new StaticWarningCode.con1('CONST_WITH_ABSTRACT_CLASS', 18, "Abstract classes cannot be created with a 'const' expression");
+  static final StaticWarningCode CONST_WITH_ABSTRACT_CLASS = new StaticWarningCode.con1('CONST_WITH_ABSTRACT_CLASS', 13, "Abstract classes cannot be created with a 'const' expression");
 
   /**
    * 12.7 Maps: It is a static warning if the values of any two keys in a map literal are equal.
    */
-  static final StaticWarningCode EQUAL_KEYS_IN_MAP = new StaticWarningCode.con1('EQUAL_KEYS_IN_MAP', 19, "Keys in a map cannot be equal");
+  static final StaticWarningCode EQUAL_KEYS_IN_MAP = new StaticWarningCode.con1('EQUAL_KEYS_IN_MAP', 14, "Keys in a map cannot be equal");
 
   /**
    * 14.2 Exports: It is a static warning to export two different libraries with the same name.
@@ -2301,7 +2303,7 @@
    * @param uri2 the uri pointing to a second library
    * @param name the shared name of the exported libraries
    */
-  static final StaticWarningCode EXPORT_DUPLICATED_LIBRARY_NAME = new StaticWarningCode.con1('EXPORT_DUPLICATED_LIBRARY_NAME', 20, "The exported libraries '%s' and '%s' should not have the same name '%s'");
+  static final StaticWarningCode EXPORT_DUPLICATED_LIBRARY_NAME = new StaticWarningCode.con1('EXPORT_DUPLICATED_LIBRARY_NAME', 15, "The exported libraries '%s' and '%s' should not have the same name '%s'");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt; h</i> or if <i>m &gt;
@@ -2311,13 +2313,13 @@
    * @param argumentCount the actual number of positional arguments given
    * @see #NOT_ENOUGH_REQUIRED_ARGUMENTS
    */
-  static final StaticWarningCode EXTRA_POSITIONAL_ARGUMENTS = new StaticWarningCode.con1('EXTRA_POSITIONAL_ARGUMENTS', 21, "%d positional arguments expected, but %d found");
+  static final StaticWarningCode EXTRA_POSITIONAL_ARGUMENTS = new StaticWarningCode.con1('EXTRA_POSITIONAL_ARGUMENTS', 16, "%d positional arguments expected, but %d found");
 
   /**
    * 5. Variables: It is a static warning if a final instance variable that has been initialized at
    * its point of declaration is also initialized in a constructor.
    */
-  static final StaticWarningCode FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION = new StaticWarningCode.con1('FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION', 22, "Values cannot be set in the constructor if they are final, and have already been set");
+  static final StaticWarningCode FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION = new StaticWarningCode.con1('FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION', 17, "Values cannot be set in the constructor if they are final, and have already been set");
 
   /**
    * 5. Variables: It is a static warning if a final instance variable that has been initialized at
@@ -2325,7 +2327,7 @@
    *
    * @param name the name of the field in question
    */
-  static final StaticWarningCode FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR = new StaticWarningCode.con1('FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR', 23, "'%s' is final and was given a value when it was declared, so it cannot be set to a new value");
+  static final StaticWarningCode FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR = new StaticWarningCode.con1('FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR', 18, "'%s' is final and was given a value when it was declared, so it cannot be set to a new value");
 
   /**
    * 7.6.1 Generative Constructors: Execution of an initializer of the form <b>this</b>.<i>v</i> =
@@ -2342,7 +2344,7 @@
    * @param initializerType the name of the type of the initializer expression
    * @param fieldType the name of the type of the field
    */
-  static final StaticWarningCode FIELD_INITIALIZER_NOT_ASSIGNABLE = new StaticWarningCode.con1('FIELD_INITIALIZER_NOT_ASSIGNABLE', 24, "The initializer type '%s' cannot be assigned to the field type '%s'");
+  static final StaticWarningCode FIELD_INITIALIZER_NOT_ASSIGNABLE = new StaticWarningCode.con1('FIELD_INITIALIZER_NOT_ASSIGNABLE', 19, "The initializer type '%s' cannot be assigned to the field type '%s'");
 
   /**
    * 7.6.1 Generative Constructors: An initializing formal has the form <i>this.id</i>. It is a
@@ -2351,7 +2353,7 @@
    * @param parameterType the name of the type of the field formal parameter
    * @param fieldType the name of the type of the field
    */
-  static final StaticWarningCode FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE = new StaticWarningCode.con1('FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE', 25, "The parameter type '%s' is incompatable with the field type '%s'");
+  static final StaticWarningCode FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE = new StaticWarningCode.con1('FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE', 20, "The parameter type '%s' is incompatable with the field type '%s'");
 
   /**
    * 5 Variables: It is a static warning if a library, static or local variable <i>v</i> is final
@@ -2368,13 +2370,13 @@
    *
    * @param name the name of the uninitialized final variable
    */
-  static final StaticWarningCode FINAL_NOT_INITIALIZED = new StaticWarningCode.con1('FINAL_NOT_INITIALIZED', 26, "The final variable '%s' must be initialized");
+  static final StaticWarningCode FINAL_NOT_INITIALIZED = new StaticWarningCode.con1('FINAL_NOT_INITIALIZED', 21, "The final variable '%s' must be initialized");
 
   /**
    * 15.5 Function Types: It is a static warning if a concrete class implements Function and does
    * not have a concrete method named call().
    */
-  static final StaticWarningCode FUNCTION_WITHOUT_CALL = new StaticWarningCode.con1('FUNCTION_WITHOUT_CALL', 27, "Concrete classes that implement Function must implement the method call()");
+  static final StaticWarningCode FUNCTION_WITHOUT_CALL = new StaticWarningCode.con1('FUNCTION_WITHOUT_CALL', 22, "Concrete classes that implement Function must implement the method call()");
 
   /**
    * 14.1 Imports: It is a static warning to import two different libraries with the same name.
@@ -2383,7 +2385,7 @@
    * @param uri2 the uri pointing to a second library
    * @param name the shared name of the imported libraries
    */
-  static final StaticWarningCode IMPORT_DUPLICATED_LIBRARY_NAME = new StaticWarningCode.con1('IMPORT_DUPLICATED_LIBRARY_NAME', 28, "The imported libraries '%s' and '%s' should not have the same name '%s'");
+  static final StaticWarningCode IMPORT_DUPLICATED_LIBRARY_NAME = new StaticWarningCode.con1('IMPORT_DUPLICATED_LIBRARY_NAME', 23, "The imported libraries '%s' and '%s' should not have the same name '%s'");
 
   /**
    * 8.1.1 Inheritance and Overriding: However, if there are multiple members <i>m<sub>1</sub>,
@@ -2395,7 +2397,7 @@
    * not all of the <i>m<sub>i</sub></i> are setters, none of the <i>m<sub>i</sub></i> are
    * inherited, and a static warning is issued.
    */
-  static final StaticWarningCode INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD = new StaticWarningCode.con1('INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD', 29, "'%s' is inherited as a getter and also a method");
+  static final StaticWarningCode INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD = new StaticWarningCode.con1('INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD', 24, "'%s' is inherited as a getter and also a method");
 
   /**
    * 7.1 Instance Methods: It is a static warning if a class <i>C</i> declares an instance method
@@ -2405,7 +2407,7 @@
    * @param memberName the name of the member with the name conflict
    * @param superclassName the name of the enclosing class that has the static member
    */
-  static final StaticWarningCode INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC = new StaticWarningCode.con1('INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC', 30, "'%s' collides with a static member in the superclass '%s'");
+  static final StaticWarningCode INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC = new StaticWarningCode.con1('INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC', 25, "'%s' collides with a static member in the superclass '%s'");
 
   /**
    * 7.2 Getters: It is a static warning if a getter <i>m1</i> overrides a getter <i>m2</i> and the
@@ -2417,7 +2419,7 @@
    * @param className the name of the class where the overridden getter is declared
    * @see #INVALID_METHOD_OVERRIDE_RETURN_TYPE
    */
-  static final StaticWarningCode INVALID_GETTER_OVERRIDE_RETURN_TYPE = new StaticWarningCode.con1('INVALID_GETTER_OVERRIDE_RETURN_TYPE', 31, "The return type '%s' is not assignable to '%s' as required by the getter it is overriding from '%s'");
+  static final StaticWarningCode INVALID_GETTER_OVERRIDE_RETURN_TYPE = new StaticWarningCode.con1('INVALID_GETTER_OVERRIDE_RETURN_TYPE', 26, "The return type '%s' is not assignable to '%s' as required by the getter it is overriding from '%s'");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
@@ -2428,7 +2430,7 @@
    *          actualParamTypeName
    * @param className the name of the class where the overridden method is declared
    */
-  static final StaticWarningCode INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE = new StaticWarningCode.con1('INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE', 32, "The parameter type '%s' is not assignable to '%s' as required by the method it is overriding from '%s'");
+  static final StaticWarningCode INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE = new StaticWarningCode.con1('INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE', 27, "The parameter type '%s' is not assignable to '%s' as required by the method it is overriding from '%s'");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
@@ -2440,7 +2442,7 @@
    * @param className the name of the class where the overridden method is declared
    * @see #INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE
    */
-  static final StaticWarningCode INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE = new StaticWarningCode.con1('INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE', 33, "The parameter type '%s' is not assignable to '%s' as required by the method it is overriding from '%s'");
+  static final StaticWarningCode INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE = new StaticWarningCode.con1('INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE', 28, "The parameter type '%s' is not assignable to '%s' as required by the method it is overriding from '%s'");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
@@ -2451,7 +2453,7 @@
    *          actualParamTypeName
    * @param className the name of the class where the overridden method is declared
    */
-  static final StaticWarningCode INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE = new StaticWarningCode.con1('INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE', 34, "The parameter type '%s' is not assignable to '%s' as required by the method it is overriding from '%s'");
+  static final StaticWarningCode INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE = new StaticWarningCode.con1('INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE', 29, "The parameter type '%s' is not assignable to '%s' as required by the method it is overriding from '%s'");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
@@ -2463,7 +2465,7 @@
    * @param className the name of the class where the overridden method is declared
    * @see #INVALID_GETTER_OVERRIDE_RETURN_TYPE
    */
-  static final StaticWarningCode INVALID_METHOD_OVERRIDE_RETURN_TYPE = new StaticWarningCode.con1('INVALID_METHOD_OVERRIDE_RETURN_TYPE', 35, "The return type '%s' is not assignable to '%s' as required by the method it is overriding from '%s'");
+  static final StaticWarningCode INVALID_METHOD_OVERRIDE_RETURN_TYPE = new StaticWarningCode.con1('INVALID_METHOD_OVERRIDE_RETURN_TYPE', 30, "The return type '%s' is not assignable to '%s' as required by the method it is overriding from '%s'");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
@@ -2471,7 +2473,7 @@
    * a formal parameter <i>p</i> and the signature of <i>m1</i> specifies a different default value
    * for <i>p</i>.
    */
-  static final StaticWarningCode INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED = new StaticWarningCode.con1('INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED', 36, "Parameters cannot override default values, this method overrides '%s.%s' where '%s' has a different value");
+  static final StaticWarningCode INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED = new StaticWarningCode.con1('INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED', 31, "Parameters cannot override default values, this method overrides '%s.%s' where '%s' has a different value");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
@@ -2479,7 +2481,7 @@
    * a formal parameter <i>p</i> and the signature of <i>m1</i> specifies a different default value
    * for <i>p</i>.
    */
-  static final StaticWarningCode INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL = new StaticWarningCode.con1('INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL', 37, "Parameters cannot override default values, this method overrides '%s.%s' where this positional parameter has a different value");
+  static final StaticWarningCode INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL = new StaticWarningCode.con1('INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL', 32, "Parameters cannot override default values, this method overrides '%s.%s' where this positional parameter has a different value");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
@@ -2489,7 +2491,7 @@
    * @param paramCount the number of named parameters in the overridden member
    * @param className the name of the class from the overridden method
    */
-  static final StaticWarningCode INVALID_OVERRIDE_NAMED = new StaticWarningCode.con1('INVALID_OVERRIDE_NAMED', 38, "Missing the named parameter '%s' to match the overridden method from '%s'");
+  static final StaticWarningCode INVALID_OVERRIDE_NAMED = new StaticWarningCode.con1('INVALID_OVERRIDE_NAMED', 33, "Missing the named parameter '%s' to match the overridden method from '%s'");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
@@ -2498,7 +2500,7 @@
    * @param paramCount the number of positional parameters in the overridden member
    * @param className the name of the class from the overridden method
    */
-  static final StaticWarningCode INVALID_OVERRIDE_POSITIONAL = new StaticWarningCode.con1('INVALID_OVERRIDE_POSITIONAL', 39, "Must have at least %d parameters to match the overridden method from '%s'");
+  static final StaticWarningCode INVALID_OVERRIDE_POSITIONAL = new StaticWarningCode.con1('INVALID_OVERRIDE_POSITIONAL', 34, "Must have at least %d parameters to match the overridden method from '%s'");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method <i>m1</i> overrides an
@@ -2508,7 +2510,7 @@
    * @param paramCount the number of required parameters in the overridden member
    * @param className the name of the class from the overridden method
    */
-  static final StaticWarningCode INVALID_OVERRIDE_REQUIRED = new StaticWarningCode.con1('INVALID_OVERRIDE_REQUIRED', 40, "Must have %d required parameters or less to match the overridden method from '%s'");
+  static final StaticWarningCode INVALID_OVERRIDE_REQUIRED = new StaticWarningCode.con1('INVALID_OVERRIDE_REQUIRED', 35, "Must have %d required parameters or less to match the overridden method from '%s'");
 
   /**
    * 7.3 Setters: It is a static warning if a setter <i>m1</i> overrides a setter <i>m2</i> and the
@@ -2520,7 +2522,7 @@
    * @param className the name of the class where the overridden setter is declared
    * @see #INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
    */
-  static final StaticWarningCode INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE = new StaticWarningCode.con1('INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE', 41, "The parameter type '%s' is not assignable to '%s' as required by the setter it is overriding from '%s'");
+  static final StaticWarningCode INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE = new StaticWarningCode.con1('INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE', 36, "The parameter type '%s' is not assignable to '%s' as required by the setter it is overriding from '%s'");
 
   /**
    * 12.6 Lists: A run-time list literal &lt;<i>E</i>&gt; [<i>e<sub>1</sub></i> ...
@@ -2536,7 +2538,7 @@
    * It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 &lt;=
    * j &lt;= m</i>.
    */
-  static final StaticWarningCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = new StaticWarningCode.con1('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE', 42, "The element type '%s' cannot be assigned to the list type '%s'");
+  static final StaticWarningCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = new StaticWarningCode.con1('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE', 37, "The element type '%s' cannot be assigned to the list type '%s'");
 
   /**
    * 12.7 Map: A run-time map literal &lt;<i>K</i>, <i>V</i>&gt; [<i>k<sub>1</sub></i> :
@@ -2552,7 +2554,7 @@
    * It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 &lt;=
    * j &lt;= m</i>.
    */
-  static final StaticWarningCode MAP_KEY_TYPE_NOT_ASSIGNABLE = new StaticWarningCode.con1('MAP_KEY_TYPE_NOT_ASSIGNABLE', 43, "The element type '%s' cannot be assigned to the map key type '%s'");
+  static final StaticWarningCode MAP_KEY_TYPE_NOT_ASSIGNABLE = new StaticWarningCode.con1('MAP_KEY_TYPE_NOT_ASSIGNABLE', 38, "The element type '%s' cannot be assigned to the map key type '%s'");
 
   /**
    * 12.7 Map: A run-time map literal &lt;<i>K</i>, <i>V</i>&gt; [<i>k<sub>1</sub></i> :
@@ -2568,20 +2570,33 @@
    * It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 &lt;=
    * j &lt;= m</i>.
    */
-  static final StaticWarningCode MAP_VALUE_TYPE_NOT_ASSIGNABLE = new StaticWarningCode.con1('MAP_VALUE_TYPE_NOT_ASSIGNABLE', 44, "The element type '%s' cannot be assigned to the map value type '%s'");
+  static final StaticWarningCode MAP_VALUE_TYPE_NOT_ASSIGNABLE = new StaticWarningCode.con1('MAP_VALUE_TYPE_NOT_ASSIGNABLE', 39, "The element type '%s' cannot be assigned to the map value type '%s'");
 
   /**
    * 7.3 Setters: It is a static warning if a class has a setter named <i>v=</i> with argument type
    * <i>T</i> and a getter named <i>v</i> with return type <i>S</i>, and <i>T</i> may not be
    * assigned to <i>S</i>.
    */
-  static final StaticWarningCode MISMATCHED_GETTER_AND_SETTER_TYPES = new StaticWarningCode.con1('MISMATCHED_GETTER_AND_SETTER_TYPES', 45, "The parameter type for setter '%s' is '%s' which is not assignable to its getter (of type '%s')");
+  static final StaticWarningCode MISMATCHED_GETTER_AND_SETTER_TYPES = new StaticWarningCode.con1('MISMATCHED_GETTER_AND_SETTER_TYPES', 40, "The parameter type for setter '%s' is '%s' which is not assignable to its getter (of type '%s')");
+
+  /**
+   * 7.3 Setters: It is a static warning if a class has a setter named <i>v=</i> with argument type
+   * <i>T</i> and a getter named <i>v</i> with return type <i>S</i>, and <i>T</i> may not be
+   * assigned to <i>S</i>.
+   */
+  static final StaticWarningCode MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE = new StaticWarningCode.con1('MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE', 41, "The parameter type for setter '%s' is '%s' which is not assignable to its getter (of type '%s'), from superclass '%s'");
+
+  /**
+   * 13.12 Return: It is a static warning if a function contains both one or more return statements
+   * of the form <i>return;</i> and one or more return statements of the form <i>return e;</i>.
+   */
+  static final StaticWarningCode MIXED_RETURN_TYPES = new StaticWarningCode.con1('MIXED_RETURN_TYPES', 42, "Methods and functions cannot use return both with and without values");
 
   /**
    * 12.11.1 New: It is a static warning if <i>q</i> is a constructor of an abstract class and
    * <i>q</i> is not a factory constructor.
    */
-  static final StaticWarningCode NEW_WITH_ABSTRACT_CLASS = new StaticWarningCode.con1('NEW_WITH_ABSTRACT_CLASS', 46, "Abstract classes cannot be created with a 'new' expression");
+  static final StaticWarningCode NEW_WITH_ABSTRACT_CLASS = new StaticWarningCode.con1('NEW_WITH_ABSTRACT_CLASS', 43, "Abstract classes cannot be created with a 'new' expression");
 
   /**
    * 15.8 Parameterized Types: Any use of a malbounded type gives rise to a static warning.
@@ -2592,7 +2607,7 @@
    * @see CompileTimeErrorCode#CONST_WITH_INVALID_TYPE_PARAMETERS
    * @see StaticTypeWarningCode#WRONG_NUMBER_OF_TYPE_ARGUMENTS
    */
-  static final StaticWarningCode NEW_WITH_INVALID_TYPE_PARAMETERS = new StaticWarningCode.con1('NEW_WITH_INVALID_TYPE_PARAMETERS', 47, "The type '%s' is declared with %d type parameters, but %d type arguments were given");
+  static final StaticWarningCode NEW_WITH_INVALID_TYPE_PARAMETERS = new StaticWarningCode.con1('NEW_WITH_INVALID_TYPE_PARAMETERS', 44, "The type '%s' is declared with %d type parameters, but %d type arguments were given");
 
   /**
    * 12.11.1 New: It is a static warning if <i>T</i> is not a class accessible in the current scope,
@@ -2600,7 +2615,7 @@
    *
    * @param name the name of the non-type element
    */
-  static final StaticWarningCode NEW_WITH_NON_TYPE = new StaticWarningCode.con1('NEW_WITH_NON_TYPE', 48, "The name '%s' is not a class");
+  static final StaticWarningCode NEW_WITH_NON_TYPE = new StaticWarningCode.con1('NEW_WITH_NON_TYPE', 45, "The name '%s' is not a class");
 
   /**
    * 12.11.1 New: If <i>T</i> is a class or parameterized type accessible in the current scope then:
@@ -2611,7 +2626,7 @@
    * a<sub>n+1</sub>, &hellip; x<sub>n+k</sub>: a<sub>n+kM/sub>)</i> it is a static warning if the
    * type <i>T</i> does not declare a constructor with the same name as the declaration of <i>T</i>.
    */
-  static final StaticWarningCode NEW_WITH_UNDEFINED_CONSTRUCTOR = new StaticWarningCode.con1('NEW_WITH_UNDEFINED_CONSTRUCTOR', 49, "The class '%s' does not have a constructor '%s'");
+  static final StaticWarningCode NEW_WITH_UNDEFINED_CONSTRUCTOR = new StaticWarningCode.con1('NEW_WITH_UNDEFINED_CONSTRUCTOR', 46, "The class '%s' does not have a constructor '%s'");
 
   /**
    * 12.11.1 New: If <i>T</i> is a class or parameterized type accessible in the current scope then:
@@ -2622,7 +2637,7 @@
    * a<sub>n+1</sub>, &hellip; x<sub>n+k</sub>: a<sub>n+kM/sub>)</i> it is a static warning if the
    * type <i>T</i> does not declare a constructor with the same name as the declaration of <i>T</i>.
    */
-  static final StaticWarningCode NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT = new StaticWarningCode.con1('NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT', 50, "The class '%s' does not have a default constructor");
+  static final StaticWarningCode NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT = new StaticWarningCode.con1('NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT', 47, "The class '%s' does not have a default constructor");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an
@@ -2642,7 +2657,7 @@
    * @param memberName the name of the fourth member
    * @param additionalCount the number of additional missing members that aren't listed
    */
-  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS', 51, "Missing inherited members: '%s', '%s', '%s', '%s' and %d more");
+  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS', 48, "Missing inherited members: '%s', '%s', '%s', '%s' and %d more");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an
@@ -2661,7 +2676,7 @@
    * @param memberName the name of the third member
    * @param memberName the name of the fourth member
    */
-  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR', 52, "Missing inherited members: '%s', '%s', '%s' and '%s'");
+  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR', 49, "Missing inherited members: '%s', '%s', '%s' and '%s'");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an
@@ -2677,7 +2692,7 @@
    *
    * @param memberName the name of the member
    */
-  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE', 53, "Missing inherited member '%s'");
+  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE', 50, "Missing inherited member '%s'");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an
@@ -2695,7 +2710,7 @@
    * @param memberName the name of the second member
    * @param memberName the name of the third member
    */
-  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE', 54, "Missing inherited members: '%s', '%s' and '%s'");
+  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE', 51, "Missing inherited members: '%s', '%s' and '%s'");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract class inherits an
@@ -2712,7 +2727,7 @@
    * @param memberName the name of the first member
    * @param memberName the name of the second member
    */
-  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO', 55, "Missing inherited members: '%s' and '%s'");
+  static final StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO = new StaticWarningCode.con1('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO', 52, "Missing inherited members: '%s' and '%s'");
 
   /**
    * 13.11 Try: An on-catch clause of the form <i>on T catch (p<sub>1</sub>, p<sub>2</sub>) s</i> or
@@ -2722,18 +2737,18 @@
    *
    * @param name the name of the non-type element
    */
-  static final StaticWarningCode NON_TYPE_IN_CATCH_CLAUSE = new StaticWarningCode.con1('NON_TYPE_IN_CATCH_CLAUSE', 56, "The name '%s' is not a type and cannot be used in an on-catch clause");
+  static final StaticWarningCode NON_TYPE_IN_CATCH_CLAUSE = new StaticWarningCode.con1('NON_TYPE_IN_CATCH_CLAUSE', 53, "The name '%s' is not a type and cannot be used in an on-catch clause");
 
   /**
    * 7.1.1 Operators: It is a static warning if the return type of the user-declared operator []= is
    * explicitly declared and not void.
    */
-  static final StaticWarningCode NON_VOID_RETURN_FOR_OPERATOR = new StaticWarningCode.con1('NON_VOID_RETURN_FOR_OPERATOR', 57, "The return type of the operator []= must be 'void'");
+  static final StaticWarningCode NON_VOID_RETURN_FOR_OPERATOR = new StaticWarningCode.con1('NON_VOID_RETURN_FOR_OPERATOR', 54, "The return type of the operator []= must be 'void'");
 
   /**
    * 7.3 Setters: It is a static warning if a setter declares a return type other than void.
    */
-  static final StaticWarningCode NON_VOID_RETURN_FOR_SETTER = new StaticWarningCode.con1('NON_VOID_RETURN_FOR_SETTER', 58, "The return type of the setter must be 'void'");
+  static final StaticWarningCode NON_VOID_RETURN_FOR_SETTER = new StaticWarningCode.con1('NON_VOID_RETURN_FOR_SETTER', 55, "The return type of the setter must be 'void'");
 
   /**
    * 15.1 Static Types: A type <i>T</i> is malformed iff: * <i>T</i> has the form <i>id</i> or the
@@ -2747,7 +2762,7 @@
    *
    * @param nonTypeName the name that is not a type
    */
-  static final StaticWarningCode NOT_A_TYPE = new StaticWarningCode.con1('NOT_A_TYPE', 59, "%s is not a type");
+  static final StaticWarningCode NOT_A_TYPE = new StaticWarningCode.con1('NOT_A_TYPE', 56, "%s is not a type");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt; h</i> or if <i>m &gt;
@@ -2757,7 +2772,7 @@
    * @param argumentCount the actual number of positional arguments given
    * @see #EXTRA_POSITIONAL_ARGUMENTS
    */
-  static final StaticWarningCode NOT_ENOUGH_REQUIRED_ARGUMENTS = new StaticWarningCode.con1('NOT_ENOUGH_REQUIRED_ARGUMENTS', 60, "%d required argument(s) expected, but %d found");
+  static final StaticWarningCode NOT_ENOUGH_REQUIRED_ARGUMENTS = new StaticWarningCode.con1('NOT_ENOUGH_REQUIRED_ARGUMENTS', 57, "%d required argument(s) expected, but %d found");
 
   /**
    * 14.3 Parts: It is a static warning if the referenced part declaration <i>p</i> names a library
@@ -2766,7 +2781,7 @@
    * @param expectedLibraryName the name of expected library name
    * @param actualLibraryName the non-matching actual library name from the "part of" declaration
    */
-  static final StaticWarningCode PART_OF_DIFFERENT_LIBRARY = new StaticWarningCode.con1('PART_OF_DIFFERENT_LIBRARY', 61, "Expected this library to be part of '%s', not '%s'");
+  static final StaticWarningCode PART_OF_DIFFERENT_LIBRARY = new StaticWarningCode.con1('PART_OF_DIFFERENT_LIBRARY', 58, "Expected this library to be part of '%s', not '%s'");
 
   /**
    * 7.6.2 Factories: It is a static warning if the function type of <i>k'</i> is not a subtype of
@@ -2775,7 +2790,7 @@
    * @param redirectedName the name of the redirected constructor
    * @param redirectingName the name of the redirecting constructor
    */
-  static final StaticWarningCode REDIRECT_TO_INVALID_FUNCTION_TYPE = new StaticWarningCode.con1('REDIRECT_TO_INVALID_FUNCTION_TYPE', 62, "The redirected constructor '%s' has incompatible parameters with '%s'");
+  static final StaticWarningCode REDIRECT_TO_INVALID_FUNCTION_TYPE = new StaticWarningCode.con1('REDIRECT_TO_INVALID_FUNCTION_TYPE', 59, "The redirected constructor '%s' has incompatible parameters with '%s'");
 
   /**
    * 7.6.2 Factories: It is a static warning if the function type of <i>k'</i> is not a subtype of
@@ -2784,21 +2799,21 @@
    * @param redirectedName the name of the redirected constructor return type
    * @param redirectingName the name of the redirecting constructor return type
    */
-  static final StaticWarningCode REDIRECT_TO_INVALID_RETURN_TYPE = new StaticWarningCode.con1('REDIRECT_TO_INVALID_RETURN_TYPE', 63, "The return type '%s' of the redirected constructor is not assignable to '%s'");
+  static final StaticWarningCode REDIRECT_TO_INVALID_RETURN_TYPE = new StaticWarningCode.con1('REDIRECT_TO_INVALID_RETURN_TYPE', 60, "The return type '%s' of the redirected constructor is not assignable to '%s'");
 
   /**
    * 7.6.2 Factories: It is a static warning if type does not denote a class accessible in the
    * current scope; if type does denote such a class <i>C</i> it is a static warning if the
    * referenced constructor (be it <i>type</i> or <i>type.id</i>) is not a constructor of <i>C</i>.
    */
-  static final StaticWarningCode REDIRECT_TO_MISSING_CONSTRUCTOR = new StaticWarningCode.con1('REDIRECT_TO_MISSING_CONSTRUCTOR', 64, "The constructor '%s' could not be found in '%s'");
+  static final StaticWarningCode REDIRECT_TO_MISSING_CONSTRUCTOR = new StaticWarningCode.con1('REDIRECT_TO_MISSING_CONSTRUCTOR', 61, "The constructor '%s' could not be found in '%s'");
 
   /**
    * 7.6.2 Factories: It is a static warning if type does not denote a class accessible in the
    * current scope; if type does denote such a class <i>C</i> it is a static warning if the
    * referenced constructor (be it <i>type</i> or <i>type.id</i>) is not a constructor of <i>C</i>.
    */
-  static final StaticWarningCode REDIRECT_TO_NON_CLASS = new StaticWarningCode.con1('REDIRECT_TO_NON_CLASS', 65, "The name '%s' is not a type and cannot be used in a redirected constructor");
+  static final StaticWarningCode REDIRECT_TO_NON_CLASS = new StaticWarningCode.con1('REDIRECT_TO_NON_CLASS', 62, "The name '%s' is not a type and cannot be used in a redirected constructor");
 
   /**
    * 13.11 Return: Let <i>f</i> be the function immediately enclosing a return statement of the form
@@ -2808,7 +2823,7 @@
    * * The return type of <i>f</i> may not be assigned to void.
    * </ol>
    */
-  static final StaticWarningCode RETURN_WITHOUT_VALUE = new StaticWarningCode.con1('RETURN_WITHOUT_VALUE', 66, "Missing return value after 'return'");
+  static final StaticWarningCode RETURN_WITHOUT_VALUE = new StaticWarningCode.con1('RETURN_WITHOUT_VALUE', 63, "Missing return value after 'return'");
 
   /**
    * 12.15.3 Static Invocation: It is a static warning if <i>C</i> does not declare a static method
@@ -2816,19 +2831,19 @@
    *
    * @param memberName the name of the instance member
    */
-  static final StaticWarningCode STATIC_ACCESS_TO_INSTANCE_MEMBER = new StaticWarningCode.con1('STATIC_ACCESS_TO_INSTANCE_MEMBER', 67, "Instance member '%s' cannot be accessed using static access");
+  static final StaticWarningCode STATIC_ACCESS_TO_INSTANCE_MEMBER = new StaticWarningCode.con1('STATIC_ACCESS_TO_INSTANCE_MEMBER', 64, "Instance member '%s' cannot be accessed using static access");
 
   /**
    * 13.9 Switch: It is a static warning if the type of <i>e</i> may not be assigned to the type of
    * <i>e<sub>k</sub></i>.
    */
-  static final StaticWarningCode SWITCH_EXPRESSION_NOT_ASSIGNABLE = new StaticWarningCode.con1('SWITCH_EXPRESSION_NOT_ASSIGNABLE', 68, "Type '%s' of the switch expression is not assignable to the type '%s' of case expressions");
+  static final StaticWarningCode SWITCH_EXPRESSION_NOT_ASSIGNABLE = new StaticWarningCode.con1('SWITCH_EXPRESSION_NOT_ASSIGNABLE', 65, "Type '%s' of the switch expression is not assignable to the type '%s' of case expressions");
 
   /**
    * 12.31 Type Test: It is a static warning if <i>T</i> does not denote a type available in the
    * current lexical scope.
    */
-  static final StaticWarningCode TYPE_TEST_NON_TYPE = new StaticWarningCode.con1('TYPE_TEST_NON_TYPE', 69, "The name '%s' is not a type and cannot be used in an 'is' expression");
+  static final StaticWarningCode TYPE_TEST_NON_TYPE = new StaticWarningCode.con1('TYPE_TEST_NON_TYPE', 66, "The name '%s' is not a type and cannot be used in an 'is' expression");
 
   /**
    * 10 Generics: However, a type parameter is considered to be a malformed type when referenced by
@@ -2837,7 +2852,7 @@
    * 15.1 Static Types: Any use of a malformed type gives rise to a static warning. A malformed type
    * is then interpreted as dynamic by the static type checker and the runtime.
    */
-  static final StaticWarningCode TYPE_PARAMETER_REFERENCED_BY_STATIC = new StaticWarningCode.con1('TYPE_PARAMETER_REFERENCED_BY_STATIC', 70, "Static members cannot reference type parameters");
+  static final StaticWarningCode TYPE_PARAMETER_REFERENCED_BY_STATIC = new StaticWarningCode.con1('TYPE_PARAMETER_REFERENCED_BY_STATIC', 67, "Static members cannot reference type parameters");
 
   /**
    * 12.15.3 Static Invocation: A static method invocation <i>i</i> has the form
@@ -2847,12 +2862,12 @@
    *
    * @param undefinedClassName the name of the undefined class
    */
-  static final StaticWarningCode UNDEFINED_CLASS = new StaticWarningCode.con1('UNDEFINED_CLASS', 71, "Undefined class '%s'");
+  static final StaticWarningCode UNDEFINED_CLASS = new StaticWarningCode.con1('UNDEFINED_CLASS', 68, "Undefined class '%s'");
 
   /**
    * Same as [UNDEFINED_CLASS], but to catch using "boolean" instead of "bool".
    */
-  static final StaticWarningCode UNDEFINED_CLASS_BOOLEAN = new StaticWarningCode.con1('UNDEFINED_CLASS_BOOLEAN', 72, "Undefined class 'boolean'; did you mean 'bool'?");
+  static final StaticWarningCode UNDEFINED_CLASS_BOOLEAN = new StaticWarningCode.con1('UNDEFINED_CLASS_BOOLEAN', 69, "Undefined class 'boolean'; did you mean 'bool'?");
 
   /**
    * 12.17 Getter Invocation: It is a static warning if there is no class <i>C</i> in the enclosing
@@ -2862,7 +2877,7 @@
    * @param getterName the name of the getter
    * @param enclosingType the name of the enclosing type where the getter is being looked for
    */
-  static final StaticWarningCode UNDEFINED_GETTER = new StaticWarningCode.con1('UNDEFINED_GETTER', 73, "There is no such getter '%s' in '%s'");
+  static final StaticWarningCode UNDEFINED_GETTER = new StaticWarningCode.con1('UNDEFINED_GETTER', 70, "There is no such getter '%s' in '%s'");
 
   /**
    * 12.30 Identifier Reference: It is as static warning if an identifier expression of the form
@@ -2872,7 +2887,7 @@
    *
    * @param name the name of the identifier
    */
-  static final StaticWarningCode UNDEFINED_IDENTIFIER = new StaticWarningCode.con1('UNDEFINED_IDENTIFIER', 74, "Undefined name '%s'");
+  static final StaticWarningCode UNDEFINED_IDENTIFIER = new StaticWarningCode.con1('UNDEFINED_IDENTIFIER', 71, "Undefined name '%s'");
 
   /**
    * 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub></i>, <i>1<=i<=l</i>,
@@ -2881,7 +2896,7 @@
    *
    * @param name the name of the requested named parameter
    */
-  static final StaticWarningCode UNDEFINED_NAMED_PARAMETER = new StaticWarningCode.con1('UNDEFINED_NAMED_PARAMETER', 75, "The named parameter '%s' is not defined");
+  static final StaticWarningCode UNDEFINED_NAMED_PARAMETER = new StaticWarningCode.con1('UNDEFINED_NAMED_PARAMETER', 72, "The named parameter '%s' is not defined");
 
   /**
    * 12.18 Assignment: It is as static warning if an assignment of the form <i>v = e</i> occurs
@@ -2896,7 +2911,7 @@
    * @param setterName the name of the getter
    * @param enclosingType the name of the enclosing type where the setter is being looked for
    */
-  static final StaticWarningCode UNDEFINED_SETTER = new StaticWarningCode.con1('UNDEFINED_SETTER', 76, "There is no such setter '%s' in '%s'");
+  static final StaticWarningCode UNDEFINED_SETTER = new StaticWarningCode.con1('UNDEFINED_SETTER', 73, "There is no such setter '%s' in '%s'");
 
   /**
    * 12.15.3 Static Invocation: It is a static warning if <i>C</i> does not declare a static method
@@ -2905,7 +2920,7 @@
    * @param methodName the name of the method
    * @param enclosingType the name of the enclosing type where the method is being looked for
    */
-  static final StaticWarningCode UNDEFINED_STATIC_METHOD_OR_GETTER = new StaticWarningCode.con1('UNDEFINED_STATIC_METHOD_OR_GETTER', 77, "There is no such static method '%s' in '%s'");
+  static final StaticWarningCode UNDEFINED_STATIC_METHOD_OR_GETTER = new StaticWarningCode.con1('UNDEFINED_STATIC_METHOD_OR_GETTER', 74, "There is no such static method '%s' in '%s'");
   static final List<StaticWarningCode> values = [
       AMBIGUOUS_IMPORT,
       ARGUMENT_TYPE_NOT_ASSIGNABLE,
@@ -2914,11 +2929,6 @@
       ASSIGNMENT_TO_METHOD,
       CASE_BLOCK_NOT_TERMINATED,
       CAST_TO_NON_TYPE,
-      COMMENT_REFERENCE_CONSTRUCTOR_NOT_VISIBLE,
-      COMMENT_REFERENCE_IDENTIFIER_NOT_VISIBLE,
-      COMMENT_REFERENCE_UNDECLARED_CONSTRUCTOR,
-      COMMENT_REFERENCE_UNDECLARED_IDENTIFIER,
-      COMMENT_REFERENCE_URI_NOT_LIBRARY,
       CONCRETE_CLASS_WITH_ABSTRACT_MEMBER,
       CONFLICTING_DART_IMPORT,
       CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER,
@@ -2953,6 +2963,8 @@
       MAP_KEY_TYPE_NOT_ASSIGNABLE,
       MAP_VALUE_TYPE_NOT_ASSIGNABLE,
       MISMATCHED_GETTER_AND_SETTER_TYPES,
+      MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE,
+      MIXED_RETURN_TYPES,
       NEW_WITH_ABSTRACT_CLASS,
       NEW_WITH_INVALID_TYPE_PARAMETERS,
       NEW_WITH_NON_TYPE,
diff --git a/pkg/analyzer_experimental/lib/src/generated/html.dart b/pkg/analyzer/lib/src/generated/html.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/generated/html.dart
rename to pkg/analyzer/lib/src/generated/html.dart
diff --git a/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart b/pkg/analyzer/lib/src/generated/instrumentation.dart
similarity index 98%
rename from pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
rename to pkg/analyzer/lib/src/generated/instrumentation.dart
index 32f7498..278b087 100644
--- a/pkg/analyzer_experimental/lib/src/generated/instrumentation.dart
+++ b/pkg/analyzer/lib/src/generated/instrumentation.dart
@@ -38,13 +38,13 @@
   /**
    * A builder that will silently ignore all data and logging requests.
    */
-  static final InstrumentationBuilder nullBuilder = new InstrumentationBuilder_15();
+  static final InstrumentationBuilder nullBuilder = new InstrumentationBuilder_16();
 
   /**
    * An instrumentation logger that can be used when no other instrumentation logger has been
    * configured. This logger will silently ignore all data and logging requests.
    */
-  static InstrumentationLogger _NULL_LOGGER = new InstrumentationLogger_16();
+  static InstrumentationLogger _NULL_LOGGER = new InstrumentationLogger_17();
 
   /**
    * The current instrumentation logger.
@@ -89,7 +89,7 @@
     _CURRENT_LOGGER = logger == null ? _NULL_LOGGER : logger;
   }
 }
-class InstrumentationBuilder_15 implements InstrumentationBuilder {
+class InstrumentationBuilder_16 implements InstrumentationBuilder {
   InstrumentationBuilder data(String name, bool value) => this;
   InstrumentationBuilder data2(String name, int value) => this;
   InstrumentationBuilder data3(String name, String value) => this;
@@ -105,7 +105,7 @@
   InstrumentationBuilder metric4(String name, List<String> value) => this;
   InstrumentationBuilder record(Exception exception) => this;
 }
-class InstrumentationLogger_16 implements InstrumentationLogger {
+class InstrumentationLogger_17 implements InstrumentationLogger {
   InstrumentationBuilder createBuilder(String name) => Instrumentation.nullBuilder;
 }
 /**
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_core.dart b/pkg/analyzer/lib/src/generated/java_core.dart
similarity index 96%
rename from pkg/analyzer_experimental/lib/src/generated/java_core.dart
rename to pkg/analyzer/lib/src/generated/java_core.dart
index 64ef68a..55b7cd6 100644
--- a/pkg/analyzer_experimental/lib/src/generated/java_core.dart
+++ b/pkg/analyzer/lib/src/generated/java_core.dart
@@ -422,6 +422,16 @@
   return a.toLowerCase() == b.toLowerCase();
 }
 
+bool javaStringRegionMatches(String t, int toffset, String o, int ooffset, int len) {
+  if (toffset < 0) return false;
+  if (ooffset < 0) return false;
+  var tend = toffset + len;
+  var oend = ooffset + len;
+  if (tend > t.length) return false;
+  if (oend > o.length) return false;
+  return t.substring(toffset, tend) == o.substring(ooffset, oend);
+}
+
 bool javaBooleanOr(bool a, bool b) {
   return a || b;
 }
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_engine.dart b/pkg/analyzer/lib/src/generated/java_engine.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/generated/java_engine.dart
rename to pkg/analyzer/lib/src/generated/java_engine.dart
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_engine_io.dart b/pkg/analyzer/lib/src/generated/java_engine_io.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/generated/java_engine_io.dart
rename to pkg/analyzer/lib/src/generated/java_engine_io.dart
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_io.dart b/pkg/analyzer/lib/src/generated/java_io.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/generated/java_io.dart
rename to pkg/analyzer/lib/src/generated/java_io.dart
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_junit.dart b/pkg/analyzer/lib/src/generated/java_junit.dart
similarity index 85%
rename from pkg/analyzer_experimental/lib/src/generated/java_junit.dart
rename to pkg/analyzer/lib/src/generated/java_junit.dart
index 3888427..2c13338 100644
--- a/pkg/analyzer_experimental/lib/src/generated/java_junit.dart
+++ b/pkg/analyzer/lib/src/generated/java_junit.dart
@@ -40,6 +40,9 @@
   static void assertSame(expected, actual) {
     expect(actual, same(expected));
   }
+  static void assertSameMsg(String msg, expected, actual) {
+    expect(actual, sameMsg(msg, expected));
+  }
 }
 
 runJUnitTest(testInstance, Function testFunction) {
@@ -77,6 +80,15 @@
   }
 }
 
+Matcher sameMsg(String msg, expected) => new _IsSameAsWithMessage(msg, expected);
+class _IsSameAsWithMessage extends Matcher {
+  final String msg;
+  final _expected;
+  const _IsSameAsWithMessage(this.msg, this._expected);
+  bool matches(item, Map matchState) => identical(item, _expected);
+  Description describe(Description description) => description.add(msg).addDescriptionOf(_expected);
+}
+
 Matcher isTrueMsg(String msg) => new _IsTrueWithMessage(msg);
 class _IsTrueWithMessage extends Matcher {
   final String msg;
diff --git a/pkg/analyzer_experimental/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
similarity index 99%
rename from pkg/analyzer_experimental/lib/src/generated/parser.dart
rename to pkg/analyzer/lib/src/generated/parser.dart
index 9a92aba..bfd461d 100644
--- a/pkg/analyzer_experimental/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -399,7 +399,7 @@
    *
    * @return the synthetic token that was created
    */
-  Token createSyntheticToken(Keyword keyword) => new KeywordToken_13(keyword, _currentToken.offset);
+  Token createSyntheticToken(Keyword keyword) => new Parser_SyntheticKeywordToken(keyword, _currentToken.offset);
 
   /**
    * Create a synthetic token with the given type.
@@ -1729,9 +1729,9 @@
     }
     try {
       List<bool> errorFound = [false];
-      AnalysisErrorListener listener = new AnalysisErrorListener_14(errorFound);
-      StringScanner scanner = new StringScanner(null, referenceSource, listener);
-      scanner.setSourceStart(1, 1, sourceOffset);
+      AnalysisErrorListener listener = new AnalysisErrorListener_15(errorFound);
+      Scanner scanner = new Scanner(null, new SubSequenceReader(new CharSequence(referenceSource), sourceOffset), listener);
+      scanner.setSourceStart(1, 1);
       Token firstToken = scanner.tokenize();
       if (errorFound[0]) {
         return null;
@@ -4502,10 +4502,12 @@
         next = skipTypeParameterList(next);
         if (next != null && matches4(next, TokenType.EQ)) {
           TypeAlias typeAlias = parseClassTypeAlias(commentAndMetadata, keyword);
+          reportError9(ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS, keyword, []);
           return typeAlias;
         }
       } else if (matches4(next, TokenType.EQ)) {
         TypeAlias typeAlias = parseClassTypeAlias(commentAndMetadata, keyword);
+        reportError9(ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS, keyword, []);
         return typeAlias;
       }
     }
@@ -5652,13 +5654,24 @@
     }
   }
 }
-class KeywordToken_13 extends KeywordToken {
-  KeywordToken_13(Keyword arg0, int arg1) : super(arg0, arg1);
+/**
+ * Instances of the class `SyntheticKeywordToken` implement a synthetic keyword token.
+ */
+class Parser_SyntheticKeywordToken extends KeywordToken {
+
+  /**
+   * Initialize a newly created token to represent the given keyword.
+   *
+   * @param keyword the keyword being represented by this token
+   * @param offset the offset from the beginning of the file to the first character in the token
+   */
+  Parser_SyntheticKeywordToken(Keyword keyword, int offset) : super(keyword, offset);
+  Token copy() => new Parser_SyntheticKeywordToken(keyword, offset);
   int get length => 0;
 }
-class AnalysisErrorListener_14 implements AnalysisErrorListener {
+class AnalysisErrorListener_15 implements AnalysisErrorListener {
   List<bool> errorFound;
-  AnalysisErrorListener_14(this.errorFound);
+  AnalysisErrorListener_15(this.errorFound);
   void onError(AnalysisError error) {
     errorFound[0] = true;
   }
diff --git a/pkg/analyzer_experimental/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
similarity index 96%
rename from pkg/analyzer_experimental/lib/src/generated/resolver.dart
rename to pkg/analyzer/lib/src/generated/resolver.dart
index 0ff54ab..a0fedd3 100644
--- a/pkg/analyzer_experimental/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -617,15 +617,17 @@
       getter.static = variable.isStatic;
       _currentHolder.addAccessor(getter);
       variable.getter = getter;
-      PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(variable);
-      setter.setter = true;
-      setter.static = variable.isStatic;
-      ParameterElementImpl parameter = new ParameterElementImpl.con2("_${variable.name}", variable.nameOffset);
-      parameter.synthetic = true;
-      parameter.parameterKind = ParameterKind.REQUIRED;
-      setter.parameters = <ParameterElement> [parameter];
-      _currentHolder.addAccessor(setter);
-      variable.setter = setter;
+      if (!isFinal) {
+        PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con2(variable);
+        setter.setter = true;
+        setter.static = variable.isStatic;
+        ParameterElementImpl parameter = new ParameterElementImpl.con2("_${variable.name}", variable.nameOffset);
+        parameter.synthetic = true;
+        parameter.parameterKind = ParameterKind.REQUIRED;
+        setter.parameters = <ParameterElement> [parameter];
+        _currentHolder.addAccessor(setter);
+        variable.setter = setter;
+      }
     }
     return null;
   }
@@ -1176,8 +1178,8 @@
           String contents = node.content;
           int attributeEnd = node.attributeEnd.end;
           LineInfo_Location location = _lineInfo.getLocation(attributeEnd);
-          sc.StringScanner scanner = new sc.StringScanner(htmlSource, contents, errorListener);
-          scanner.setSourceStart(location.lineNumber, location.columnNumber, attributeEnd);
+          sc.Scanner scanner = new sc.Scanner(htmlSource, new sc.SubSequenceReader(new CharSequence(contents), attributeEnd), errorListener);
+          scanner.setSourceStart(location.lineNumber, location.columnNumber);
           sc.Token firstToken = scanner.tokenize();
           List<int> lineStarts = scanner.lineStarts;
           Parser parser = new Parser(htmlSource, errorListener);
@@ -1382,7 +1384,7 @@
       return false;
     }
     String rhsNameStr = typeName.name.name;
-    if ((rhsType.isDynamic && rhsNameStr == sc.Keyword.DYNAMIC.syntax)) {
+    if (rhsType.isDynamic && rhsNameStr == sc.Keyword.DYNAMIC.syntax) {
       if (node.notOperator == null) {
         _errorReporter.reportError2(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node, []);
       } else {
@@ -2963,6 +2965,11 @@
   SubtypeManager _subtypeManager;
 
   /**
+   * The object keeping track of which elements have had their types promoted.
+   */
+  TypePromotionManager _promoteManager;
+
+  /**
    * The name of the method that can be implemented by a class to allow its instances to be invoked
    * as if they were a function.
    */
@@ -2987,6 +2994,7 @@
     _dynamicType = resolver.typeProvider.dynamicType;
     _typeType = resolver.typeProvider.typeType;
     _subtypeManager = new SubtypeManager();
+    _promoteManager = resolver.promoteManager;
   }
   Object visitAssignmentExpression(AssignmentExpression node) {
     sc.Token operator = node.operator;
@@ -3011,7 +3019,7 @@
         }
         if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
           ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_METHOD : HintCode.UNDEFINED_METHOD) as ErrorCode;
-          _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, errorCode, operator, [
+          _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, operator, [
               methodName,
               shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
         }
@@ -3040,7 +3048,7 @@
         }
         if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
           ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
-          _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, errorCode, operator, [
+          _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, operator, [
               methodName,
               shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
         }
@@ -3460,7 +3468,7 @@
     }
     if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
       ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
-      _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, errorCode, node.operator, [
+      _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, node.operator, [
           methodName,
           shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
     }
@@ -3528,7 +3536,7 @@
       }
       if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
         ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
-        _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, errorCode, operator, [
+        _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, operator, [
             methodName,
             shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
       }
@@ -3610,22 +3618,18 @@
     if (enclosingClass == null) {
       return null;
     }
-    ClassElement superclass = getSuperclass(enclosingClass);
-    if (superclass == null) {
+    InterfaceType superType = enclosingClass.supertype;
+    if (superType == null) {
       return null;
     }
     SimpleIdentifier name = node.constructorName;
-    ConstructorElement element;
-    if (name == null) {
-      element = superclass.unnamedConstructor;
-    } else {
-      element = superclass.getNamedConstructor(name.name);
-    }
+    String superName = name != null ? name.name : null;
+    ConstructorElement element = superType.lookUpConstructor(superName, _resolver.definingLibrary);
     if (element == null) {
       if (name != null) {
-        _resolver.reportError5(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, node, [superclass.name, name]);
+        _resolver.reportError5(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, node, [superType.displayName, name]);
       } else {
-        _resolver.reportError5(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node, [superclass.name]);
+        _resolver.reportError5(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node, [superType.displayName]);
       }
       return null;
     } else {
@@ -3773,13 +3777,13 @@
       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, errorCode, node, [
+        _resolver.reportErrorProxyConditionalAnalysisError(shouldReportMissingMember_static ? staticType.element : propagatedType.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, errorCode, offset, length, [
+        _resolver.reportErrorProxyConditionalAnalysisError2(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, offset, length, [
             methodName,
             shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
       }
@@ -3818,7 +3822,7 @@
       return resolveArgumentsToParameters(false, argumentList, element as ExecutableElement);
     } else if (element is VariableElement) {
       VariableElement variable = element as VariableElement;
-      Type2 type = variable.type;
+      Type2 type = _promoteManager.getStaticType(variable);
       if (type is FunctionType) {
         FunctionType functionType = type as FunctionType;
         List<ParameterElement> parameters = functionType.parameters;
@@ -3936,20 +3940,6 @@
   }
 
   /**
-   * Return the element representing the superclass of the given class.
-   *
-   * @param targetClass the class whose superclass is to be returned
-   * @return the element representing the superclass of the given class
-   */
-  ClassElement getSuperclass(ClassElement targetClass) {
-    InterfaceType superType = targetClass.supertype;
-    if (superType == null) {
-      return null;
-    }
-    return superType.element;
-  }
-
-  /**
    * Return `true` if the given type represents an object that could be invoked using the call
    * operator '()'.
    *
@@ -4675,34 +4665,34 @@
       }
     }
     if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
-      Element selectedElement = select(staticElement, propagatedElement);
-      bool isStaticProperty = isStatic(selectedElement);
+      Element staticOrPropagatedEnclosingElt = shouldReportMissingMember_static ? staticType.element : propagatedType.element;
+      bool isStaticProperty = isStatic(staticOrPropagatedEnclosingElt);
       if (propertyName.inSetterContext()) {
         if (isStaticProperty) {
           ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode;
-          _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, propertyName, [
+          _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, errorCode, propertyName, [
               propertyName.name,
-              shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
+              staticOrPropagatedEnclosingElt.displayName]);
         } else {
           ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode;
-          _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, propertyName, [
+          _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, errorCode, propertyName, [
               propertyName.name,
-              shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
+              staticOrPropagatedEnclosingElt.displayName]);
         }
       } else if (propertyName.inGetterContext()) {
         if (isStaticProperty) {
           ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode;
-          _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, propertyName, [
+          _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, errorCode, propertyName, [
               propertyName.name,
-              shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
+              staticOrPropagatedEnclosingElt.displayName]);
         } else {
           ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode;
-          _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, errorCode, propertyName, [
+          _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, errorCode, propertyName, [
               propertyName.name,
-              shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
+              staticOrPropagatedEnclosingElt.displayName]);
         }
       } else {
-        _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, [propertyName.name]);
+        _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnclosingElt, StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, [propertyName.name]);
       }
     }
   }
@@ -6446,8 +6436,10 @@
     TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.start();
     try {
       for (Source source in library.compilationUnitSources) {
+        CompilationUnit ast = library.getAST(source);
+        ast.accept(new VariableResolverVisitor(library, source, _typeProvider));
         ResolverVisitor visitor = new ResolverVisitor.con1(library, source, _typeProvider);
-        library.getAST(source).accept(visitor);
+        ast.accept(visitor);
         for (ProxyConditionalAnalysisError conditionalCode in visitor.proxyConditionalAnalysisErrors) {
           if (conditionalCode.shouldIncludeErrorCode()) {
             visitor.reportError(conditionalCode.analysisError);
@@ -6738,6 +6730,11 @@
   final TypeOverrideManager overrideManager = new TypeOverrideManager();
 
   /**
+   * The object keeping track of which elements have had their types promoted.
+   */
+  final TypePromotionManager promoteManager = new TypePromotionManager();
+
+  /**
    * Proxy conditional error codes.
    */
   final List<ProxyConditionalAnalysisError> proxyConditionalAnalysisErrors = new List<ProxyConditionalAnalysisError>();
@@ -6789,10 +6786,16 @@
       if (rightOperand != null) {
         try {
           overrideManager.enterScope();
+          promoteManager.enterScope();
           propagateTrueState(leftOperand);
+          promoteTypes(leftOperand);
+          clearTypePromotionsIfPotentiallyMutatedIn(leftOperand);
+          clearTypePromotionsIfPotentiallyMutatedIn(rightOperand);
+          clearTypePromotionsIfAccessedInScopeAndProtentiallyMutated(rightOperand);
           rightOperand.accept(this);
         } finally {
           overrideManager.exitScope();
+          promoteManager.exitScope();
         }
       }
     } else if (identical(operatorType, sc.TokenType.BAR_BAR)) {
@@ -6876,10 +6879,15 @@
     if (thenExpression != null) {
       try {
         overrideManager.enterScope();
+        promoteManager.enterScope();
         propagateTrueState(condition);
+        promoteTypes(condition);
+        clearTypePromotionsIfPotentiallyMutatedIn(thenExpression);
+        clearTypePromotionsIfAccessedInScopeAndProtentiallyMutated(thenExpression);
         thenExpression.accept(this);
       } finally {
         overrideManager.exitScope();
+        promoteManager.exitScope();
       }
     }
     Expression elseExpression = node.elseExpression;
@@ -7018,11 +7026,16 @@
     if (thenStatement != null) {
       try {
         overrideManager.enterScope();
+        promoteManager.enterScope();
         propagateTrueState(condition);
+        promoteTypes(condition);
+        clearTypePromotionsIfPotentiallyMutatedIn(thenStatement);
+        clearTypePromotionsIfAccessedInScopeAndProtentiallyMutated(thenStatement);
         visitStatementInScope(thenStatement);
       } finally {
         thenOverrides = overrideManager.captureLocalOverrides();
         overrideManager.exitScope();
+        promoteManager.exitScope();
       }
     }
     Map<Element, Type2> elseOverrides = null;
@@ -7198,6 +7211,32 @@
   }
 
   /**
+   * Return the static element associated with the given expression whose type can be promoted, or
+   * `null` if there is no element whose type can be promoted.
+   *
+   * @param expression the expression with which the element is associated
+   * @return the element associated with the given expression
+   */
+  VariableElement getPromotionStaticElement(Expression expression) {
+    if (expression is! SimpleIdentifier) {
+      return null;
+    }
+    SimpleIdentifier identifier = expression as SimpleIdentifier;
+    Element element = identifier.staticElement;
+    if (element is! VariableElement) {
+      return null;
+    }
+    ElementKind kind = element.kind;
+    if (identical(kind, ElementKind.LOCAL_VARIABLE)) {
+      return element as VariableElement;
+    }
+    if (identical(kind, ElementKind.PARAMETER)) {
+      return element as VariableElement;
+    }
+    return null;
+  }
+
+  /**
    * If it is appropriate to do so, override the current type of the static and propagated elements
    * associated with the given expression with the given type. Generally speaking, it is appropriate
    * if the given type is more specific than the current type.
@@ -7242,6 +7281,32 @@
   }
 
   /**
+   * If it is appropriate to do so, promotes the current type of the static element associated with
+   * the given expression with the given type. Generally speaking, it is appropriate if the given
+   * type is more specific than the current type.
+   *
+   * @param expression the expression used to access the static element whose types might be
+   *          promoted
+   * @param potentialType the potential type of the elements
+   */
+  void promote(Expression expression, Type2 potentialType) {
+    VariableElement element = getPromotionStaticElement(expression);
+    if (element != null) {
+      Type2 type = expression.staticType;
+      if (type == null || type.isDynamic) {
+        return;
+      }
+      if (potentialType == null || potentialType.isDynamic) {
+        return;
+      }
+      if (!potentialType.isMoreSpecificThan(type)) {
+        return;
+      }
+      promoteManager.setType(element, potentialType);
+    }
+  }
+
+  /**
    * Report a conditional analysis error with the given error code and arguments.
    *
    * @param enclosingElement the enclosing element
@@ -7326,6 +7391,37 @@
   }
 
   /**
+   * Checks each promoted variable in the current scope for compliance with the following
+   * specification statement:
+   *
+   * If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i> then the variable
+   * <i>v</i> is not potentially mutated anywhere in the scope of <i>v</i>.
+   */
+  void clearTypePromotionsIfAccessedInScopeAndProtentiallyMutated(ASTNode target) {
+    for (Element element in promoteManager.promotedElements) {
+      if (((element as VariableElementImpl)).isPotentiallyMutated) {
+        if (isVariableAccessedInClosure(element, target)) {
+          promoteManager.setType(element, null);
+        }
+      }
+    }
+  }
+
+  /**
+   * Checks each promoted variable in the current scope for compliance with the following
+   * specification statement:
+   *
+   * <i>v</i> is not potentially mutated in <i>s<sub>1</sub></i> or within a closure.
+   */
+  void clearTypePromotionsIfPotentiallyMutatedIn(ASTNode target) {
+    for (Element element in promoteManager.promotedElements) {
+      if (isVariablePotentiallyMutatedIn(element, target)) {
+        promoteManager.setType(element, null);
+      }
+    }
+  }
+
+  /**
    * Return the best type information available for the given element. If the type of the element
    * has been overridden, then return the overriding type. Otherwise, return the static type.
    *
@@ -7453,6 +7549,58 @@
   }
 
   /**
+   * Return `true` if the given variable is accessed within a closure in the given
+   * [ASTNode] and also mutated somewhere in variable scope. This information is only
+   * available for local variables (including parameters).
+   *
+   * @param variable the variable to check
+   * @param target the [ASTNode] to check within
+   * @return `true` if this variable is potentially mutated somewhere in the given ASTNode
+   */
+  bool isVariableAccessedInClosure(Element variable, ASTNode target) {
+    List<bool> result = [false];
+    target.accept(new RecursiveASTVisitor_7(result, variable));
+    return result[0];
+  }
+
+  /**
+   * Return `true` if the given variable is potentially mutated somewhere in the given
+   * [ASTNode]. This information is only available for local variables (including parameters).
+   *
+   * @param variable the variable to check
+   * @param target the [ASTNode] to check within
+   * @return `true` if this variable is potentially mutated somewhere in the given ASTNode
+   */
+  bool isVariablePotentiallyMutatedIn(Element variable, ASTNode target) {
+    List<bool> result = [false];
+    target.accept(new RecursiveASTVisitor_8(result, variable));
+    return result[0];
+  }
+
+  /**
+   * Promotes type information using given condition.
+   */
+  void promoteTypes(Expression condition) {
+    if (condition is BinaryExpression) {
+      BinaryExpression binary = condition as BinaryExpression;
+      if (identical(binary.operator.type, sc.TokenType.AMPERSAND_AMPERSAND)) {
+        Expression left = binary.leftOperand;
+        Expression right = binary.rightOperand;
+        promoteTypes(left);
+        promoteTypes(right);
+        clearTypePromotionsIfPotentiallyMutatedIn(right);
+      }
+    } else if (condition is IsExpression) {
+      IsExpression is2 = condition as IsExpression;
+      if (is2.notOperator == null) {
+        promote(is2.expression, is2.type.type);
+      }
+    } else if (condition is ParenthesizedExpression) {
+      promoteTypes(((condition as ParenthesizedExpression)).expression);
+    }
+  }
+
+  /**
    * Propagate any type information that results from knowing that the given condition will have
    * been evaluated to 'false'.
    *
@@ -7539,6 +7687,46 @@
   get enclosingClass_J2DAccessor => enclosingClass;
   set enclosingClass_J2DAccessor(__v) => enclosingClass = __v;
 }
+class RecursiveASTVisitor_7 extends RecursiveASTVisitor<Object> {
+  List<bool> result;
+  Element variable;
+  RecursiveASTVisitor_7(this.result, this.variable) : super();
+  bool _inClosure = false;
+  Object visitFunctionExpression(FunctionExpression node) {
+    bool inClosure = this._inClosure;
+    try {
+      this._inClosure = true;
+      return super.visitFunctionExpression(node);
+    } finally {
+      this._inClosure = inClosure;
+    }
+  }
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    if (result[0]) {
+      return null;
+    }
+    if (_inClosure && identical(node.staticElement, variable)) {
+      result[0] = javaBooleanOr(result[0], true);
+    }
+    return null;
+  }
+}
+class RecursiveASTVisitor_8 extends RecursiveASTVisitor<Object> {
+  List<bool> result;
+  Element variable;
+  RecursiveASTVisitor_8(this.result, this.variable) : super();
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    if (result[0]) {
+      return null;
+    }
+    if (identical(node.staticElement, variable)) {
+      if (node.inSetterContext()) {
+        result[0] = javaBooleanOr(result[0], true);
+      }
+    }
+    return null;
+  }
+}
 /**
  * The abstract class `ScopedVisitor` maintains name and label scopes as an AST structure is
  * being visited.
@@ -8106,6 +8294,11 @@
   TypeOverrideManager _overrideManager;
 
   /**
+   * The object keeping track of which elements have had their types promoted.
+   */
+  TypePromotionManager _promoteManager;
+
+  /**
    * A table mapping [ExecutableElement]s to their propagated return types.
    */
   Map<ExecutableElement, Type2> _propagatedReturnTypes = new Map<ExecutableElement, Type2>();
@@ -8126,6 +8319,7 @@
     _typeProvider = resolver.typeProvider;
     _dynamicType = _typeProvider.dynamicType;
     _overrideManager = resolver.overrideManager;
+    _promoteManager = resolver.promoteManager;
   }
 
   /**
@@ -9072,7 +9266,8 @@
     } else if (element is TypeParameterElement) {
       staticType = ((element as TypeParameterElement)).type;
     } else if (element is VariableElement) {
-      staticType = ((element as VariableElement)).type;
+      VariableElement variable = element as VariableElement;
+      staticType = _promoteManager.getStaticType(variable);
     } else if (element is PrefixElement) {
       return null;
     } else {
@@ -9195,7 +9390,7 @@
     }
     if (body is BlockFunctionBody) {
       List<Type2> result = [null];
-      body.accept(new GeneralizingASTVisitor_7(result));
+      body.accept(new GeneralizingASTVisitor_9(result));
       return result[0];
     }
     return null;
@@ -9235,7 +9430,8 @@
         return type.returnType;
       }
     } else if (element is VariableElement) {
-      Type2 variableType = ((element as VariableElement)).type;
+      VariableElement variable = element as VariableElement;
+      Type2 variableType = _promoteManager.getStaticType(variable);
       if (variableType is FunctionType) {
         return ((variableType as FunctionType)).returnType;
       }
@@ -9554,9 +9750,9 @@
   get thisType_J2DAccessor => _thisType;
   set thisType_J2DAccessor(__v) => _thisType = __v;
 }
-class GeneralizingASTVisitor_7 extends GeneralizingASTVisitor<Object> {
+class GeneralizingASTVisitor_9 extends GeneralizingASTVisitor<Object> {
   List<Type2> result;
-  GeneralizingASTVisitor_7(this.result) : super();
+  GeneralizingASTVisitor_9(this.result) : super();
   Object visitExpression(Expression node) => null;
   Object visitReturnStatement(ReturnStatement node) {
     Type2 type;
@@ -9915,6 +10111,139 @@
   }
 }
 /**
+ * Instances of the class `TypePromotionManager` manage the ability to promote types of local
+ * variables and formal parameters from their declared types based on control flow.
+ */
+class TypePromotionManager {
+
+  /**
+   * The current promotion scope, or `null` if no scope has been entered.
+   */
+  TypePromotionManager_TypePromoteScope _currentScope;
+
+  /**
+   * Enter a new promotions scope.
+   */
+  void enterScope() {
+    _currentScope = new TypePromotionManager_TypePromoteScope(_currentScope);
+  }
+
+  /**
+   * Exit the current promotion scope.
+   */
+  void exitScope() {
+    if (_currentScope == null) {
+      throw new IllegalStateException("No scope to exit");
+    }
+    _currentScope = _currentScope._outerScope;
+  }
+
+  /**
+   * Returns the elements with promoted types.
+   */
+  Iterable<Element> get promotedElements => _currentScope.promotedElements;
+
+  /**
+   * Returns static type of the given variable - declared or promoted.
+   *
+   * @return the static type of the given variable - declared or promoted
+   */
+  Type2 getStaticType(VariableElement variable) {
+    Type2 staticType = getType(variable);
+    if (staticType == null) {
+      staticType = variable.type;
+    }
+    return staticType;
+  }
+
+  /**
+   * Return the promoted type of the given element, or `null` if the type of the element has
+   * not been promoted.
+   *
+   * @param element the element whose type might have been promoted
+   * @return the promoted type of the given element
+   */
+  Type2 getType(Element element) {
+    if (_currentScope == null) {
+      return null;
+    }
+    return _currentScope.getType(element);
+  }
+
+  /**
+   * Set the promoted type of the given element to the given type.
+   *
+   * @param element the element whose type might have been promoted
+   * @param type the promoted type of the given element
+   */
+  void setType(Element element, Type2 type) {
+    if (_currentScope == null) {
+      throw new IllegalStateException("Cannot promote without a scope");
+    }
+    _currentScope.setType(element, type);
+  }
+}
+/**
+ * Instances of the class `TypePromoteScope` represent a scope in which the types of
+ * elements can be promoted.
+ */
+class TypePromotionManager_TypePromoteScope {
+
+  /**
+   * The outer scope in which types might be promoter.
+   */
+  TypePromotionManager_TypePromoteScope _outerScope;
+
+  /**
+   * A table mapping elements to the promoted type of that element.
+   */
+  Map<Element, Type2> _promotedTypes = new Map<Element, Type2>();
+
+  /**
+   * Initialize a newly created scope to be an empty child of the given scope.
+   *
+   * @param outerScope the outer scope in which types might be promoted
+   */
+  TypePromotionManager_TypePromoteScope(TypePromotionManager_TypePromoteScope outerScope) {
+    this._outerScope = outerScope;
+  }
+
+  /**
+   * Returns the elements with promoted types.
+   */
+  Iterable<Element> get promotedElements => _promotedTypes.keys.toSet();
+
+  /**
+   * Return the promoted type of the given element, or `null` if the type of the element has
+   * not been promoted.
+   *
+   * @param element the element whose type might have been promoted
+   * @return the promoted type of the given element
+   */
+  Type2 getType(Element element) {
+    Type2 type = _promotedTypes[element];
+    if (type == null && element is PropertyAccessorElement) {
+      type = _promotedTypes[((element as PropertyAccessorElement)).variable];
+    }
+    if (type != null) {
+      return type;
+    } else if (_outerScope != null) {
+      return _outerScope.getType(element);
+    }
+    return null;
+  }
+
+  /**
+   * Set the promoted type of the given element to the given type.
+   *
+   * @param element the element whose type might have been promoted
+   * @param type the promoted type of the given element
+   */
+  void setType(Element element, Type2 type) {
+    _promotedTypes[element] = type;
+  }
+}
+/**
  * The interface `TypeProvider` defines the behavior of objects that provide access to types
  * defined by the language.
  *
@@ -10251,7 +10580,7 @@
       TypeName exceptionTypeName = node.exceptionType;
       Type2 exceptionType;
       if (exceptionTypeName == null) {
-        exceptionType = typeProvider.objectType;
+        exceptionType = typeProvider.dynamicType;
       } else {
         exceptionType = getType3(exceptionTypeName);
       }
@@ -11033,6 +11362,61 @@
   }
 }
 /**
+ * Instances of the class `VariableResolverVisitor` are used to resolve
+ * [SimpleIdentifier]s to local variables and formal parameters.
+ *
+ * @coverage dart.engine.resolver
+ */
+class VariableResolverVisitor extends ScopedVisitor {
+
+  /**
+   * Initialize a newly created visitor to resolve the nodes in a compilation unit.
+   *
+   * @param library the library containing the compilation unit being resolved
+   * @param source the source representing the compilation unit being visited
+   * @param typeProvider the object used to access the types from the core library
+   */
+  VariableResolverVisitor(Library library, Source source, TypeProvider typeProvider) : super.con1(library, source, typeProvider);
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    if (node.staticElement != null) {
+      return null;
+    }
+    ASTNode parent = node.parent;
+    if (parent is PrefixedIdentifier && identical(((parent as PrefixedIdentifier)).identifier, node)) {
+      return null;
+    }
+    if (parent is PropertyAccess && identical(((parent as PropertyAccess)).propertyName, node)) {
+      return null;
+    }
+    if (parent is MethodInvocation && identical(((parent as MethodInvocation)).methodName, node)) {
+      return null;
+    }
+    if (parent is ConstructorName) {
+      return null;
+    }
+    if (parent is Label) {
+      return null;
+    }
+    Element element = nameScope.lookup(node, definingLibrary);
+    if (element is! VariableElement) {
+      return null;
+    }
+    ElementKind kind = element.kind;
+    if (identical(kind, ElementKind.LOCAL_VARIABLE)) {
+      node.staticElement = element;
+      if (node.inSetterContext()) {
+        ((element as LocalVariableElementImpl)).markPotentiallyMutated();
+      }
+    } else if (identical(kind, ElementKind.PARAMETER)) {
+      node.staticElement = element;
+      if (node.inSetterContext()) {
+        ((element as ParameterElementImpl)).markPotentiallyMutated();
+      }
+    }
+    return null;
+  }
+}
+/**
  * Instances of the class `ClassScope` implement the scope defined by a class.
  *
  * @coverage dart.engine.resolver
@@ -11137,7 +11521,7 @@
       return element;
     }
     if (_hiddenNames.contains(name)) {
-      return null;
+      errorListener.onError(new AnalysisError.con2(source, identifier.offset, identifier.length, CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, []));
     }
     return enclosingScope.lookup3(identifier, name, referencingLibrary);
   }
@@ -12240,7 +12624,7 @@
    * @param expression the expression to validate
    */
   void validateInitializerExpression(List<ParameterElement> parameterElements, Expression expression) {
-    EvaluationResultImpl result = expression.accept(new ConstantVisitor_11(this, parameterElements));
+    EvaluationResultImpl result = expression.accept(new ConstantVisitor_13(this, parameterElements));
     reportErrors(result, CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER);
   }
 
@@ -12285,10 +12669,10 @@
     }
   }
 }
-class ConstantVisitor_11 extends ConstantVisitor {
+class ConstantVisitor_13 extends ConstantVisitor {
   final ConstantVerifier ConstantVerifier_this;
   List<ParameterElement> parameterElements;
-  ConstantVisitor_11(this.ConstantVerifier_this, this.parameterElements) : super();
+  ConstantVisitor_13(this.ConstantVerifier_this, this.parameterElements) : super();
   EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) {
     Element element = node.staticElement;
     for (ParameterElement parameterElement in parameterElements) {
@@ -12459,6 +12843,18 @@
   ExecutableElement _enclosingFunction;
 
   /**
+   * The number of return statements found in the method or function that we are currently visiting
+   * that have a return value.
+   */
+  int _returnWithCount = 0;
+
+  /**
+   * The number of return statements found in the method or function that we are currently visiting
+   * that do not have a return value.
+   */
+  int _returnWithoutCount = 0;
+
+  /**
    * This map is initialized when visiting the contents of a class declaration. If the visitor is
    * not in an enclosing class declaration, then the map is set to `null`.
    *
@@ -12550,6 +12946,20 @@
     checkForArgumentTypeNotAssignable2(node.rightOperand);
     return super.visitBinaryExpression(node);
   }
+  Object visitBlockFunctionBody(BlockFunctionBody node) {
+    int previousReturnWithCount = _returnWithCount;
+    int previousReturnWithoutCount = _returnWithoutCount;
+    try {
+      _returnWithCount = 0;
+      _returnWithoutCount = 0;
+      super.visitBlockFunctionBody(node);
+      checkForMixedReturns(node);
+    } finally {
+      _returnWithCount = previousReturnWithCount;
+      _returnWithoutCount = previousReturnWithoutCount;
+    }
+    return null;
+  }
   Object visitCatchClause(CatchClause node) {
     bool previousIsInCatchClause = _isInCatchClause;
     try {
@@ -12576,7 +12986,7 @@
         if (!checkForImplementsDisallowedClass(implementsClause) && !checkForExtendsDisallowedClass(extendsClause)) {
           checkForNonAbstractClassInheritsAbstractMember(node);
           checkForInconsistentMethodInheritance();
-          checkForRecursiveInterfaceInheritance(_enclosingClass, new List<ClassElement>());
+          checkForRecursiveInterfaceInheritance(_enclosingClass);
         }
       }
       ClassElement classElement = node.element;
@@ -12607,7 +13017,7 @@
     ClassElement outerClassElement = _enclosingClass;
     try {
       _enclosingClass = node.element;
-      checkForRecursiveInterfaceInheritance(node.element, new List<ClassElement>());
+      checkForRecursiveInterfaceInheritance(node.element);
       checkForTypeAliasCannotReferenceItself_mixin(node);
     } finally {
       _enclosingClass = outerClassElement;
@@ -12921,6 +13331,11 @@
     return super.visitRethrowExpression(node);
   }
   Object visitReturnStatement(ReturnStatement node) {
+    if (node.expression == null) {
+      _returnWithoutCount++;
+    } else {
+      _returnWithCount++;
+    }
     checkForAllReturnStatementErrorCodes(node);
     return super.visitReturnStatement(node);
   }
@@ -13444,20 +13859,20 @@
    * @see StaticWarningCode#REDIRECT_TO_MISSING_CONSTRUCTOR
    */
   bool checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) {
-    ConstructorName redirectedNode = node.redirectedConstructor;
-    if (redirectedNode == null) {
+    ConstructorName redirectedConstructor = node.redirectedConstructor;
+    if (redirectedConstructor == null) {
       return false;
     }
-    ConstructorElement redirectedElement = redirectedNode.staticElement;
+    ConstructorElement redirectedElement = redirectedConstructor.staticElement;
     if (redirectedElement == null) {
-      TypeName constructorTypeName = redirectedNode.type;
+      TypeName constructorTypeName = redirectedConstructor.type;
       Type2 redirectedType = constructorTypeName.type;
       if (redirectedType != null && redirectedType.element != null && !redirectedType.isDynamic) {
         String constructorStrName = constructorTypeName.name.name;
-        if (redirectedNode.name != null) {
-          constructorStrName += ".${redirectedNode.name.name}";
+        if (redirectedConstructor.name != null) {
+          constructorStrName += ".${redirectedConstructor.name.name}";
         }
-        _errorReporter.reportError2(StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR, redirectedNode, [constructorStrName, redirectedType.displayName]);
+        _errorReporter.reportError2(StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR, redirectedConstructor, [constructorStrName, redirectedType.displayName]);
         return true;
       }
       return false;
@@ -13467,11 +13882,11 @@
     FunctionType constructorType = node.element.type;
     Type2 constructorReturnType = constructorType.returnType;
     if (!redirectedReturnType.isAssignableTo(constructorReturnType)) {
-      _errorReporter.reportError2(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, redirectedNode, [redirectedReturnType, constructorReturnType]);
+      _errorReporter.reportError2(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, redirectedConstructor, [redirectedReturnType, constructorReturnType]);
       return true;
     }
     if (!redirectedType.isSubtypeOf(constructorType)) {
-      _errorReporter.reportError2(StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE, redirectedNode, [redirectedType, constructorType]);
+      _errorReporter.reportError2(StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE, redirectedConstructor, [redirectedType, constructorType]);
       return true;
     }
     return false;
@@ -15125,14 +15540,17 @@
    *
    * @param node the accessor currently being visited
    * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES
+   * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE
    */
   bool checkForMismatchedAccessorTypes(Declaration accessorDeclaration, String accessorTextName) {
     ExecutableElement accessorElement = accessorDeclaration.element as ExecutableElement;
     if (accessorElement is! PropertyAccessorElement) {
       return false;
     }
-    PropertyAccessorElement counterpartAccessor = null;
     PropertyAccessorElement propertyAccessorElement = accessorElement as PropertyAccessorElement;
+    PropertyAccessorElement counterpartAccessor = null;
+    ClassElement enclosingClassForCounterpart = null;
     if (propertyAccessorElement.isGetter) {
       counterpartAccessor = propertyAccessorElement.correspondingSetter;
     } else {
@@ -15142,7 +15560,22 @@
       }
     }
     if (counterpartAccessor == null) {
-      return false;
+      if (_enclosingClass != null) {
+        String lookupIdentifier = propertyAccessorElement.name;
+        if (lookupIdentifier.endsWith("=")) {
+          lookupIdentifier = lookupIdentifier.substring(0, lookupIdentifier.length - 1);
+        } else {
+          lookupIdentifier += "=";
+        }
+        ExecutableElement elementFromInheritance = _inheritanceManager.lookupInheritance(_enclosingClass, lookupIdentifier);
+        if (elementFromInheritance != null && elementFromInheritance is PropertyAccessorElement) {
+          enclosingClassForCounterpart = elementFromInheritance.enclosingElement as ClassElement;
+          counterpartAccessor = elementFromInheritance as PropertyAccessorElement;
+        }
+      }
+      if (counterpartAccessor == null) {
+        return false;
+      }
     }
     Type2 getterType = null;
     Type2 setterType = null;
@@ -15151,14 +15584,37 @@
       setterType = getSetterType(counterpartAccessor);
     } else if (propertyAccessorElement.isSetter) {
       setterType = getSetterType(propertyAccessorElement);
-      counterpartAccessor = propertyAccessorElement.correspondingGetter;
       getterType = getGetterType(counterpartAccessor);
     }
     if (setterType != null && getterType != null && !getterType.isAssignableTo(setterType)) {
-      _errorReporter.reportError2(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, accessorDeclaration, [
-          accessorTextName,
-          setterType.displayName,
-          getterType.displayName]);
+      if (enclosingClassForCounterpart == null) {
+        _errorReporter.reportError2(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, accessorDeclaration, [
+            accessorTextName,
+            setterType.displayName,
+            getterType.displayName]);
+        return true;
+      } else {
+        _errorReporter.reportError2(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, accessorDeclaration, [
+            accessorTextName,
+            setterType.displayName,
+            getterType.displayName,
+            enclosingClassForCounterpart.displayName]);
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the given function body does not contain return statements that both have
+   * and do not have return values.
+   *
+   * @param node the function body being tested
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#MIXED_RETURN_TYPES
+   */
+  bool checkForMixedReturns(BlockFunctionBody node) {
+    if (_returnWithCount > 0 && _returnWithoutCount > 0) {
+      _errorReporter.reportError2(StaticWarningCode.MIXED_RETURN_TYPES, node, []);
       return true;
     }
     return false;
@@ -15333,16 +15789,17 @@
     List<MethodElement> methods = _enclosingClass.methods;
     List<PropertyAccessorElement> accessors = _enclosingClass.accessors;
     Set<String> methodsInEnclosingClass = new Set<String>();
-    Set<String> accessorsInEnclosingClass = new Set<String>();
     for (MethodElement method in methods) {
-      javaSetAdd(methodsInEnclosingClass, method.name);
+      String methodName = method.name;
+      if (methodName == ElementResolver.NO_SUCH_METHOD_METHOD_NAME) {
+        return false;
+      }
+      javaSetAdd(methodsInEnclosingClass, methodName);
     }
+    Set<String> accessorsInEnclosingClass = new Set<String>();
     for (PropertyAccessorElement accessor in accessors) {
       javaSetAdd(accessorsInEnclosingClass, accessor.name);
     }
-    if (methodsInEnclosingClass.contains(ElementResolver.NO_SUCH_METHOD_METHOD_NAME)) {
-      return false;
-    }
     Set<ExecutableElement> missingOverrides = new Set<ExecutableElement>();
     MemberMap membersInheritedFromInterfaces = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass);
     MemberMap membersInheritedFromSuperclasses = _inheritanceManager.getMapOfMembersInheritedFromClasses(_enclosingClass);
@@ -15619,64 +16076,64 @@
    * This checks the class declaration is not a superinterface to itself.
    *
    * @param classElt the class element to test
-   * @param list a list containing the potentially cyclic implements path
    * @return `true` if and only if an error code is generated on the passed element
    * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE
    * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS
    * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS
    */
-  bool checkForRecursiveInterfaceInheritance(ClassElement classElt, List<ClassElement> list) {
+  bool checkForRecursiveInterfaceInheritance(ClassElement classElt) {
     if (classElt == null) {
       return false;
     }
-    InterfaceType supertype = classElt.supertype;
-    list.add(classElt);
-    if (list.length != 1 && _enclosingClass == classElt) {
+    return checkForRecursiveInterfaceInheritance2(classElt, new List<ClassElement>());
+  }
+
+  /**
+   * This checks the class declaration is not a superinterface to itself.
+   *
+   * @param classElt the class element to test
+   * @param path a list containing the potentially cyclic implements path
+   * @return `true` if and only if an error code is generated on the passed element
+   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE
+   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS
+   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS
+   */
+  bool checkForRecursiveInterfaceInheritance2(ClassElement classElt, List<ClassElement> path) {
+    int size = path.length;
+    if (size > 0 && _enclosingClass == classElt) {
       String enclosingClassName = _enclosingClass.displayName;
-      if (list.length > 2) {
+      if (size > 1) {
         String separator = ", ";
-        int listLength = list.length;
         JavaStringBuilder builder = new JavaStringBuilder();
-        for (int i = 0; i < listLength; i++) {
-          builder.append(list[i].displayName);
-          if (i != listLength - 1) {
-            builder.append(separator);
-          }
+        for (int i = 0; i < size; i++) {
+          builder.append(path[i].displayName);
+          builder.append(separator);
         }
+        builder.append(classElt.displayName);
         _errorReporter.reportError3(CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClassName, builder.toString()]);
         return true;
-      } else if (list.length == 2) {
+      } else {
+        InterfaceType supertype = classElt.supertype;
         ErrorCode errorCode = (supertype != null && _enclosingClass == supertype.element ? CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS : CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS) as ErrorCode;
         _errorReporter.reportError3(errorCode, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClassName]);
         return true;
       }
     }
-    for (int i = 1; i < list.length - 1; i++) {
-      if (classElt == list[i]) {
-        list.removeAt(list.length - 1);
-        return false;
-      }
+    if (path.indexOf(classElt) > 0) {
+      return false;
     }
-    List<ClassElement> interfaceElements;
+    path.add(classElt);
+    InterfaceType supertype = classElt.supertype;
+    if (supertype != null && checkForRecursiveInterfaceInheritance2(supertype.element, path)) {
+      return true;
+    }
     List<InterfaceType> interfaceTypes = classElt.interfaces;
-    if (supertype != null && !supertype.isObject) {
-      interfaceElements = new List<ClassElement>(interfaceTypes.length + 1);
-      interfaceElements[0] = supertype.element;
-      for (int i = 0; i < interfaceTypes.length; i++) {
-        interfaceElements[i + 1] = interfaceTypes[i].element;
-      }
-    } else {
-      interfaceElements = new List<ClassElement>(interfaceTypes.length);
-      for (int i = 0; i < interfaceTypes.length; i++) {
-        interfaceElements[i] = interfaceTypes[i].element;
-      }
-    }
-    for (ClassElement classElt2 in interfaceElements) {
-      if (checkForRecursiveInterfaceInheritance(classElt2, list)) {
+    for (InterfaceType interfaceType in interfaceTypes) {
+      if (checkForRecursiveInterfaceInheritance2(interfaceType.element, path)) {
         return true;
       }
     }
-    list.removeAt(list.length - 1);
+    path.removeAt(path.length - 1);
     return false;
   }
 
@@ -15686,18 +16143,28 @@
    *
    * @param node the constructor declaration to evaluate
    * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR
+   * @see CompileTimeErrorCode#FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR
    * @see CompileTimeErrorCode#MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS
    * @see CompileTimeErrorCode#SUPER_IN_REDIRECTING_CONSTRUCTOR
-   * @see CompileTimeErrorCode#FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR
    */
   bool checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) {
-    int numProblems = 0;
+    bool errorReported = false;
+    ConstructorName redirectedConstructor = node.redirectedConstructor;
+    if (redirectedConstructor != null) {
+      for (FormalParameter parameter in node.parameters.parameters) {
+        if (parameter is DefaultFormalParameter && ((parameter as DefaultFormalParameter)).defaultValue != null) {
+          _errorReporter.reportError2(CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR, parameter.identifier, []);
+          errorReported = true;
+        }
+      }
+    }
     int numRedirections = 0;
     for (ConstructorInitializer initializer in node.initializers) {
       if (initializer is RedirectingConstructorInvocation) {
         if (numRedirections > 0) {
           _errorReporter.reportError2(CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS, initializer, []);
-          numProblems++;
+          errorReported = true;
         }
         numRedirections++;
       }
@@ -15706,15 +16173,15 @@
       for (ConstructorInitializer initializer in node.initializers) {
         if (initializer is SuperConstructorInvocation) {
           _errorReporter.reportError2(CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, initializer, []);
-          numProblems++;
+          errorReported = true;
         }
         if (initializer is ConstructorFieldInitializer) {
           _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, initializer, []);
-          numProblems++;
+          errorReported = true;
         }
       }
     }
-    return numProblems != 0;
+    return errorReported;
   }
 
   /**
@@ -16354,7 +16821,7 @@
           break;
         }
       }
-      current.accept(new GeneralizingElementVisitor_12(target, toCheck));
+      current.accept(new GeneralizingElementVisitor_14(target, toCheck));
       javaSetAdd(checked, current);
     }
   }
@@ -16550,10 +17017,10 @@
       INIT_IN_INITIALIZERS];
   INIT_STATE(String name, int ordinal) : super(name, ordinal);
 }
-class GeneralizingElementVisitor_12 extends GeneralizingElementVisitor<Object> {
+class GeneralizingElementVisitor_14 extends GeneralizingElementVisitor<Object> {
   Element target;
   List<Element> toCheck;
-  GeneralizingElementVisitor_12(this.target, this.toCheck) : super();
+  GeneralizingElementVisitor_14(this.target, this.toCheck) : super();
   bool _inClass = false;
   Object visitClassElement(ClassElement element) {
     addTypeToCheck(element.supertype);
@@ -16582,7 +17049,10 @@
     addTypeToCheck(element.type);
     return super.visitParameterElement(element);
   }
-  Object visitTypeParameterElement(TypeParameterElement element) => null;
+  Object visitTypeParameterElement(TypeParameterElement element) {
+    addTypeToCheck(element.bound);
+    return super.visitTypeParameterElement(element);
+  }
   Object visitVariableElement(VariableElement element) {
     addTypeToCheck(element.type);
     return super.visitVariableElement(element);
diff --git a/pkg/analyzer_experimental/lib/src/generated/scanner.dart b/pkg/analyzer/lib/src/generated/scanner.dart
similarity index 79%
rename from pkg/analyzer_experimental/lib/src/generated/scanner.dart
rename to pkg/analyzer/lib/src/generated/scanner.dart
index 81652aa..e60e57a 100644
--- a/pkg/analyzer_experimental/lib/src/generated/scanner.dart
+++ b/pkg/analyzer/lib/src/generated/scanner.dart
@@ -7,6 +7,7 @@
 import 'source.dart';
 import 'error.dart';
 import 'instrumentation.dart';
+import 'utilities_collection.dart' show TokenMap;
 /**
  * Instances of the abstract class `KeywordState` represent a state in a state machine used to
  * scan keywords.
@@ -188,6 +189,34 @@
   ErrorType get type => ErrorType.SYNTACTIC_ERROR;
 }
 /**
+ * Instances of the class `SubSequenceReader` implement a [CharacterReader] that reads
+ * characters from a character sequence, but adds a delta when reporting the current character
+ * offset so that the character sequence can be a subsequence from a larger sequence.
+ */
+class SubSequenceReader extends CharSequenceReader {
+
+  /**
+   * The offset from the beginning of the file to the beginning of the source being scanned.
+   */
+  int _offsetDelta = 0;
+
+  /**
+   * Initialize a newly created reader to read the characters in the given sequence.
+   *
+   * @param sequence the sequence from which characters will be read
+   * @param offsetDelta the offset from the beginning of the file to the beginning of the source
+   *          being scanned
+   */
+  SubSequenceReader(CharSequence sequence, int offsetDelta) : super(sequence) {
+    this._offsetDelta = offsetDelta;
+  }
+  int get offset => _offsetDelta + super.offset;
+  String getString(int start, int endDelta) => super.getString(start - _offsetDelta, endDelta);
+  void set offset(int offset) {
+    super.offset = offset - _offsetDelta;
+  }
+}
+/**
  * Instances of the class `TokenWithComment` represent a string token that is preceded by
  * comments.
  *
@@ -211,7 +240,16 @@
   StringTokenWithComment(TokenType type, String value, int offset, Token precedingComment) : super(type, value, offset) {
     this._precedingComment = precedingComment;
   }
+  Token copy() => new StringTokenWithComment(type, lexeme, offset, copyComments(_precedingComment));
   Token get precedingComments => _precedingComment;
+  void applyDelta(int delta) {
+    super.applyDelta(delta);
+    Token token = _precedingComment;
+    while (token != null) {
+      token.applyDelta(delta);
+      token = token.next;
+    }
+  }
 }
 /**
  * The enumeration `Keyword` defines the keywords in the Dart programming language.
@@ -367,8 +405,133 @@
   }
 }
 /**
- * The abstract class `AbstractScanner` implements a scanner for Dart code. Subclasses are
- * required to implement the interface used to access the characters being scanned.
+ * Instances of the class `CharSequenceReader` implement a [CharacterReader] that reads
+ * characters from a character sequence.
+ */
+class CharSequenceReader implements CharacterReader {
+
+  /**
+   * The sequence from which characters will be read.
+   */
+  CharSequence _sequence;
+
+  /**
+   * The number of characters in the string.
+   */
+  int _stringLength = 0;
+
+  /**
+   * The index, relative to the string, of the last character that was read.
+   */
+  int _charOffset = 0;
+
+  /**
+   * Initialize a newly created reader to read the characters in the given sequence.
+   *
+   * @param sequence the sequence from which characters will be read
+   */
+  CharSequenceReader(CharSequence sequence) {
+    this._sequence = sequence;
+    this._stringLength = sequence.length();
+    this._charOffset = -1;
+  }
+  int advance() {
+    if (_charOffset + 1 >= _stringLength) {
+      return -1;
+    }
+    return _sequence.charAt(++_charOffset);
+  }
+  int get offset => _charOffset;
+  String getString(int start, int endDelta) => _sequence.subSequence(start, _charOffset + 1 + endDelta).toString();
+  int peek() {
+    if (_charOffset + 1 >= _sequence.length()) {
+      return -1;
+    }
+    return _sequence.charAt(_charOffset + 1);
+  }
+  void set offset(int offset) {
+    _charOffset = offset;
+  }
+}
+/**
+ * Instances of the class `IncrementalScanner` implement a scanner that scans a subset of a
+ * string and inserts the resulting tokens into the middle of an existing token stream.
+ *
+ * @coverage dart.engine.parser
+ */
+class IncrementalScanner extends Scanner {
+
+  /**
+   * The reader used to access the characters in the source.
+   */
+  CharacterReader _reader;
+
+  /**
+   * A map from tokens that were copied to the copies of the tokens.
+   */
+  TokenMap _tokenMap = new TokenMap();
+
+  /**
+   * Initialize a newly created scanner.
+   *
+   * @param source the source being scanned
+   * @param reader the character reader used to read the characters in the source
+   * @param errorListener the error listener that will be informed of any errors that are found
+   */
+  IncrementalScanner(Source source, CharacterReader reader, AnalysisErrorListener errorListener) : super(source, reader, errorListener) {
+    this._reader = reader;
+  }
+
+  /**
+   * Given the stream of tokens scanned from the original source, the modified source (the result of
+   * replacing one contiguous range of characters with another string of characters), and a
+   * specification of the modification that was made, return a stream of tokens scanned from the
+   * modified source. The original stream of tokens will not be modified.
+   *
+   * @param originalStream the stream of tokens scanned from the original source
+   * @param index the index of the first character in both the original and modified source that was
+   *          affected by the modification
+   * @param removedLength the number of characters removed from the original source
+   * @param insertedLength the number of characters added to the modified source
+   */
+  Token rescan(Token originalStream, int index, int removedLength, int insertedLength) {
+    while (originalStream.end < index) {
+      originalStream = copyAndAdvance(originalStream, 0);
+    }
+    int modifiedEnd = index + insertedLength - 1;
+    _reader.offset = Math.min(originalStream.offset, index) - 1;
+    int next = _reader.advance();
+    while (next != -1 && _reader.offset <= modifiedEnd) {
+      next = bigSwitch(next);
+    }
+    int removedEnd = index + removedLength - 1;
+    while (originalStream.offset <= removedEnd) {
+      originalStream = originalStream.next;
+    }
+    int delta = insertedLength - removedLength;
+    while (originalStream.type != TokenType.EOF) {
+      originalStream = copyAndAdvance(originalStream, delta);
+    }
+    copyAndAdvance(originalStream, delta);
+    return firstToken();
+  }
+  Token copyAndAdvance(Token originalToken, int delta) {
+    Token copiedToken = originalToken.copy();
+    _tokenMap.put(originalToken, copiedToken);
+    copiedToken.applyDelta(delta);
+    appendToken(copiedToken);
+    Token originalComment = originalToken.precedingComments;
+    Token copiedComment = originalToken.precedingComments;
+    while (originalComment != null) {
+      _tokenMap.put(originalComment, copiedComment);
+      originalComment = originalComment.next;
+      copiedComment = copiedComment.next;
+    }
+    return originalToken.next;
+  }
+}
+/**
+ * The class `Scanner` implements a scanner for Dart code.
  *
  * The lexical structure of Dart is ambiguous without knowledge of the context in which a token is
  * being scanned. For example, without context we cannot determine whether source of the form "<<"
@@ -378,7 +541,7 @@
  *
  * @coverage dart.engine.parser
  */
-abstract class AbstractScanner {
+class Scanner {
 
   /**
    * The source being scanned.
@@ -386,6 +549,11 @@
   Source source;
 
   /**
+   * The reader used to access the characters in the source.
+   */
+  CharacterReader _reader;
+
+  /**
    * The error listener that will be informed of any errors that are found during the scan.
    */
   AnalysisErrorListener _errorListener;
@@ -440,10 +608,12 @@
    * Initialize a newly created scanner.
    *
    * @param source the source being scanned
+   * @param reader the character reader used to read the characters in the source
    * @param errorListener the error listener that will be informed of any errors that are found
    */
-  AbstractScanner(Source source, AnalysisErrorListener errorListener) {
+  Scanner(Source source, CharacterReader reader, AnalysisErrorListener errorListener) {
     this.source = source;
+    this._reader = reader;
     this._errorListener = errorListener;
     _tokens = new Token(TokenType.EOF, -1);
     _tokens.setNext(_tokens);
@@ -460,15 +630,6 @@
   List<int> get lineStarts => _lineStarts;
 
   /**
-   * Return the current offset relative to the beginning of the file. Return the initial offset if
-   * the scanner has not yet scanned the source code, and one (1) past the end of the source code if
-   * the source code has been scanned.
-   *
-   * @return the current offset of the scanner in the source
-   */
-  int get offset;
-
-  /**
    * Return `true` if any unmatched groups were found during the parse.
    *
    * @return `true` if any unmatched groups were found during the parse
@@ -476,6 +637,28 @@
   bool hasUnmatchedGroups() => _hasUnmatchedGroups2;
 
   /**
+   * Record that the source begins on the given line and column at the current offset as given by
+   * the reader. The line starts for lines before the given line will not be correct.
+   *
+   * This method must be invoked at most one time and must be invoked before scanning begins. The
+   * values provided must be sensible. The results are undefined if these conditions are violated.
+   *
+   * @param line the one-based index of the line containing the first character of the source
+   * @param column the one-based index of the column in which the first character of the source
+   *          occurs
+   */
+  void setSourceStart(int line, int column) {
+    int offset = _reader.offset;
+    if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) {
+      return;
+    }
+    for (int i = 2; i < line; i++) {
+      _lineStarts.add(1);
+    }
+    _lineStarts.add(offset - column + 1);
+  }
+
+  /**
    * Scan the source code to produce a list of tokens representing the source.
    *
    * @return the first token in the list of tokens that were produced
@@ -484,7 +667,7 @@
     InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engine.AbstractScanner.tokenize");
     int tokenCounter = 0;
     try {
-      int next = advance();
+      int next = _reader.advance();
       while (next != -1) {
         tokenCounter++;
         next = bigSwitch(next);
@@ -498,36 +681,168 @@
   }
 
   /**
-   * Advance the current position and return the character at the new current position.
+   * Append the given token to the end of the token stream being scanned. This method is intended to
+   * be used by subclasses that copy existing tokens and should not normally be used because it will
+   * fail to correctly associate any comments with the token being passed in.
    *
-   * @return the character at the new current position
+   * @param token the token to be appended
    */
-  int advance();
+  void appendToken(Token token) {
+    _tail = _tail.setNext(token);
+  }
+  int bigSwitch(int next) {
+    beginToken();
+    if (next == 0xD) {
+      next = _reader.advance();
+      if (next == 0xA) {
+        next = _reader.advance();
+      }
+      recordStartOfLine();
+      return next;
+    } else if (next == 0xA) {
+      next = _reader.advance();
+      recordStartOfLine();
+      return next;
+    } else if (next == 0x9 || next == 0x20) {
+      return _reader.advance();
+    }
+    if (next == 0x72) {
+      int peek = _reader.peek();
+      if (peek == 0x22 || peek == 0x27) {
+        int start = _reader.offset;
+        return tokenizeString(_reader.advance(), start, true);
+      }
+    }
+    if (0x61 <= next && next <= 0x7A) {
+      return tokenizeKeywordOrIdentifier(next, true);
+    }
+    if ((0x41 <= next && next <= 0x5A) || next == 0x5F || next == 0x24) {
+      return tokenizeIdentifier(next, _reader.offset, true);
+    }
+    if (next == 0x3C) {
+      return tokenizeLessThan(next);
+    }
+    if (next == 0x3E) {
+      return tokenizeGreaterThan(next);
+    }
+    if (next == 0x3D) {
+      return tokenizeEquals(next);
+    }
+    if (next == 0x21) {
+      return tokenizeExclamation(next);
+    }
+    if (next == 0x2B) {
+      return tokenizePlus(next);
+    }
+    if (next == 0x2D) {
+      return tokenizeMinus(next);
+    }
+    if (next == 0x2A) {
+      return tokenizeMultiply(next);
+    }
+    if (next == 0x25) {
+      return tokenizePercent(next);
+    }
+    if (next == 0x26) {
+      return tokenizeAmpersand(next);
+    }
+    if (next == 0x7C) {
+      return tokenizeBar(next);
+    }
+    if (next == 0x5E) {
+      return tokenizeCaret(next);
+    }
+    if (next == 0x5B) {
+      return tokenizeOpenSquareBracket(next);
+    }
+    if (next == 0x7E) {
+      return tokenizeTilde(next);
+    }
+    if (next == 0x5C) {
+      appendToken2(TokenType.BACKSLASH);
+      return _reader.advance();
+    }
+    if (next == 0x23) {
+      return tokenizeTag(next);
+    }
+    if (next == 0x28) {
+      appendBeginToken(TokenType.OPEN_PAREN);
+      return _reader.advance();
+    }
+    if (next == 0x29) {
+      appendEndToken(TokenType.CLOSE_PAREN, TokenType.OPEN_PAREN);
+      return _reader.advance();
+    }
+    if (next == 0x2C) {
+      appendToken2(TokenType.COMMA);
+      return _reader.advance();
+    }
+    if (next == 0x3A) {
+      appendToken2(TokenType.COLON);
+      return _reader.advance();
+    }
+    if (next == 0x3B) {
+      appendToken2(TokenType.SEMICOLON);
+      return _reader.advance();
+    }
+    if (next == 0x3F) {
+      appendToken2(TokenType.QUESTION);
+      return _reader.advance();
+    }
+    if (next == 0x5D) {
+      appendEndToken(TokenType.CLOSE_SQUARE_BRACKET, TokenType.OPEN_SQUARE_BRACKET);
+      return _reader.advance();
+    }
+    if (next == 0x60) {
+      appendToken2(TokenType.BACKPING);
+      return _reader.advance();
+    }
+    if (next == 0x7B) {
+      appendBeginToken(TokenType.OPEN_CURLY_BRACKET);
+      return _reader.advance();
+    }
+    if (next == 0x7D) {
+      appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
+      return _reader.advance();
+    }
+    if (next == 0x2F) {
+      return tokenizeSlashOrComment(next);
+    }
+    if (next == 0x40) {
+      appendToken2(TokenType.AT);
+      return _reader.advance();
+    }
+    if (next == 0x22 || next == 0x27) {
+      return tokenizeString(next, _reader.offset, false);
+    }
+    if (next == 0x2E) {
+      return tokenizeDotOrNumber(next);
+    }
+    if (next == 0x30) {
+      return tokenizeHexOrNumber(next);
+    }
+    if (0x31 <= next && next <= 0x39) {
+      return tokenizeNumber(next);
+    }
+    if (next == -1) {
+      return -1;
+    }
+    reportError(ScannerErrorCode.ILLEGAL_CHARACTER, [next]);
+    return _reader.advance();
+  }
 
   /**
-   * Return the substring of the source code between the start offset and the modified current
-   * position. The current position is modified by adding the end delta.
+   * Return the first token in the token stream that was scanned.
    *
-   * @param start the offset to the beginning of the string, relative to the start of the file
-   * @param endDelta the number of character after the current location to be included in the
-   *          string, or the number of characters before the current location to be excluded if the
-   *          offset is negative
-   * @return the specified substring of the source code
+   * @return the first token in the token stream that was scanned
    */
-  String getString(int start, int endDelta);
-
-  /**
-   * Return the character at the current position without changing the current position.
-   *
-   * @return the character at the current position
-   */
-  int peek();
+  Token firstToken() => _tokens.next;
 
   /**
    * Record the fact that we are at the beginning of a new line in the source.
    */
   void recordStartOfLine() {
-    _lineStarts.add(offset);
+    _lineStarts.add(_reader.offset);
   }
   void appendBeginToken(TokenType type) {
     BeginToken token;
@@ -571,9 +886,9 @@
   void appendEofToken() {
     Token eofToken;
     if (_firstComment == null) {
-      eofToken = new Token(TokenType.EOF, offset + 1);
+      eofToken = new Token(TokenType.EOF, _reader.offset + 1);
     } else {
-      eofToken = new TokenWithComment(TokenType.EOF, offset + 1, _firstComment);
+      eofToken = new TokenWithComment(TokenType.EOF, _reader.offset + 1, _firstComment);
       _firstComment = null;
       _lastComment = null;
     }
@@ -610,7 +925,7 @@
       _lastComment = null;
     }
   }
-  void appendToken(TokenType type) {
+  void appendToken2(TokenType type) {
     if (_firstComment == null) {
       _tail = _tail.setNext(new Token(type, _tokenStart));
     } else {
@@ -619,7 +934,7 @@
       _lastComment = null;
     }
   }
-  void appendToken2(TokenType type, int offset) {
+  void appendToken3(TokenType type, int offset) {
     if (_firstComment == null) {
       _tail = _tail.setNext(new Token(type, offset));
     } else {
@@ -629,147 +944,7 @@
     }
   }
   void beginToken() {
-    _tokenStart = offset;
-  }
-  int bigSwitch(int next) {
-    beginToken();
-    if (next == 0xD) {
-      next = advance();
-      if (next == 0xA) {
-        next = advance();
-      }
-      recordStartOfLine();
-      return next;
-    } else if (next == 0xA) {
-      next = advance();
-      recordStartOfLine();
-      return next;
-    } else if (next == 0x9 || next == 0x20) {
-      return advance();
-    }
-    if (next == 0x72) {
-      int peek = this.peek();
-      if (peek == 0x22 || peek == 0x27) {
-        int start = offset;
-        return tokenizeString(advance(), start, true);
-      }
-    }
-    if (0x61 <= next && next <= 0x7A) {
-      return tokenizeKeywordOrIdentifier(next, true);
-    }
-    if ((0x41 <= next && next <= 0x5A) || next == 0x5F || next == 0x24) {
-      return tokenizeIdentifier(next, offset, true);
-    }
-    if (next == 0x3C) {
-      return tokenizeLessThan(next);
-    }
-    if (next == 0x3E) {
-      return tokenizeGreaterThan(next);
-    }
-    if (next == 0x3D) {
-      return tokenizeEquals(next);
-    }
-    if (next == 0x21) {
-      return tokenizeExclamation(next);
-    }
-    if (next == 0x2B) {
-      return tokenizePlus(next);
-    }
-    if (next == 0x2D) {
-      return tokenizeMinus(next);
-    }
-    if (next == 0x2A) {
-      return tokenizeMultiply(next);
-    }
-    if (next == 0x25) {
-      return tokenizePercent(next);
-    }
-    if (next == 0x26) {
-      return tokenizeAmpersand(next);
-    }
-    if (next == 0x7C) {
-      return tokenizeBar(next);
-    }
-    if (next == 0x5E) {
-      return tokenizeCaret(next);
-    }
-    if (next == 0x5B) {
-      return tokenizeOpenSquareBracket(next);
-    }
-    if (next == 0x7E) {
-      return tokenizeTilde(next);
-    }
-    if (next == 0x5C) {
-      appendToken(TokenType.BACKSLASH);
-      return advance();
-    }
-    if (next == 0x23) {
-      return tokenizeTag(next);
-    }
-    if (next == 0x28) {
-      appendBeginToken(TokenType.OPEN_PAREN);
-      return advance();
-    }
-    if (next == 0x29) {
-      appendEndToken(TokenType.CLOSE_PAREN, TokenType.OPEN_PAREN);
-      return advance();
-    }
-    if (next == 0x2C) {
-      appendToken(TokenType.COMMA);
-      return advance();
-    }
-    if (next == 0x3A) {
-      appendToken(TokenType.COLON);
-      return advance();
-    }
-    if (next == 0x3B) {
-      appendToken(TokenType.SEMICOLON);
-      return advance();
-    }
-    if (next == 0x3F) {
-      appendToken(TokenType.QUESTION);
-      return advance();
-    }
-    if (next == 0x5D) {
-      appendEndToken(TokenType.CLOSE_SQUARE_BRACKET, TokenType.OPEN_SQUARE_BRACKET);
-      return advance();
-    }
-    if (next == 0x60) {
-      appendToken(TokenType.BACKPING);
-      return advance();
-    }
-    if (next == 0x7B) {
-      appendBeginToken(TokenType.OPEN_CURLY_BRACKET);
-      return advance();
-    }
-    if (next == 0x7D) {
-      appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
-      return advance();
-    }
-    if (next == 0x2F) {
-      return tokenizeSlashOrComment(next);
-    }
-    if (next == 0x40) {
-      appendToken(TokenType.AT);
-      return advance();
-    }
-    if (next == 0x22 || next == 0x27) {
-      return tokenizeString(next, offset, false);
-    }
-    if (next == 0x2E) {
-      return tokenizeDotOrNumber(next);
-    }
-    if (next == 0x30) {
-      return tokenizeHexOrNumber(next);
-    }
-    if (0x31 <= next && next <= 0x39) {
-      return tokenizeNumber(next);
-    }
-    if (next == -1) {
-      return -1;
-    }
-    reportError(ScannerErrorCode.ILLEGAL_CHARACTER, [next]);
-    return advance();
+    _tokenStart = _reader.offset;
   }
 
   /**
@@ -790,7 +965,6 @@
     }
     return null;
   }
-  Token firstToken() => _tokens.next;
 
   /**
    * Report an error at the current offset.
@@ -799,91 +973,91 @@
    * @param arguments any arguments needed to complete the error message
    */
   void reportError(ScannerErrorCode errorCode, List<Object> arguments) {
-    _errorListener.onError(new AnalysisError.con2(source, offset, 1, errorCode, arguments));
+    _errorListener.onError(new AnalysisError.con2(source, _reader.offset, 1, errorCode, arguments));
   }
   int select(int choice, TokenType yesType, TokenType noType) {
-    int next = advance();
+    int next = _reader.advance();
     if (next == choice) {
-      appendToken(yesType);
-      return advance();
+      appendToken2(yesType);
+      return _reader.advance();
     } else {
-      appendToken(noType);
+      appendToken2(noType);
       return next;
     }
   }
   int select2(int choice, TokenType yesType, TokenType noType, int offset) {
-    int next = advance();
+    int next = _reader.advance();
     if (next == choice) {
-      appendToken2(yesType, offset);
-      return advance();
+      appendToken3(yesType, offset);
+      return _reader.advance();
     } else {
-      appendToken2(noType, offset);
+      appendToken3(noType, offset);
       return next;
     }
   }
   int tokenizeAmpersand(int next) {
-    next = advance();
+    next = _reader.advance();
     if (next == 0x26) {
-      appendToken(TokenType.AMPERSAND_AMPERSAND);
-      return advance();
+      appendToken2(TokenType.AMPERSAND_AMPERSAND);
+      return _reader.advance();
     } else if (next == 0x3D) {
-      appendToken(TokenType.AMPERSAND_EQ);
-      return advance();
+      appendToken2(TokenType.AMPERSAND_EQ);
+      return _reader.advance();
     } else {
-      appendToken(TokenType.AMPERSAND);
+      appendToken2(TokenType.AMPERSAND);
       return next;
     }
   }
   int tokenizeBar(int next) {
-    next = advance();
+    next = _reader.advance();
     if (next == 0x7C) {
-      appendToken(TokenType.BAR_BAR);
-      return advance();
+      appendToken2(TokenType.BAR_BAR);
+      return _reader.advance();
     } else if (next == 0x3D) {
-      appendToken(TokenType.BAR_EQ);
-      return advance();
+      appendToken2(TokenType.BAR_EQ);
+      return _reader.advance();
     } else {
-      appendToken(TokenType.BAR);
+      appendToken2(TokenType.BAR);
       return next;
     }
   }
   int tokenizeCaret(int next) => select(0x3D, TokenType.CARET_EQ, TokenType.CARET);
   int tokenizeDotOrNumber(int next) {
-    int start = offset;
-    next = advance();
-    if ((0x30 <= next && next <= 0x39)) {
+    int start = _reader.offset;
+    next = _reader.advance();
+    if (0x30 <= next && next <= 0x39) {
       return tokenizeFractionPart(next, start);
     } else if (0x2E == next) {
       return select(0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD);
     } else {
-      appendToken(TokenType.PERIOD);
+      appendToken2(TokenType.PERIOD);
       return next;
     }
   }
   int tokenizeEquals(int next) {
-    next = advance();
+    next = _reader.advance();
     if (next == 0x3D) {
-      appendToken(TokenType.EQ_EQ);
-      return advance();
+      appendToken2(TokenType.EQ_EQ);
+      return _reader.advance();
     } else if (next == 0x3E) {
-      appendToken(TokenType.FUNCTION);
-      return advance();
+      appendToken2(TokenType.FUNCTION);
+      return _reader.advance();
     }
-    appendToken(TokenType.EQ);
+    appendToken2(TokenType.EQ);
     return next;
   }
   int tokenizeExclamation(int next) {
-    next = advance();
+    next = _reader.advance();
     if (next == 0x3D) {
-      appendToken(TokenType.BANG_EQ);
-      return advance();
+      appendToken2(TokenType.BANG_EQ);
+      return _reader.advance();
     }
-    appendToken(TokenType.BANG);
+    appendToken2(TokenType.BANG);
     return next;
   }
   int tokenizeExponent(int next) {
     if (next == 0x2B || next == 0x2D) {
-      next = advance();
+      next = _reader.advance();
     }
     bool hasDigits = false;
     while (true) {
@@ -895,7 +1069,7 @@
         }
         return next;
       }
-      next = advance();
+      next = _reader.advance();
     }
   }
   int tokenizeFractionPart(int next, int start) {
@@ -906,97 +1080,97 @@
         hasDigit = true;
       } else if (0x65 == next || 0x45 == next) {
         hasDigit = true;
-        next = tokenizeExponent(advance());
+        next = tokenizeExponent(_reader.advance());
         done = true;
         continue LOOP;
       } else {
         done = true;
         continue LOOP;
       }
-      next = advance();
+      next = _reader.advance();
     }
     if (!hasDigit) {
-      appendStringToken(TokenType.INT, getString(start, -2));
+      appendStringToken(TokenType.INT, _reader.getString(start, -2));
       if (0x2E == next) {
-        return select2(0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD, offset - 1);
+        return select2(0x2E, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD, _reader.offset - 1);
       }
-      appendToken2(TokenType.PERIOD, offset - 1);
+      appendToken3(TokenType.PERIOD, _reader.offset - 1);
       return bigSwitch(next);
     }
-    appendStringToken(TokenType.DOUBLE, getString(start, next < 0 ? 0 : -1));
+    appendStringToken(TokenType.DOUBLE, _reader.getString(start, next < 0 ? 0 : -1));
     return next;
   }
   int tokenizeGreaterThan(int next) {
-    next = advance();
+    next = _reader.advance();
     if (0x3D == next) {
-      appendToken(TokenType.GT_EQ);
-      return advance();
+      appendToken2(TokenType.GT_EQ);
+      return _reader.advance();
     } else if (0x3E == next) {
-      next = advance();
+      next = _reader.advance();
       if (0x3D == next) {
-        appendToken(TokenType.GT_GT_EQ);
-        return advance();
+        appendToken2(TokenType.GT_GT_EQ);
+        return _reader.advance();
       } else {
-        appendToken(TokenType.GT_GT);
+        appendToken2(TokenType.GT_GT);
         return next;
       }
     } else {
-      appendToken(TokenType.GT);
+      appendToken2(TokenType.GT);
       return next;
     }
   }
   int tokenizeHex(int next) {
-    int start = offset - 1;
+    int start = _reader.offset - 1;
     bool hasDigits = false;
     while (true) {
-      next = advance();
+      next = _reader.advance();
       if ((0x30 <= next && next <= 0x39) || (0x41 <= next && next <= 0x46) || (0x61 <= next && next <= 0x66)) {
         hasDigits = true;
       } else {
         if (!hasDigits) {
           reportError(ScannerErrorCode.MISSING_HEX_DIGIT, []);
         }
-        appendStringToken(TokenType.HEXADECIMAL, getString(start, next < 0 ? 0 : -1));
+        appendStringToken(TokenType.HEXADECIMAL, _reader.getString(start, next < 0 ? 0 : -1));
         return next;
       }
     }
   }
   int tokenizeHexOrNumber(int next) {
-    int x = peek();
+    int x = _reader.peek();
     if (x == 0x78 || x == 0x58) {
-      advance();
+      _reader.advance();
       return tokenizeHex(x);
     }
     return tokenizeNumber(next);
   }
   int tokenizeIdentifier(int next, int start, bool allowDollar) {
     while ((0x61 <= next && next <= 0x7A) || (0x41 <= next && next <= 0x5A) || (0x30 <= next && next <= 0x39) || next == 0x5F || (next == 0x24 && allowDollar)) {
-      next = advance();
+      next = _reader.advance();
     }
-    appendStringToken(TokenType.IDENTIFIER, getString(start, next < 0 ? 0 : -1));
+    appendStringToken(TokenType.IDENTIFIER, _reader.getString(start, next < 0 ? 0 : -1));
     return next;
   }
   int tokenizeInterpolatedExpression(int next, int start) {
     appendBeginToken(TokenType.STRING_INTERPOLATION_EXPRESSION);
-    next = advance();
+    next = _reader.advance();
     while (next != -1) {
       if (next == 0x7D) {
         BeginToken begin = findTokenMatchingClosingBraceInInterpolationExpression();
         if (begin == null) {
           beginToken();
-          appendToken(TokenType.CLOSE_CURLY_BRACKET);
-          next = advance();
+          appendToken2(TokenType.CLOSE_CURLY_BRACKET);
+          next = _reader.advance();
           beginToken();
           return next;
         } else if (identical(begin.type, TokenType.OPEN_CURLY_BRACKET)) {
           beginToken();
           appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
-          next = advance();
+          next = _reader.advance();
           beginToken();
         } else if (identical(begin.type, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
           beginToken();
           appendEndToken(TokenType.CLOSE_CURLY_BRACKET, TokenType.STRING_INTERPOLATION_EXPRESSION);
-          next = advance();
+          next = _reader.advance();
           beginToken();
           return next;
         }
@@ -1007,13 +1181,13 @@
     if (next == -1) {
       return next;
     }
-    next = advance();
+    next = _reader.advance();
     beginToken();
     return next;
   }
   int tokenizeInterpolatedIdentifier(int next, int start) {
     appendStringToken2(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 0);
-    if (((0x41 <= next && next <= 0x5A) || (0x61 <= next && next <= 0x7A) || next == 0x5F)) {
+    if ((0x41 <= next && next <= 0x5A) || (0x61 <= next && next <= 0x7A) || next == 0x5F) {
       beginToken();
       next = tokenizeKeywordOrIdentifier(next, false);
     }
@@ -1022,10 +1196,10 @@
   }
   int tokenizeKeywordOrIdentifier(int next, bool allowDollar) {
     KeywordState state = KeywordState.KEYWORD_STATE;
-    int start = offset;
+    int start = _reader.offset;
     while (state != null && 0x61 <= next && next <= 0x7A) {
       state = state.next(next as int);
-      next = advance();
+      next = _reader.advance();
     }
     if (state == null || state.keyword() == null) {
       return tokenizeIdentifier(next, start, allowDollar);
@@ -1040,183 +1214,183 @@
     }
   }
   int tokenizeLessThan(int next) {
-    next = advance();
+    next = _reader.advance();
     if (0x3D == next) {
-      appendToken(TokenType.LT_EQ);
-      return advance();
+      appendToken2(TokenType.LT_EQ);
+      return _reader.advance();
     } else if (0x3C == next) {
       return select(0x3D, TokenType.LT_LT_EQ, TokenType.LT_LT);
     } else {
-      appendToken(TokenType.LT);
+      appendToken2(TokenType.LT);
       return next;
     }
   }
   int tokenizeMinus(int next) {
-    next = advance();
+    next = _reader.advance();
     if (next == 0x2D) {
-      appendToken(TokenType.MINUS_MINUS);
-      return advance();
+      appendToken2(TokenType.MINUS_MINUS);
+      return _reader.advance();
     } else if (next == 0x3D) {
-      appendToken(TokenType.MINUS_EQ);
-      return advance();
+      appendToken2(TokenType.MINUS_EQ);
+      return _reader.advance();
     } else {
-      appendToken(TokenType.MINUS);
+      appendToken2(TokenType.MINUS);
       return next;
     }
   }
   int tokenizeMultiLineComment(int next) {
     int nesting = 1;
-    next = advance();
+    next = _reader.advance();
     while (true) {
       if (-1 == next) {
         reportError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, []);
-        appendCommentToken(TokenType.MULTI_LINE_COMMENT, getString(_tokenStart, 0));
+        appendCommentToken(TokenType.MULTI_LINE_COMMENT, _reader.getString(_tokenStart, 0));
         return next;
       } else if (0x2A == next) {
-        next = advance();
+        next = _reader.advance();
         if (0x2F == next) {
           --nesting;
           if (0 == nesting) {
-            appendCommentToken(TokenType.MULTI_LINE_COMMENT, getString(_tokenStart, 0));
-            return advance();
+            appendCommentToken(TokenType.MULTI_LINE_COMMENT, _reader.getString(_tokenStart, 0));
+            return _reader.advance();
           } else {
-            next = advance();
+            next = _reader.advance();
           }
         }
       } else if (0x2F == next) {
-        next = advance();
+        next = _reader.advance();
         if (0x2A == next) {
-          next = advance();
+          next = _reader.advance();
           ++nesting;
         }
       } else if (next == 0xD) {
-        next = advance();
+        next = _reader.advance();
         if (next == 0xA) {
-          next = advance();
+          next = _reader.advance();
         }
         recordStartOfLine();
       } else if (next == 0xA) {
         recordStartOfLine();
-        next = advance();
+        next = _reader.advance();
       } else {
-        next = advance();
+        next = _reader.advance();
       }
     }
   }
   int tokenizeMultiLineRawString(int quoteChar, int start) {
-    int next = advance();
+    int next = _reader.advance();
     outer: while (next != -1) {
       while (next != quoteChar) {
-        next = advance();
+        next = _reader.advance();
         if (next == -1) {
           break outer;
         } else if (next == 0xD) {
-          next = advance();
+          next = _reader.advance();
           if (next == 0xA) {
-            next = advance();
+            next = _reader.advance();
           }
           recordStartOfLine();
         } else if (next == 0xA) {
           recordStartOfLine();
-          next = advance();
+          next = _reader.advance();
         }
       }
-      next = advance();
+      next = _reader.advance();
       if (next == quoteChar) {
-        next = advance();
+        next = _reader.advance();
         if (next == quoteChar) {
-          appendStringToken(TokenType.STRING, getString(start, 0));
-          return advance();
+          appendStringToken(TokenType.STRING, _reader.getString(start, 0));
+          return _reader.advance();
         }
       }
     }
     reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
-    appendStringToken(TokenType.STRING, getString(start, 0));
-    return advance();
+    appendStringToken(TokenType.STRING, _reader.getString(start, 0));
+    return _reader.advance();
   }
   int tokenizeMultiLineString(int quoteChar, int start, bool raw) {
     if (raw) {
       return tokenizeMultiLineRawString(quoteChar, start);
     }
-    int next = advance();
+    int next = _reader.advance();
     while (next != -1) {
       if (next == 0x24) {
-        appendStringToken(TokenType.STRING, getString(start, -1));
+        appendStringToken(TokenType.STRING, _reader.getString(start, -1));
         beginToken();
         next = tokenizeStringInterpolation(start);
-        start = offset;
+        start = _reader.offset;
         continue;
       }
       if (next == quoteChar) {
-        next = advance();
+        next = _reader.advance();
         if (next == quoteChar) {
-          next = advance();
+          next = _reader.advance();
           if (next == quoteChar) {
-            appendStringToken(TokenType.STRING, getString(start, 0));
-            return advance();
+            appendStringToken(TokenType.STRING, _reader.getString(start, 0));
+            return _reader.advance();
           }
         }
         continue;
       }
       if (next == 0x5C) {
-        next = advance();
+        next = _reader.advance();
         if (next == -1) {
           break;
         }
         bool missingCharacter = false;
         if (next == 0xD) {
           missingCharacter = true;
-          next = advance();
+          next = _reader.advance();
           if (next == 0xA) {
-            next = advance();
+            next = _reader.advance();
           }
           recordStartOfLine();
         } else if (next == 0xA) {
           missingCharacter = true;
           recordStartOfLine();
-          next = advance();
+          next = _reader.advance();
         } else {
-          next = advance();
+          next = _reader.advance();
         }
         if (missingCharacter) {
-          _errorListener.onError(new AnalysisError.con2(source, offset - 1, 1, ScannerErrorCode.CHARACTER_EXPECTED_AFTER_SLASH, []));
+          _errorListener.onError(new AnalysisError.con2(source, _reader.offset - 1, 1, ScannerErrorCode.CHARACTER_EXPECTED_AFTER_SLASH, []));
         }
       } else if (next == 0xD) {
-        next = advance();
+        next = _reader.advance();
         if (next == 0xA) {
-          next = advance();
+          next = _reader.advance();
         }
         recordStartOfLine();
       } else if (next == 0xA) {
         recordStartOfLine();
-        next = advance();
+        next = _reader.advance();
       } else {
-        next = advance();
+        next = _reader.advance();
       }
     }
     reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
-    appendStringToken(TokenType.STRING, getString(start, 0));
-    return advance();
+    appendStringToken(TokenType.STRING, _reader.getString(start, 0));
+    return _reader.advance();
   }
   int tokenizeMultiply(int next) => select(0x3D, TokenType.STAR_EQ, TokenType.STAR);
   int tokenizeNumber(int next) {
-    int start = offset;
+    int start = _reader.offset;
     while (true) {
-      next = advance();
+      next = _reader.advance();
       if (0x30 <= next && next <= 0x39) {
         continue;
       } else if (next == 0x2E) {
-        return tokenizeFractionPart(advance(), start);
+        return tokenizeFractionPart(_reader.advance(), start);
       } else if (next == 0x65 || next == 0x45) {
         return tokenizeFractionPart(next, start);
       } else {
-        appendStringToken(TokenType.INT, getString(start, next < 0 ? 0 : -1));
+        appendStringToken(TokenType.INT, _reader.getString(start, next < 0 ? 0 : -1));
         return next;
       }
     }
   }
   int tokenizeOpenSquareBracket(int next) {
-    next = advance();
+    next = _reader.advance();
     if (next == 0x5D) {
       return select(0x3D, TokenType.INDEX_EQ, TokenType.INDEX);
     } else {
@@ -1226,91 +1400,91 @@
   }
   int tokenizePercent(int next) => select(0x3D, TokenType.PERCENT_EQ, TokenType.PERCENT);
   int tokenizePlus(int next) {
-    next = advance();
+    next = _reader.advance();
     if (0x2B == next) {
-      appendToken(TokenType.PLUS_PLUS);
-      return advance();
+      appendToken2(TokenType.PLUS_PLUS);
+      return _reader.advance();
     } else if (0x3D == next) {
-      appendToken(TokenType.PLUS_EQ);
-      return advance();
+      appendToken2(TokenType.PLUS_EQ);
+      return _reader.advance();
     } else {
-      appendToken(TokenType.PLUS);
+      appendToken2(TokenType.PLUS);
       return next;
     }
   }
   int tokenizeSingleLineComment(int next) {
     while (true) {
-      next = advance();
+      next = _reader.advance();
       if (-1 == next) {
-        appendCommentToken(TokenType.SINGLE_LINE_COMMENT, getString(_tokenStart, 0));
+        appendCommentToken(TokenType.SINGLE_LINE_COMMENT, _reader.getString(_tokenStart, 0));
         return next;
       } else if (0xA == next || 0xD == next) {
-        appendCommentToken(TokenType.SINGLE_LINE_COMMENT, getString(_tokenStart, -1));
+        appendCommentToken(TokenType.SINGLE_LINE_COMMENT, _reader.getString(_tokenStart, -1));
         return next;
       }
     }
   }
   int tokenizeSingleLineRawString(int next, int quoteChar, int start) {
-    next = advance();
+    next = _reader.advance();
     while (next != -1) {
       if (next == quoteChar) {
-        appendStringToken(TokenType.STRING, getString(start, 0));
-        return advance();
+        appendStringToken(TokenType.STRING, _reader.getString(start, 0));
+        return _reader.advance();
       } else if (next == 0xD || next == 0xA) {
         reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
-        appendStringToken(TokenType.STRING, getString(start, 0));
-        return advance();
+        appendStringToken(TokenType.STRING, _reader.getString(start, 0));
+        return _reader.advance();
       }
-      next = advance();
+      next = _reader.advance();
     }
     reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
-    appendStringToken(TokenType.STRING, getString(start, 0));
-    return advance();
+    appendStringToken(TokenType.STRING, _reader.getString(start, 0));
+    return _reader.advance();
   }
   int tokenizeSingleLineString(int next, int quoteChar, int start) {
     while (next != quoteChar) {
       if (next == 0x5C) {
-        next = advance();
+        next = _reader.advance();
       } else if (next == 0x24) {
-        appendStringToken(TokenType.STRING, getString(start, -1));
+        appendStringToken(TokenType.STRING, _reader.getString(start, -1));
         beginToken();
         next = tokenizeStringInterpolation(start);
-        start = offset;
+        start = _reader.offset;
         continue;
       }
       if (next <= 0xD && (next == 0xA || next == 0xD || next == -1)) {
         reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, []);
-        appendStringToken(TokenType.STRING, getString(start, 0));
-        return advance();
+        appendStringToken(TokenType.STRING, _reader.getString(start, 0));
+        return _reader.advance();
       }
-      next = advance();
+      next = _reader.advance();
     }
-    appendStringToken(TokenType.STRING, getString(start, 0));
-    return advance();
+    appendStringToken(TokenType.STRING, _reader.getString(start, 0));
+    return _reader.advance();
   }
   int tokenizeSlashOrComment(int next) {
-    next = advance();
+    next = _reader.advance();
     if (0x2A == next) {
       return tokenizeMultiLineComment(next);
     } else if (0x2F == next) {
       return tokenizeSingleLineComment(next);
     } else if (0x3D == next) {
-      appendToken(TokenType.SLASH_EQ);
-      return advance();
+      appendToken2(TokenType.SLASH_EQ);
+      return _reader.advance();
     } else {
-      appendToken(TokenType.SLASH);
+      appendToken2(TokenType.SLASH);
       return next;
     }
   }
   int tokenizeString(int next, int start, bool raw) {
     int quoteChar = next;
-    next = advance();
+    next = _reader.advance();
     if (quoteChar == next) {
-      next = advance();
+      next = _reader.advance();
       if (quoteChar == next) {
         return tokenizeMultiLineString(quoteChar, start, raw);
       } else {
-        appendStringToken(TokenType.STRING, getString(start, -1));
+        appendStringToken(TokenType.STRING, _reader.getString(start, -1));
         return next;
       }
     }
@@ -1322,7 +1496,7 @@
   }
   int tokenizeStringInterpolation(int start) {
     beginToken();
-    int next = advance();
+    int next = _reader.advance();
     if (next == 0x7B) {
       return tokenizeInterpolatedExpression(next, start);
     } else {
@@ -1330,24 +1504,24 @@
     }
   }
   int tokenizeTag(int next) {
-    if (offset == 0) {
-      if (peek() == 0x21) {
+    if (_reader.offset == 0) {
+      if (_reader.peek() == 0x21) {
         do {
-          next = advance();
+          next = _reader.advance();
         } while (next != 0xA && next != 0xD && next > 0);
-        appendStringToken(TokenType.SCRIPT_TAG, getString(_tokenStart, 0));
+        appendStringToken(TokenType.SCRIPT_TAG, _reader.getString(_tokenStart, 0));
         return next;
       }
     }
-    appendToken(TokenType.HASH);
-    return advance();
+    appendToken2(TokenType.HASH);
+    return _reader.advance();
   }
   int tokenizeTilde(int next) {
-    next = advance();
+    next = _reader.advance();
     if (next == 0x2F) {
       return select(0x3D, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
     } else {
-      appendToken(TokenType.TILDE);
+      appendToken2(TokenType.TILDE);
       return next;
     }
   }
@@ -1375,60 +1549,11 @@
   StringToken(TokenType type, String value, int offset) : super(type, offset) {
     this._value2 = StringUtilities.intern(value);
   }
+  Token copy() => new StringToken(type, _value2, offset);
   String get lexeme => _value2;
   String value() => _value2;
 }
 /**
- * Instances of the class `CharBufferScanner` implement a scanner that reads from a character
- * buffer. The scanning logic is in the superclass.
- *
- * @coverage dart.engine.parser
- */
-class CharBufferScanner extends AbstractScanner {
-
-  /**
-   * The buffer from which characters will be read.
-   */
-  CharBuffer _buffer;
-
-  /**
-   * The number of characters in the buffer.
-   */
-  int _bufferLength = 0;
-
-  /**
-   * The index of the last character that was read.
-   */
-  int _charOffset = 0;
-
-  /**
-   * Initialize a newly created scanner to scan the characters in the given character buffer.
-   *
-   * @param source the source being scanned
-   * @param buffer the buffer from which characters will be read
-   * @param errorListener the error listener that will be informed of any errors that are found
-   */
-  CharBufferScanner(Source source, CharBuffer buffer, AnalysisErrorListener errorListener) : super(source, errorListener) {
-    this._buffer = buffer;
-    this._bufferLength = buffer.length();
-    this._charOffset = -1;
-  }
-  int get offset => _charOffset;
-  int advance() {
-    if (_charOffset + 1 >= _bufferLength) {
-      return -1;
-    }
-    return _buffer.charAt(++_charOffset);
-  }
-  String getString(int start, int endDelta) => ((_buffer as CharSequence)).subSequence(start, _charOffset + 1 + endDelta).toString();
-  int peek() {
-    if (_charOffset + 1 >= _buffer.length()) {
-      return -1;
-    }
-    return _buffer.charAt(_charOffset + 1);
-  }
-}
-/**
  * Instances of the class `TokenWithComment` represent a normal token that is preceded by
  * comments.
  *
@@ -1452,6 +1577,7 @@
   TokenWithComment(TokenType type, int offset, Token precedingComment) : super(type, offset) {
     this._precedingComment = precedingComment;
   }
+  Token copy() => new TokenWithComment(type, offset, _precedingComment);
   Token get precedingComments => _precedingComment;
 }
 /**
@@ -1494,6 +1620,14 @@
   }
 
   /**
+   * Return a newly created token that is a copy of this token but that is not a part of any token
+   * stream.
+   *
+   * @return a newly created token that is a copy of this token
+   */
+  Token copy() => new Token(type, offset);
+
+  /**
    * Return the offset from the beginning of the file to the character after last character of the
    * token.
    *
@@ -1581,88 +1715,82 @@
    * @return the value of this token
    */
   Object value() => type.lexeme;
+
+  /**
+   * Apply (add) the given delta to this token's offset.
+   *
+   * @param delta the amount by which the offset is to be adjusted
+   */
+  void applyDelta(int delta) {
+    offset += delta;
+  }
+
+  /**
+   * Copy a linked list of comment tokens identical to the given comment tokens.
+   *
+   * @param token the first token in the list, or `null` if there are no tokens to be copied
+   * @return the tokens that were created
+   */
+  Token copyComments(Token token) {
+    if (token == null) {
+      return null;
+    }
+    Token head = token.copy();
+    Token tail = head;
+    token = token.next;
+    while (token != null) {
+      tail = tail.setNext(token.copy());
+    }
+    return head;
+  }
 }
 /**
- * Instances of the class `StringScanner` implement a scanner that reads from a string. The
- * scanning logic is in the superclass.
- *
- * @coverage dart.engine.parser
+ * The interface `CharacterReader`
  */
-class StringScanner extends AbstractScanner {
+abstract class CharacterReader {
 
   /**
-   * The offset from the beginning of the file to the beginning of the source being scanned.
-   */
-  int _offsetDelta = 0;
-
-  /**
-   * The string from which characters will be read.
-   */
-  String _string;
-
-  /**
-   * The number of characters in the string.
-   */
-  int _stringLength = 0;
-
-  /**
-   * The index, relative to the string, of the last character that was read.
-   */
-  int _charOffset = 0;
-
-  /**
-   * Initialize a newly created scanner to scan the characters in the given string.
+   * Advance the current position and return the character at the new current position.
    *
-   * @param source the source being scanned
-   * @param string the string from which characters will be read
-   * @param errorListener the error listener that will be informed of any errors that are found
+   * @return the character at the new current position
    */
-  StringScanner(Source source, String string, AnalysisErrorListener errorListener) : super(source, errorListener) {
-    this._offsetDelta = 0;
-    this._string = string;
-    this._stringLength = string.length;
-    this._charOffset = -1;
-  }
-  int get offset => _offsetDelta + _charOffset;
+  int advance();
 
   /**
-   * Record that the source begins on the given line and column at the given offset. The line starts
-   * for lines before the given line will not be correct.
+   * Return the current offset relative to the beginning of the source. Return the initial offset if
+   * the scanner has not yet scanned the source code, and one (1) past the end of the source code if
+   * the entire source code has been scanned.
    *
-   * This method must be invoked at most one time and must be invoked before scanning begins. The
-   * values provided must be sensible. The results are undefined if these conditions are violated.
-   *
-   * @param line the one-based index of the line containing the first character of the source
-   * @param column the one-based index of the column in which the first character of the source
-   *          occurs
-   * @param offset the zero-based offset from the beginning of the larger context to the first
-   *          character of the source
+   * @return the current offset of the scanner in the source
    */
-  void setSourceStart(int line, int column, int offset) {
-    if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) {
-      return;
-    }
-    _offsetDelta = 1;
-    for (int i = 2; i < line; i++) {
-      recordStartOfLine();
-    }
-    _offsetDelta = offset - column + 1;
-    recordStartOfLine();
-    _offsetDelta = offset;
-  }
-  int advance() {
-    if (_charOffset + 1 >= _stringLength) {
-      return -1;
-    }
-    return _string.codeUnitAt(++_charOffset);
-  }
-  String getString(int start, int endDelta) => _string.substring(start - _offsetDelta, _charOffset + 1 + endDelta);
-  int peek() {
-    if (_charOffset + 1 >= _string.length) {
-      return -1;
-    }
-    return _string.codeUnitAt(_charOffset + 1);
-  }
+  int get offset;
+
+  /**
+   * Return the substring of the source code between the start offset and the modified current
+   * position. The current position is modified by adding the end delta.
+   *
+   * @param start the offset to the beginning of the string, relative to the start of the file
+   * @param endDelta the number of characters after the current location to be included in the
+   *          string, or the number of characters before the current location to be excluded if the
+   *          offset is negative
+   * @return the specified substring of the source code
+   */
+  String getString(int start, int endDelta);
+
+  /**
+   * Return the character at the current position without changing the current position.
+   *
+   * @return the character at the current position
+   */
+  int peek();
+
+  /**
+   * Set the current offset relative to the beginning of the source. The new offset must be between
+   * the initial offset and one (1) past the end of the source code.
+   *
+   * @param offset the new offset in the source
+   */
+  void set offset(int offset);
 }
 /**
  * Instances of the class `BeginTokenWithComment` represent a begin token that is preceded by
@@ -1688,7 +1816,16 @@
   BeginTokenWithComment(TokenType type, int offset, Token precedingComment) : super(type, offset) {
     this._precedingComment = precedingComment;
   }
+  Token copy() => new BeginTokenWithComment(type, offset, copyComments(_precedingComment));
   Token get precedingComments => _precedingComment;
+  void applyDelta(int delta) {
+    super.applyDelta(delta);
+    Token token = _precedingComment;
+    while (token != null) {
+      token.applyDelta(delta);
+      token = token.next;
+    }
+  }
 }
 /**
  * Instances of the class `KeywordToken` represent a keyword in the language.
@@ -1711,6 +1848,7 @@
   KeywordToken(Keyword keyword, int offset) : super(TokenType.KEYWORD, offset) {
     this.keyword = keyword;
   }
+  Token copy() => new KeywordToken(keyword, offset);
   String get lexeme => keyword.syntax;
   Keyword value() => keyword;
 }
@@ -1736,6 +1874,7 @@
   BeginToken(TokenType type, int offset) : super(type, offset) {
     assert((identical(type, TokenType.OPEN_CURLY_BRACKET) || identical(type, TokenType.OPEN_PAREN) || identical(type, TokenType.OPEN_SQUARE_BRACKET) || identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION)));
   }
+  Token copy() => new BeginToken(type, offset);
 }
 /**
  * The enumeration `TokenClass` represents classes (or groups) of tokens with a similar use.
@@ -1875,7 +2014,16 @@
   KeywordTokenWithComment(Keyword keyword, int offset, Token precedingComment) : super(keyword, offset) {
     this._precedingComment = precedingComment;
   }
+  Token copy() => new KeywordTokenWithComment(keyword, offset, copyComments(_precedingComment));
   Token get precedingComments => _precedingComment;
+  void applyDelta(int delta) {
+    super.applyDelta(delta);
+    Token token = _precedingComment;
+    while (token != null) {
+      token.applyDelta(delta);
+      token = token.next;
+    }
+  }
 }
 /**
  * The enumeration `TokenType` defines the types of tokens that can be returned by the
diff --git a/pkg/analyzer_experimental/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/generated/sdk.dart
rename to pkg/analyzer/lib/src/generated/sdk.dart
diff --git a/pkg/analyzer_experimental/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
similarity index 98%
rename from pkg/analyzer_experimental/lib/src/generated/sdk_io.dart
rename to pkg/analyzer/lib/src/generated/sdk_io.dart
index 5289fb2..f00131a 100644
--- a/pkg/analyzer_experimental/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -465,9 +465,9 @@
    */
   LibraryMap readFrom(JavaFile librariesFile, String libraryFileContents) {
     List<bool> foundError = [false];
-    AnalysisErrorListener errorListener = new AnalysisErrorListener_8(foundError);
+    AnalysisErrorListener errorListener = new AnalysisErrorListener_10(foundError);
     Source source = new FileBasedSource.con2(null, librariesFile, UriKind.FILE_URI);
-    StringScanner scanner = new StringScanner(source, libraryFileContents, errorListener);
+    Scanner scanner = new Scanner(source, new CharSequenceReader(new CharSequence(libraryFileContents)), errorListener);
     Parser parser = new Parser(source, errorListener);
     CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
     SdkLibrariesReader_LibraryBuilder libraryBuilder = new SdkLibrariesReader_LibraryBuilder();
@@ -557,9 +557,9 @@
     return null;
   }
 }
-class AnalysisErrorListener_8 implements AnalysisErrorListener {
+class AnalysisErrorListener_10 implements AnalysisErrorListener {
   List<bool> foundError;
-  AnalysisErrorListener_8(this.foundError);
+  AnalysisErrorListener_10(this.foundError);
   void onError(AnalysisError error) {
     foundError[0] = true;
   }
diff --git a/pkg/analyzer_experimental/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
similarity index 97%
rename from pkg/analyzer_experimental/lib/src/generated/source.dart
rename to pkg/analyzer/lib/src/generated/source.dart
index e0d3c4d..4a1546b 100644
--- a/pkg/analyzer_experimental/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -154,9 +154,9 @@
    *
    * @param source the source whose contents are being overridden
    * @param contents the new contents of the source
-   * @return `true` if the new cached contents are different from the old, else `false`
+   * @return the original cached contents or `null` if none
    */
-  bool setContents(Source source, String contents) => contentCache.setContents(source, contents);
+  String setContents(Source source, String contents) => contentCache.setContents(source, contents);
 
   /**
    * Return the contents of the given source, or `null` if this factory does not override the
@@ -795,16 +795,15 @@
    *
    * @param source the source whose contents are being overridden
    * @param contents the new contents of the source
-   * @return `true` if the new cached contents are different than the old, else `false`
+   * @return the original cached contents or `null` if none
    */
-  bool setContents(Source source, String contents) {
+  String setContents(Source source, String contents) {
     if (contents == null) {
       _stampMap.remove(source);
-      return _contentMap.remove(source) != null;
+      return _contentMap.remove(source);
     } else {
       _stampMap[source] = JavaSystem.currentTimeMillis();
-      String originalContents = javaMapPut(_contentMap, source, contents);
-      return contents != originalContents;
+      return javaMapPut(_contentMap, source, contents);
     }
   }
 }
\ No newline at end of file
diff --git a/pkg/analyzer_experimental/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/generated/source_io.dart
rename to pkg/analyzer/lib/src/generated/source_io.dart
diff --git a/pkg/analyzer_experimental/lib/src/generated/utilities_collection.dart b/pkg/analyzer/lib/src/generated/utilities_collection.dart
similarity index 76%
rename from pkg/analyzer_experimental/lib/src/generated/utilities_collection.dart
rename to pkg/analyzer/lib/src/generated/utilities_collection.dart
index 4dd72cb..adda610 100644
--- a/pkg/analyzer_experimental/lib/src/generated/utilities_collection.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_collection.dart
@@ -2,6 +2,7 @@
 // significant change. Please see the README file for more information.
 library engine.utilities.collection;
 import 'java_core.dart';
+import 'scanner.dart' show Token;
 /**
  * The class `BooleanArray` defines methods for operating on integers as if they were arrays
  * of booleans. These arrays can be indexed by either integers or by enumeration constants.
@@ -73,6 +74,37 @@
   }
 }
 /**
+ * Instances of the class `TokenMap` map one set of tokens to another set of tokens.
+ */
+class TokenMap {
+
+  /**
+   * A table mapping tokens to tokens. This should be replaced by a more performant implementation.
+   * One possibility is a pair of parallel arrays, with keys being sorted by their offset and a
+   * cursor indicating where to start searching.
+   */
+  Map<Token, Token> _map = new Map<Token, Token>();
+
+  /**
+   * Return the token that is mapped to the given token, or `null` if there is no token
+   * corresponding to the given token.
+   *
+   * @param key the token being mapped to another token
+   * @return the token that is mapped to the given token
+   */
+  Token get(Token key) => _map[key];
+
+  /**
+   * Map the key to the value.
+   *
+   * @param key the token being mapped to the value
+   * @param value the token to which the key will be mapped
+   */
+  void put(Token key, Token value) {
+    _map[key] = value;
+  }
+}
+/**
  * The class `ListUtilities` defines utility methods useful for working with [List
  ].
  */
diff --git a/pkg/analyzer_experimental/lib/src/generated/utilities_dart.dart b/pkg/analyzer/lib/src/generated/utilities_dart.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/generated/utilities_dart.dart
rename to pkg/analyzer/lib/src/generated/utilities_dart.dart
diff --git a/pkg/analyzer_experimental/lib/src/generated/utilities_general.dart b/pkg/analyzer/lib/src/generated/utilities_general.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/generated/utilities_general.dart
rename to pkg/analyzer/lib/src/generated/utilities_general.dart
diff --git a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart b/pkg/analyzer/lib/src/services/formatter_impl.dart
similarity index 98%
rename from pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
rename to pkg/analyzer/lib/src/services/formatter_impl.dart
index 88e0192..ccb5b6d 100644
--- a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer/lib/src/services/formatter_impl.dart
@@ -6,11 +6,12 @@
 
 import 'dart:math';
 
-import 'package:analyzer_experimental/analyzer.dart';
-import 'package:analyzer_experimental/src/generated/parser.dart';
-import 'package:analyzer_experimental/src/generated/scanner.dart';
-import 'package:analyzer_experimental/src/generated/source.dart';
-import 'package:analyzer_experimental/src/services/writer.dart';
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/src/generated/java_core.dart' show CharSequence;
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/services/writer.dart';
 
 /// Formatter options.
 class FormatterOptions {
@@ -170,7 +171,8 @@
   }
 
   Token tokenize(String source) {
-    var scanner = new StringScanner(null, source, this);
+    var reader = new CharSequenceReader(new CharSequence(source));
+    var scanner = new Scanner(null, reader, this);
     var token = scanner.tokenize();
     lineInfo = new LineInfo(scanner.lineStarts);
     return token;
diff --git a/pkg/analyzer_experimental/lib/src/services/runtime/coverage/coverage_impl.dart b/pkg/analyzer/lib/src/services/runtime/coverage/coverage_impl.dart
similarity index 94%
rename from pkg/analyzer_experimental/lib/src/services/runtime/coverage/coverage_impl.dart
rename to pkg/analyzer/lib/src/services/runtime/coverage/coverage_impl.dart
index c1f3956..262280d 100644
--- a/pkg/analyzer_experimental/lib/src/services/runtime/coverage/coverage_impl.dart
+++ b/pkg/analyzer/lib/src/services/runtime/coverage/coverage_impl.dart
@@ -11,10 +11,11 @@
 
 import 'package:path/path.dart' as pathos;
 
-import 'package:analyzer_experimental/src/generated/scanner.dart' show StringScanner;
-import 'package:analyzer_experimental/src/generated/parser.dart' show Parser;
-import 'package:analyzer_experimental/src/generated/ast.dart';
-import 'package:analyzer_experimental/src/generated/engine.dart' show RecordingErrorListener;
+import 'package:analyzer/src/generated/java_core.dart' show CharSequence;
+import 'package:analyzer/src/generated/scanner.dart' show CharSequenceReader, Scanner;
+import 'package:analyzer/src/generated/parser.dart' show Parser;
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart' show RecordingErrorListener;
 
 import '../log.dart' as log;
 import 'models.dart';
@@ -206,7 +207,7 @@
       return true;
     }
     // TODO(scheglov) use configuration
-    return path.contains('/packages/analyzer_experimental/');
+    return path.contains('/packages/analyzer/');
   }
 
   String rewriteFileContent(String path, String code) {
@@ -246,7 +247,8 @@
     var source = null;
     var errorListener = new RecordingErrorListener();
     var parser = new Parser(source, errorListener);
-    var scanner = new StringScanner(source, code, errorListener);
+    var reader = new CharSequenceReader(new CharSequence(code));
+    var scanner = new Scanner(null, reader, errorListener);
     var token = scanner.tokenize();
     return parser.parseCompilationUnit(token);
   }
diff --git a/pkg/analyzer_experimental/lib/src/services/runtime/coverage/coverage_lib.dart b/pkg/analyzer/lib/src/services/runtime/coverage/coverage_lib.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/services/runtime/coverage/coverage_lib.dart
rename to pkg/analyzer/lib/src/services/runtime/coverage/coverage_lib.dart
diff --git a/pkg/analyzer_experimental/lib/src/services/runtime/coverage/models.dart b/pkg/analyzer/lib/src/services/runtime/coverage/models.dart
similarity index 95%
rename from pkg/analyzer_experimental/lib/src/services/runtime/coverage/models.dart
rename to pkg/analyzer/lib/src/services/runtime/coverage/models.dart
index 463a0cd..912985f 100644
--- a/pkg/analyzer_experimental/lib/src/services/runtime/coverage/models.dart
+++ b/pkg/analyzer/lib/src/services/runtime/coverage/models.dart
@@ -7,8 +7,8 @@
 
 import 'dart:collection' show SplayTreeMap;
 
-import 'package:analyzer_experimental/src/generated/source.dart' show Source, SourceRange;
-import 'package:analyzer_experimental/src/generated/ast.dart' show ASTNode;
+import 'package:analyzer/src/generated/source.dart' show Source, SourceRange;
+import 'package:analyzer/src/generated/ast.dart' show ASTNode;
 
 import 'utils.dart';
 
diff --git a/pkg/analyzer_experimental/lib/src/services/runtime/coverage/utils.dart b/pkg/analyzer/lib/src/services/runtime/coverage/utils.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/services/runtime/coverage/utils.dart
rename to pkg/analyzer/lib/src/services/runtime/coverage/utils.dart
diff --git a/pkg/analyzer_experimental/lib/src/services/runtime/log.dart b/pkg/analyzer/lib/src/services/runtime/log.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/services/runtime/log.dart
rename to pkg/analyzer/lib/src/services/runtime/log.dart
diff --git a/pkg/analyzer_experimental/lib/src/services/writer.dart b/pkg/analyzer/lib/src/services/writer.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/services/writer.dart
rename to pkg/analyzer/lib/src/services/writer.dart
diff --git a/pkg/analyzer_experimental/lib/src/string_source.dart b/pkg/analyzer/lib/src/string_source.dart
similarity index 100%
rename from pkg/analyzer_experimental/lib/src/string_source.dart
rename to pkg/analyzer/lib/src/string_source.dart
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
new file mode 100644
index 0000000..a9cfe4d
--- /dev/null
+++ b/pkg/analyzer/pubspec.yaml
@@ -0,0 +1,11 @@
+name: analyzer
+version: 0.9.0
+author: Dart Team <misc@dartlang.org>
+description: Static analyzer for Dart.
+homepage: http://www.dartlang.org
+dependencies:
+  args: ">=0.8.6"
+  logging: ">=0.8.6"
+  path: ">=0.8.6"
+dev_dependencies:
+  unittest: ">=0.8.6"
diff --git a/pkg/analyzer_experimental/test/error_test.dart b/pkg/analyzer/test/error_test.dart
similarity index 100%
rename from pkg/analyzer_experimental/test/error_test.dart
rename to pkg/analyzer/test/error_test.dart
diff --git a/pkg/analyzer_experimental/test/generated/ast_test.dart b/pkg/analyzer/test/generated/ast_test.dart
similarity index 98%
rename from pkg/analyzer_experimental/test/generated/ast_test.dart
rename to pkg/analyzer/test/generated/ast_test.dart
index f90e9a3..15e5588 100644
--- a/pkg/analyzer_experimental/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/generated/ast_test.dart
@@ -1,12 +1,12 @@
 // This code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 library engine.ast_test;
-import 'package:analyzer_experimental/src/generated/java_core.dart';
-import 'package:analyzer_experimental/src/generated/java_junit.dart';
-import 'package:analyzer_experimental/src/generated/scanner.dart';
-import 'package:analyzer_experimental/src/generated/ast.dart';
-import 'package:analyzer_experimental/src/generated/utilities_dart.dart';
-import 'package:analyzer_experimental/src/generated/element.dart' show ClassElement;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_junit.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/generated/element.dart' show ClassElement;
 import 'package:unittest/unittest.dart' as _ut;
 import 'parser_test.dart' show ParserTestCase;
 import 'test_support.dart';
@@ -775,7 +775,7 @@
         "}"]);
     CompilationUnit unit = ParserTestCase.parseCompilationUnit(source, []);
     List<ASTNode> nodes = new List<ASTNode>();
-    BreadthFirstVisitor<Object> visitor = new BreadthFirstVisitor_17(nodes);
+    BreadthFirstVisitor<Object> visitor = new BreadthFirstVisitor_18(nodes);
     visitor.visitAllNodes(unit);
     EngineTestCase.assertSize(59, nodes);
     EngineTestCase.assertInstanceOf(CompilationUnit, nodes[0]);
@@ -793,9 +793,9 @@
     });
   }
 }
-class BreadthFirstVisitor_17 extends BreadthFirstVisitor<Object> {
+class BreadthFirstVisitor_18 extends BreadthFirstVisitor<Object> {
   List<ASTNode> nodes;
-  BreadthFirstVisitor_17(this.nodes) : super();
+  BreadthFirstVisitor_18(this.nodes) : super();
   Object visitNode(ASTNode node) {
     nodes.add(node);
     return super.visitNode(node);
@@ -920,6 +920,24 @@
     list.add(node);
     JUnitTestCase.assertSame(node.endToken, list.endToken);
   }
+  void test_indexOf() {
+    List<ASTNode> nodes = new List<ASTNode>();
+    ASTNode firstNode = ASTFactory.booleanLiteral(true);
+    ASTNode secondNode = ASTFactory.booleanLiteral(false);
+    ASTNode thirdNode = ASTFactory.booleanLiteral(true);
+    ASTNode fourthNode = ASTFactory.booleanLiteral(false);
+    nodes.add(firstNode);
+    nodes.add(secondNode);
+    nodes.add(thirdNode);
+    NodeList<ASTNode> list = new NodeList<ASTNode>(ASTFactory.argumentList([]));
+    list.addAll(nodes);
+    EngineTestCase.assertSize(3, list);
+    JUnitTestCase.assertEquals(0, list.indexOf(firstNode));
+    JUnitTestCase.assertEquals(1, list.indexOf(secondNode));
+    JUnitTestCase.assertEquals(2, list.indexOf(thirdNode));
+    JUnitTestCase.assertEquals(-1, list.indexOf(fourthNode));
+    JUnitTestCase.assertEquals(-1, list.indexOf(null));
+  }
   void test_remove() {
     List<ASTNode> nodes = new List<ASTNode>();
     ASTNode firstNode = ASTFactory.booleanLiteral(true);
@@ -1038,6 +1056,10 @@
         final __test = new NodeListTest();
         runJUnitTest(__test, __test.test_get_tooBig);
       });
+      _ut.test('test_indexOf', () {
+        final __test = new NodeListTest();
+        runJUnitTest(__test, __test.test_indexOf);
+      });
       _ut.test('test_remove', () {
         final __test = new NodeListTest();
         runJUnitTest(__test, __test.test_remove);
diff --git a/pkg/analyzer_experimental/test/generated/element_test.dart b/pkg/analyzer/test/generated/element_test.dart
similarity index 99%
rename from pkg/analyzer_experimental/test/generated/element_test.dart
rename to pkg/analyzer/test/generated/element_test.dart
index 048e507..16ac04b 100644
--- a/pkg/analyzer_experimental/test/generated/element_test.dart
+++ b/pkg/analyzer/test/generated/element_test.dart
@@ -1,14 +1,14 @@
 // This code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 library engine.element_test;
-import 'package:analyzer_experimental/src/generated/java_core.dart';
-import 'package:analyzer_experimental/src/generated/java_engine_io.dart';
-import 'package:analyzer_experimental/src/generated/java_junit.dart';
-import 'package:analyzer_experimental/src/generated/source_io.dart';
-import 'package:analyzer_experimental/src/generated/utilities_dart.dart';
-import 'package:analyzer_experimental/src/generated/ast.dart';
-import 'package:analyzer_experimental/src/generated/element.dart';
-import 'package:analyzer_experimental/src/generated/engine.dart' show AnalysisContext, AnalysisContextImpl;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/java_junit.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext, AnalysisContextImpl;
 import 'package:unittest/unittest.dart' as _ut;
 import 'test_support.dart';
 import 'ast_test.dart' show ASTFactory;
@@ -2497,7 +2497,7 @@
   }
   void test_isSubtypeOf_baseCase_classFunction() {
     ClassElementImpl functionElement = ElementFactory.classElement2("Function", []);
-    InterfaceTypeImpl functionType = new InterfaceTypeImpl_22(functionElement);
+    InterfaceTypeImpl functionType = new InterfaceTypeImpl_23(functionElement);
     FunctionType f = ElementFactory.functionElement("f").type;
     JUnitTestCase.assertTrue(f.isSubtypeOf(functionType));
   }
@@ -2961,8 +2961,8 @@
     });
   }
 }
-class InterfaceTypeImpl_22 extends InterfaceTypeImpl {
-  InterfaceTypeImpl_22(ClassElement arg0) : super.con1(arg0);
+class InterfaceTypeImpl_23 extends InterfaceTypeImpl {
+  InterfaceTypeImpl_23(ClassElement arg0) : super.con1(arg0);
   bool get isDartCoreFunction => true;
 }
 main() {
diff --git a/pkg/analyzer_experimental/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
similarity index 99%
rename from pkg/analyzer_experimental/test/generated/parser_test.dart
rename to pkg/analyzer/test/generated/parser_test.dart
index 6835d17..0ceef47 100644
--- a/pkg/analyzer_experimental/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -1,13 +1,13 @@
 // This code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 library engine.parser_test;
-import 'package:analyzer_experimental/src/generated/java_core.dart';
-import 'package:analyzer_experimental/src/generated/java_junit.dart';
-import 'package:analyzer_experimental/src/generated/error.dart';
-import 'package:analyzer_experimental/src/generated/scanner.dart';
-import 'package:analyzer_experimental/src/generated/ast.dart';
-import 'package:analyzer_experimental/src/generated/parser.dart';
-import 'package:analyzer_experimental/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_junit.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:unittest/unittest.dart' as _ut;
 import 'test_support.dart';
 import 'scanner_test.dart' show TokenFactory;
@@ -3788,7 +3788,7 @@
    * @throws Exception if the method could not be invoked or throws an exception
    */
   String computeStringValue(String lexeme, bool first, bool last) {
-    AnalysisErrorListener listener = new AnalysisErrorListener_23();
+    AnalysisErrorListener listener = new AnalysisErrorListener_24();
     Parser parser = new Parser(null, listener);
     return invokeParserMethodImpl(parser, "computeStringValue", <Object> [lexeme, first, last], null) as String;
   }
@@ -3842,7 +3842,7 @@
    */
   bool isFunctionExpression(String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    StringScanner scanner = new StringScanner(null, source, listener);
+    Scanner scanner = new Scanner(null, new CharSequenceReader(new CharSequence(source)), listener);
     Token tokenStream = scanner.tokenize();
     Parser parser = new Parser(null, listener);
     return invokeParserMethodImpl(parser, "isFunctionExpression", <Object> [tokenStream], tokenStream) as bool;
@@ -3886,7 +3886,7 @@
    */
   Token skip(String methodName, String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    StringScanner scanner = new StringScanner(null, source, listener);
+    Scanner scanner = new Scanner(null, new CharSequenceReader(new CharSequence(source)), listener);
     Token tokenStream = scanner.tokenize();
     Parser parser = new Parser(null, listener);
     return invokeParserMethodImpl(parser, methodName, <Object> [tokenStream], tokenStream) as Token;
@@ -6020,7 +6020,7 @@
     });
   }
 }
-class AnalysisErrorListener_23 implements AnalysisErrorListener {
+class AnalysisErrorListener_24 implements AnalysisErrorListener {
   void onError(AnalysisError event) {
     JUnitTestCase.fail("Unexpected compilation error: ${event.message} (${event.offset}, ${event.length})");
   }
@@ -6614,7 +6614,7 @@
    */
   static CompilationUnit parseCompilationUnit(String source, List<ErrorCode> errorCodes) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    StringScanner scanner = new StringScanner(null, source, listener);
+    Scanner scanner = new Scanner(null, new CharSequenceReader(new CharSequence(source)), listener);
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     Token token = scanner.tokenize();
     Parser parser = new Parser(null, listener);
@@ -6635,7 +6635,7 @@
    */
   static Expression parseExpression(String source, List<ErrorCode> errorCodes) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    StringScanner scanner = new StringScanner(null, source, listener);
+    Scanner scanner = new Scanner(null, new CharSequenceReader(new CharSequence(source)), listener);
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     Token token = scanner.tokenize();
     Parser parser = new Parser(null, listener);
@@ -6656,7 +6656,7 @@
    */
   static Statement parseStatement(String source, List<ErrorCode> errorCodes) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    StringScanner scanner = new StringScanner(null, source, listener);
+    Scanner scanner = new Scanner(null, new CharSequenceReader(new CharSequence(source)), listener);
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     Token token = scanner.tokenize();
     Parser parser = new Parser(null, listener);
@@ -6679,7 +6679,7 @@
    */
   static List<Statement> parseStatements(String source, int expectedCount, List<ErrorCode> errorCodes) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    StringScanner scanner = new StringScanner(null, source, listener);
+    Scanner scanner = new Scanner(null, new CharSequenceReader(new CharSequence(source)), listener);
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     Token token = scanner.tokenize();
     Parser parser = new Parser(null, listener);
@@ -6706,7 +6706,7 @@
    *           scanning and parsing the source do not match the expected errors
    */
   static Object invokeParserMethod(String methodName, List<Object> objects, String source, GatheringErrorListener listener) {
-    StringScanner scanner = new StringScanner(null, source, listener);
+    Scanner scanner = new Scanner(null, new CharSequenceReader(new CharSequence(source)), listener);
     Token tokenStream = scanner.tokenize();
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     Parser parser = new Parser(null, listener);
@@ -7599,12 +7599,6 @@
  * that errors are correctly reported, and in some cases, not reported.
  */
 class ErrorParserTest extends ParserTestCase {
-  void fail_deprecatedClassTypeAlias() {
-    ParserTestCase.parseCompilationUnit("typedef C = abstract S with M;", [ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS]);
-  }
-  void fail_deprecatedClassTypeAlias_withGeneric() {
-    ParserTestCase.parseCompilationUnit("typedef C<T> = abstract S<T> with M;", [ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS]);
-  }
   void fail_expectedListOrMapLiteral() {
     TypedLiteral literal = ParserTestCase.parse4("parseListOrMapLiteral", <Object> [null], "1", [ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]);
     JUnitTestCase.assertTrue(literal.isSynthetic);
@@ -7766,6 +7760,12 @@
   void test_continueWithoutLabelInCase_noError_switchInLoop() {
     ParserTestCase.parse5("parseWhileStatement", "while (a) { switch (b) {default: continue;}}", []);
   }
+  void test_deprecatedClassTypeAlias() {
+    ParserTestCase.parseCompilationUnit("typedef C = abstract S with M;", [ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS]);
+  }
+  void test_deprecatedClassTypeAlias_withGeneric() {
+    ParserTestCase.parseCompilationUnit("typedef C<T> = abstract S<T> with M;", [ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS]);
+  }
   void test_directiveAfterDeclaration_classBeforeDirective() {
     CompilationUnit unit = ParserTestCase.parseCompilationUnit("class Foo{} library l;", [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
     JUnitTestCase.assertNotNull(unit);
@@ -8549,6 +8549,14 @@
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_continueWithoutLabelInCase_noError_switchInLoop);
       });
+      _ut.test('test_deprecatedClassTypeAlias', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_deprecatedClassTypeAlias);
+      });
+      _ut.test('test_deprecatedClassTypeAlias_withGeneric', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_deprecatedClassTypeAlias_withGeneric);
+      });
       _ut.test('test_directiveAfterDeclaration_classBeforeDirective', () {
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_directiveAfterDeclaration_classBeforeDirective);
diff --git a/pkg/analyzer_experimental/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
similarity index 96%
rename from pkg/analyzer_experimental/test/generated/resolver_test.dart
rename to pkg/analyzer/test/generated/resolver_test.dart
index 9620ea8..4a0fb46b 100644
--- a/pkg/analyzer_experimental/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -1,19 +1,19 @@
 // This code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 library engine.resolver_test;
-import 'package:analyzer_experimental/src/generated/java_core.dart';
-import 'package:analyzer_experimental/src/generated/java_junit.dart';
-import 'package:analyzer_experimental/src/generated/source_io.dart';
-import 'package:analyzer_experimental/src/generated/error.dart';
-import 'package:analyzer_experimental/src/generated/scanner.dart';
-import 'package:analyzer_experimental/src/generated/ast.dart';
-import 'package:analyzer_experimental/src/generated/parser.dart' show ParserErrorCode;
-import 'package:analyzer_experimental/src/generated/element.dart';
-import 'package:analyzer_experimental/src/generated/resolver.dart';
-import 'package:analyzer_experimental/src/generated/engine.dart';
-import 'package:analyzer_experimental/src/generated/java_engine_io.dart';
-import 'package:analyzer_experimental/src/generated/sdk.dart' show DartSdk;
-import 'package:analyzer_experimental/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_junit.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
+import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
 import 'package:unittest/unittest.dart' as _ut;
 import 'test_support.dart';
 import 'ast_test.dart' show ASTFactory;
@@ -424,7 +424,7 @@
         "  }",
         "}"]));
     LibraryElement library = resolve(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+    assertNoErrors(source);
     CompilationUnit unit = resolveCompilationUnit(source, library);
     FunctionDeclaration function = unit.declarations[2] as FunctionDeclaration;
     BlockFunctionBody body = function.functionExpression.body as BlockFunctionBody;
@@ -2373,6 +2373,35 @@
     assertNoErrors(source);
     verify([source]);
   }
+  void test_mixedReturnTypes_differentScopes() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class C {",
+        "  m(int x) {",
+        "    f(int y) {",
+        "      return;",
+        "    }",
+        "    f(x);",
+        "    return 0;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_mixedReturnTypes_sameKind() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class C {",
+        "  m(int x) {",
+        "    if (x < 0) {",
+        "      return 1;",
+        "    }",
+        "    return 0;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
   void test_mixinDeclaresConstructor() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
@@ -2488,6 +2517,30 @@
     assertNoErrors(source);
     verify([source]);
   }
+  void test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_accessor() {
+    Source source = addSource(EngineTestCase.createSource([
+        "abstract class A {",
+        "  int get g;",
+        "}",
+        "class B extends A {",
+        "  noSuchMethod(v) => '';",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_method() {
+    Source source = addSource(EngineTestCase.createSource([
+        "abstract class A {",
+        "  m(p);",
+        "}",
+        "class B extends A {",
+        "  noSuchMethod(v) => '';",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
   void test_nonBoolExpression_functionType() {
     Source source = addSource(EngineTestCase.createSource([
         "bool makeAssertion() => true;",
@@ -2844,7 +2897,7 @@
     assertNoErrors(source);
     verify([source]);
   }
-  void test_propagateTypeArgsIntoBounds() {
+  void test_propagateTypeArgs_intoBounds() {
     Source source = addSource(EngineTestCase.createSource([
         "abstract class A<E> {}",
         "abstract class B<F> implements A<F>{}",
@@ -2854,6 +2907,20 @@
     assertNoErrors(source);
     verify([source]);
   }
+  void test_propagateTypeArgs_intoSupertype() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A<T> {",
+        "  A(T p);",
+        "  A.named(T p);",
+        "}",
+        "class B<S> extends A<S> {",
+        "  B(S p) : super(p);",
+        "  B.named(S p) : super.named(p);",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
   void test_proxy_annotation_prefixed() {
     Source source = addSource(EngineTestCase.createSource([
         "library L;",
@@ -3202,12 +3269,6 @@
     assertNoErrors(source);
     verify([source]);
   }
-  void test_typeAliasCannotReferenceItself_typeParameterBounds() {
-    Source source = addSource(EngineTestCase.createSource(["typedef A<T extends A>();"]));
-    resolve(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
   void test_typeArgumentNotMatchingBounds_const() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {}",
@@ -3248,6 +3309,186 @@
     assertNoErrors(source);
     verify([source]);
   }
+  void test_typePromotion_booleanAnd_useInRight() {
+    Source source = addSource(EngineTestCase.createSource([
+        "main(Object p) {",
+        "  p is String && p.length != 0;",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment() {
+    Source source = addSource(EngineTestCase.createSource([
+        "callMe(f()) { f(); }",
+        "main(Object p) {",
+        "  (p is String) && callMe(() { p.length; });",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_conditional_useInThen() {
+    Source source = addSource(EngineTestCase.createSource(["main(Object p) {", "  p is String ? p.length : 0;", "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment() {
+    Source source = addSource(EngineTestCase.createSource([
+        "callMe(f()) { f(); }",
+        "main(Object p) {",
+        "  p is String ? callMe(() { p.length; }) : 0;",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_functionType_arg_ignoreIfNotMoreSpecific() {
+    Source source = addSource(EngineTestCase.createSource([
+        "typedef FuncB(B b);",
+        "typedef FuncA(A a);",
+        "class A {}",
+        "class B {}",
+        "main(FuncA f) {",
+        "  if (f is FuncB) {",
+        "    f(new A());",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_functionType_return_ignoreIfNotMoreSpecific() {
+    Source source = addSource(EngineTestCase.createSource([
+        "typedef FuncDynToDyn(x);",
+        "typedef void FuncDynToVoid(x);",
+        "class A {}",
+        "main(FuncDynToDyn f) {",
+        "  if (f is FuncDynToVoid) {",
+        "    A a = f(null);",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_functionType_return_voidToDynamic() {
+    Source source = addSource(EngineTestCase.createSource([
+        "typedef FuncDynToDyn(x);",
+        "typedef void FuncDynToVoid(x);",
+        "class A {}",
+        "main(FuncDynToVoid f) {",
+        "  if (f is FuncDynToDyn) {",
+        "    A a = f(null);",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_if_accessedInClosure_noAssignment() {
+    Source source = addSource(EngineTestCase.createSource([
+        "callMe(f()) { f(); }",
+        "main(Object p) {",
+        "  if (p is String) {",
+        "    callMe(() {",
+        "      p.length;",
+        "    });",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_if_hasAssignment_outsideAfter() {
+    Source source = addSource(EngineTestCase.createSource([
+        "main(Object p) {",
+        "  if (p is String) {",
+        "    p.length;",
+        "  }",
+        "  p = 0;",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_if_hasAssignment_outsideBefore() {
+    Source source = addSource(EngineTestCase.createSource([
+        "main(Object p, Object p2) {",
+        "  p = p2;",
+        "  if (p is String) {",
+        "    p.length;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_if_is_and_left() {
+    Source source = addSource(EngineTestCase.createSource([
+        "bool tt() => true;",
+        "main(Object p) {",
+        "  if (p is String && tt()) {",
+        "    p.length;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_if_is_and_right() {
+    Source source = addSource(EngineTestCase.createSource([
+        "bool tt() => true;",
+        "main(Object p) {",
+        "  if (tt() && p is String) {",
+        "    p.length;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_if_is_and_subThenSuper() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {",
+        "  var a;",
+        "}",
+        "class B extends A {",
+        "  var b;",
+        "}",
+        "main(Object p) {",
+        "  if (p is B && p is A) {",
+        "    p.a;",
+        "    p.b;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_if_is_parenthesized() {
+    Source source = addSource(EngineTestCase.createSource([
+        "main(Object p) {",
+        "  if ((p is String)) {",
+        "    p.length;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+  void test_typePromotion_if_is_single() {
+    Source source = addSource(EngineTestCase.createSource([
+        "main(Object p) {",
+        "  if (p is String) {",
+        "    p.length;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
   void test_undefinedConstructorInInitializer_explicit_named() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
@@ -4058,6 +4299,14 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_misMatchedGetterAndSetterTypes_topLevel_unspecifiedSetter);
       });
+      _ut.test('test_mixedReturnTypes_differentScopes', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_mixedReturnTypes_differentScopes);
+      });
+      _ut.test('test_mixedReturnTypes_sameKind', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_mixedReturnTypes_sameKind);
+      });
       _ut.test('test_mixinDeclaresConstructor', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_mixinDeclaresConstructor);
@@ -4102,6 +4351,14 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_abstractOverridesConcrete_method);
       });
+      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_accessor', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_accessor);
+      });
+      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_method', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_method);
+      });
       _ut.test('test_nonBoolExpression_functionType', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_nonBoolExpression_functionType);
@@ -4246,9 +4503,13 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_prefixCollidesWithTopLevelMembers);
       });
-      _ut.test('test_propagateTypeArgsIntoBounds', () {
+      _ut.test('test_propagateTypeArgs_intoBounds', () {
         final __test = new NonErrorResolverTest();
-        runJUnitTest(__test, __test.test_propagateTypeArgsIntoBounds);
+        runJUnitTest(__test, __test.test_propagateTypeArgs_intoBounds);
+      });
+      _ut.test('test_propagateTypeArgs_intoSupertype', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_propagateTypeArgs_intoSupertype);
       });
       _ut.test('test_proxy_annotation_prefixed', () {
         final __test = new NonErrorResolverTest();
@@ -4358,10 +4619,6 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_typeAliasCannotReferenceItself_returnClass_withTypeAlias);
       });
-      _ut.test('test_typeAliasCannotReferenceItself_typeParameterBounds', () {
-        final __test = new NonErrorResolverTest();
-        runJUnitTest(__test, __test.test_typeAliasCannotReferenceItself_typeParameterBounds);
-      });
       _ut.test('test_typeArgumentNotMatchingBounds_const', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_typeArgumentNotMatchingBounds_const);
@@ -4382,6 +4639,66 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_typeArgumentNotMatchingBounds_typeArgumentList_20);
       });
+      _ut.test('test_typePromotion_booleanAnd_useInRight', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_booleanAnd_useInRight);
+      });
+      _ut.test('test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment);
+      });
+      _ut.test('test_typePromotion_conditional_useInThen', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_conditional_useInThen);
+      });
+      _ut.test('test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment);
+      });
+      _ut.test('test_typePromotion_functionType_arg_ignoreIfNotMoreSpecific', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_functionType_arg_ignoreIfNotMoreSpecific);
+      });
+      _ut.test('test_typePromotion_functionType_return_ignoreIfNotMoreSpecific', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_functionType_return_ignoreIfNotMoreSpecific);
+      });
+      _ut.test('test_typePromotion_functionType_return_voidToDynamic', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_functionType_return_voidToDynamic);
+      });
+      _ut.test('test_typePromotion_if_accessedInClosure_noAssignment', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_if_accessedInClosure_noAssignment);
+      });
+      _ut.test('test_typePromotion_if_hasAssignment_outsideAfter', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_if_hasAssignment_outsideAfter);
+      });
+      _ut.test('test_typePromotion_if_hasAssignment_outsideBefore', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_if_hasAssignment_outsideBefore);
+      });
+      _ut.test('test_typePromotion_if_is_and_left', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_if_is_and_left);
+      });
+      _ut.test('test_typePromotion_if_is_and_right', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_if_is_and_right);
+      });
+      _ut.test('test_typePromotion_if_is_and_subThenSuper', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_if_is_and_subThenSuper);
+      });
+      _ut.test('test_typePromotion_if_is_parenthesized', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_if_is_parenthesized);
+      });
+      _ut.test('test_typePromotion_if_is_single', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_typePromotion_if_is_single);
+      });
       _ut.test('test_undefinedConstructorInInitializer_explicit_named', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_undefinedConstructorInInitializer_explicit_named);
@@ -5153,6 +5470,106 @@
     assertErrors(source, [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND]);
     verify([source]);
   }
+  void test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated() {
+    Source source = addSource(EngineTestCase.createSource([
+        "callMe(f()) { f(); }",
+        "main(Object p) {",
+        "  (p is String) && callMe(() { p.length; });",
+        "  p = 0;",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+  void test_typePromotion_booleanAnd_useInRight_mutatedInLeft() {
+    Source source = addSource(EngineTestCase.createSource([
+        "main(Object p) {",
+        "  ((p is String) && ((p = 42) == 42)) && p.length != 0;",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+  void test_typePromotion_booleanAnd_useInRight_mutatedInRight() {
+    Source source = addSource(EngineTestCase.createSource([
+        "main(Object p) {",
+        "  (p is String) && (((p = 42) == 42) && p.length != 0);",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+  void test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_after() {
+    Source source = addSource(EngineTestCase.createSource([
+        "callMe(f()) { f(); }",
+        "main(Object p) {",
+        "  p is String ? callMe(() { p.length; }) : 0;",
+        "  p = 42;",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+  void test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_before() {
+    Source source = addSource(EngineTestCase.createSource([
+        "callMe(f()) { f(); }",
+        "main(Object p) {",
+        "  p = 42;",
+        "  p is String ? callMe(() { p.length; }) : 0;",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+  void test_typePromotion_conditional_useInThen_hasAssignment() {
+    Source source = addSource(EngineTestCase.createSource([
+        "main(Object p) {",
+        "  p is String ? (p.length + (p = 42)) : 0;",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+  void test_typePromotion_if_accessedInClosure_hasAssignment() {
+    Source source = addSource(EngineTestCase.createSource([
+        "callMe(f()) { f(); }",
+        "main(Object p) {",
+        "  if (p is String) {",
+        "    callMe(() {",
+        "      p.length;",
+        "    });",
+        "  }",
+        "  p = 0;",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+  void test_typePromotion_if_and_right_hasAssignment() {
+    Source source = addSource(EngineTestCase.createSource([
+        "main(Object p) {",
+        "  if (p is String && (p = null) == null) {",
+        "    p.length;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+  void test_typePromotion_if_hasAssignment_after() {
+    Source source = addSource(EngineTestCase.createSource([
+        "main(Object p) {",
+        "  if (p is String) {",
+        "    p.length;",
+        "    p = 0;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+  void test_typePromotion_if_hasAssignment_before() {
+    Source source = addSource(EngineTestCase.createSource([
+        "main(Object p) {",
+        "  if (p is String) {",
+        "    p = 0;",
+        "    p.length;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
   void test_undefinedGetter() {
     Source source = addSource(EngineTestCase.createSource(["class T {}", "f(T e) { return e.m; }"]));
     resolve(source);
@@ -5210,9 +5627,7 @@
   void test_undefinedOperator_indexBoth() {
     Source source = addSource(EngineTestCase.createSource(["class A {}", "f(A a) {", "  a[0]++;", "}"]));
     resolve(source);
-    assertErrors(source, [
-        StaticTypeWarningCode.UNDEFINED_OPERATOR,
-        StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
   }
   void test_undefinedOperator_indexGetter() {
     Source source = addSource(EngineTestCase.createSource(["class A {}", "f(A a) {", "  a[0];", "}"]));
@@ -5580,6 +5995,46 @@
         final __test = new StaticTypeWarningCodeTest();
         runJUnitTest(__test, __test.test_typeParameterSupertypeOfItsBound);
       });
+      _ut.test('test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated);
+      });
+      _ut.test('test_typePromotion_booleanAnd_useInRight_mutatedInLeft', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_typePromotion_booleanAnd_useInRight_mutatedInLeft);
+      });
+      _ut.test('test_typePromotion_booleanAnd_useInRight_mutatedInRight', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_typePromotion_booleanAnd_useInRight_mutatedInRight);
+      });
+      _ut.test('test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_after', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_after);
+      });
+      _ut.test('test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_before', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_before);
+      });
+      _ut.test('test_typePromotion_conditional_useInThen_hasAssignment', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_typePromotion_conditional_useInThen_hasAssignment);
+      });
+      _ut.test('test_typePromotion_if_accessedInClosure_hasAssignment', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_typePromotion_if_accessedInClosure_hasAssignment);
+      });
+      _ut.test('test_typePromotion_if_and_right_hasAssignment', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_typePromotion_if_and_right_hasAssignment);
+      });
+      _ut.test('test_typePromotion_if_hasAssignment_after', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_typePromotion_if_hasAssignment_after);
+      });
+      _ut.test('test_typePromotion_if_hasAssignment_before', () {
+        final __test = new StaticTypeWarningCodeTest();
+        runJUnitTest(__test, __test.test_typePromotion_if_hasAssignment_before);
+      });
       _ut.test('test_undefinedGetter', () {
         final __test = new StaticTypeWarningCodeTest();
         runJUnitTest(__test, __test.test_undefinedGetter);
@@ -6089,7 +6544,7 @@
         "  }",
         "}"]));
     resolve(source);
-    assertErrors(source, [HintCode.UNDEFINED_OPERATOR, HintCode.UNDEFINED_OPERATOR]);
+    assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
   }
   void test_undefinedOperator_indexGetter() {
     Source source = addSource(EngineTestCase.createSource([
@@ -6569,7 +7024,7 @@
     CatchClause clause = ASTFactory.catchClause("e", []);
     SimpleIdentifier exceptionParameter = clause.exceptionParameter;
     exceptionParameter.staticElement = new LocalVariableElementImpl(exceptionParameter);
-    resolve(clause, _typeProvider.objectType, null, []);
+    resolve(clause, _typeProvider.dynamicType, null, []);
     _listener.assertNoErrors();
   }
   void test_visitCatchClause_exception_stackTrace() {
@@ -6578,7 +7033,7 @@
     exceptionParameter.staticElement = new LocalVariableElementImpl(exceptionParameter);
     SimpleIdentifier stackTraceParameter = clause.stackTraceParameter;
     stackTraceParameter.staticElement = new LocalVariableElementImpl(stackTraceParameter);
-    resolve(clause, _typeProvider.objectType, _typeProvider.stackTraceType, []);
+    resolve(clause, _typeProvider.dynamicType, _typeProvider.stackTraceType, []);
     _listener.assertNoErrors();
   }
   void test_visitCatchClause_on_exception() {
@@ -6741,7 +7196,7 @@
    * @param definedElements the elements that are to be defined in the scope in which the element is
    *          being resolved
    */
-  void resolve(CatchClause node, InterfaceType exceptionType, InterfaceType stackTraceType, List<Element> definedElements) {
+  void resolve(CatchClause node, Type2 exceptionType, InterfaceType stackTraceType, List<Element> definedElements) {
     resolveNode(node, definedElements);
     SimpleIdentifier exceptionParameter = node.exceptionParameter;
     if (exceptionParameter != null) {
@@ -8429,6 +8884,19 @@
     assertErrors(source, [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
     verify([source]);
   }
+  void test_defaultValueInRedirectingFactoryConstructor() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {",
+        "  factory A([int x = 0]) = B;",
+        "}",
+        "",
+        "class B implements A {",
+        "  B([int x = 1]) {}",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR]);
+    verify([source]);
+  }
   void test_duplicateConstructorName_named() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  A.a() {}", "  A.a() {}", "}"]));
     resolve(source);
@@ -8448,9 +8916,7 @@
   void test_duplicateDefinition() {
     Source source = addSource(EngineTestCase.createSource(["f() {", "  int m = 0;", "  m(a) {}", "}"]));
     resolve(source);
-    assertErrors(source, [
-        CompileTimeErrorCode.DUPLICATE_DEFINITION,
-        CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
     verify([source]);
   }
   void test_duplicateDefinition_acrossLibraries() {
@@ -8464,29 +8930,19 @@
   void test_duplicateDefinition_classMembers_fields() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  int a;", "  int a;", "}"]));
     resolve(source);
-    assertErrors(source, [
-        CompileTimeErrorCode.DUPLICATE_DEFINITION,
-        CompileTimeErrorCode.DUPLICATE_DEFINITION,
-        CompileTimeErrorCode.DUPLICATE_DEFINITION,
-        CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
     verify([source]);
   }
   void test_duplicateDefinition_classMembers_fields_oneStatic() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  int x;", "  static int x;", "}"]));
     resolve(source);
-    assertErrors(source, [
-        CompileTimeErrorCode.DUPLICATE_DEFINITION,
-        CompileTimeErrorCode.DUPLICATE_DEFINITION,
-        CompileTimeErrorCode.DUPLICATE_DEFINITION,
-        CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
     verify([source]);
   }
   void test_duplicateDefinition_classMembers_methods() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  m() {}", "  m() {}", "}"]));
     resolve(source);
-    assertErrors(source, [
-        CompileTimeErrorCode.DUPLICATE_DEFINITION,
-        CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
     verify([source]);
   }
   void test_duplicateDefinition_localFields() {
@@ -8498,25 +8954,19 @@
         "  }",
         "}"]));
     resolve(source);
-    assertErrors(source, [
-        CompileTimeErrorCode.DUPLICATE_DEFINITION,
-        CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
     verify([source]);
   }
   void test_duplicateDefinition_parameterWithFunctionName_local() {
     Source source = addSource(EngineTestCase.createSource(["main() {", "  f(f) {}", "}"]));
     resolve(source);
-    assertErrors(source, [
-        CompileTimeErrorCode.DUPLICATE_DEFINITION,
-        CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
     verify([source]);
   }
   void test_duplicateDefinition_parameterWithFunctionName_topLevel() {
     Source source = addSource(EngineTestCase.createSource(["main() {", "  f(f) {}", "}"]));
     resolve(source);
-    assertErrors(source, [
-        CompileTimeErrorCode.DUPLICATE_DEFINITION,
-        CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
     verify([source]);
   }
   void test_duplicateDefinitionInheritance_instanceGetter_staticGetter() {
@@ -8842,9 +9292,7 @@
   void test_getterAndMethodWithSameName() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  x(y) {}", "  get x => 0;", "}"]));
     resolve(source);
-    assertErrors(source, [
-        CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME,
-        CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME]);
+    assertErrors(source, [CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME]);
     verify([source]);
   }
   void test_implementsDisallowedClass_bool() {
@@ -9364,9 +9812,7 @@
   void test_methodAndGetterWithSameName() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  get x => 0;", "  x(y) {}", "}"]));
     resolve(source);
-    assertErrors(source, [
-        CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME,
-        CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME]);
+    assertErrors(source, [CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME]);
     verify([source]);
   }
   void test_mixinDeclaresConstructor_classDeclaration() {
@@ -10057,6 +10503,41 @@
     assertErrors(source, [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]);
     verify([source]);
   }
+  void test_referencedBeforeDeclaration_hideInBlock_function() {
+    Source source = addSource(EngineTestCase.createSource([
+        "var v = 1;",
+        "main() {",
+        "  print(v);",
+        "  v() {}",
+        "}",
+        "print(x) {}"]));
+    resolve(source);
+    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
+  }
+  void test_referencedBeforeDeclaration_hideInBlock_local() {
+    Source source = addSource(EngineTestCase.createSource([
+        "var v = 1;",
+        "main() {",
+        "  print(v);",
+        "  var v = 2;",
+        "}",
+        "print(x) {}"]));
+    resolve(source);
+    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
+  }
+  void test_referencedBeforeDeclaration_hideInBlock_subBlock() {
+    Source source = addSource(EngineTestCase.createSource([
+        "var v = 1;",
+        "main() {",
+        "  {",
+        "    print(v);",
+        "  }",
+        "  var v = 2;",
+        "}",
+        "print(x) {}"]));
+    resolve(source);
+    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
+  }
   void test_referenceToDeclaredVariableInInitializer_closure() {
     Source source = addSource(EngineTestCase.createSource(["f() {", "  var x = (x) {};", "}"]));
     resolve(source);
@@ -10243,6 +10724,12 @@
         CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
     verify([source]);
   }
+  void test_typeAliasCannotReferenceItself_typeVariableBounds() {
+    Source source = addSource(EngineTestCase.createSource(["typedef A<T extends A>();"]));
+    resolve(source);
+    assertErrors(source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+    verify([source]);
+  }
   void test_typeAliasCannotRereferenceItself_mixin_direct() {
     Source source = addSource(EngineTestCase.createSource(["class M = Object with M;"]));
     resolve(source);
@@ -10771,6 +11258,10 @@
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_defaultValueInFunctionTypedParameter_optional);
       });
+      _ut.test('test_defaultValueInRedirectingFactoryConstructor', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_defaultValueInRedirectingFactoryConstructor);
+      });
       _ut.test('test_duplicateConstructorName_named', () {
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_duplicateConstructorName_named);
@@ -11567,6 +12058,18 @@
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_referenceToDeclaredVariableInInitializer_unqualifiedInvocation);
       });
+      _ut.test('test_referencedBeforeDeclaration_hideInBlock_function', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_referencedBeforeDeclaration_hideInBlock_function);
+      });
+      _ut.test('test_referencedBeforeDeclaration_hideInBlock_local', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_referencedBeforeDeclaration_hideInBlock_local);
+      });
+      _ut.test('test_referencedBeforeDeclaration_hideInBlock_subBlock', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_referencedBeforeDeclaration_hideInBlock_subBlock);
+      });
       _ut.test('test_rethrowOutsideCatch', () {
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_rethrowOutsideCatch);
@@ -11647,6 +12150,10 @@
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_typeAliasCannotReferenceItself_returnType_indirect);
       });
+      _ut.test('test_typeAliasCannotReferenceItself_typeVariableBounds', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_typeAliasCannotReferenceItself_typeVariableBounds);
+      });
       _ut.test('test_typeAliasCannotRereferenceItself_mixin_direct', () {
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_typeAliasCannotRereferenceItself_mixin_direct);
@@ -11970,7 +12477,7 @@
         "  return (n is int && n > 0) ? n & 0x0F : 0;",
         "}"]));
     resolve(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+    assertNoErrors(source);
   }
   void test_conditional_is() {
     Source source = addSource(EngineTestCase.createSource([
@@ -11978,7 +12485,7 @@
         "  return (n is int) ? n & 0x0F : 0;",
         "}"]));
     resolve(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+    assertNoErrors(source);
   }
   void test_conditional_isNot() {
     Source source = addSource(EngineTestCase.createSource([
@@ -12016,7 +12523,7 @@
         "  return 0;",
         "}"]));
     resolve(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+    assertNoErrors(source);
   }
   void test_if_is() {
     Source source = addSource(EngineTestCase.createSource([
@@ -12027,7 +12534,7 @@
         "  return 0;",
         "}"]));
     resolve(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+    assertNoErrors(source);
   }
   void test_if_isNot() {
     Source source = addSource(EngineTestCase.createSource([
@@ -13039,62 +13546,6 @@
   }
 }
 class StaticWarningCodeTest extends ResolverTestCase {
-  void fail_commentReferenceConstructorNotVisible() {
-    Source source = addSource(EngineTestCase.createSource([]));
-    resolve(source);
-    assertErrors(source, [StaticWarningCode.COMMENT_REFERENCE_CONSTRUCTOR_NOT_VISIBLE]);
-    verify([source]);
-  }
-  void fail_commentReferenceIdentifierNotVisible() {
-    Source source = addSource(EngineTestCase.createSource([]));
-    resolve(source);
-    assertErrors(source, [StaticWarningCode.COMMENT_REFERENCE_IDENTIFIER_NOT_VISIBLE]);
-    verify([source]);
-  }
-  void fail_commentReferenceUndeclaredConstructor() {
-    Source source = addSource(EngineTestCase.createSource([]));
-    resolve(source);
-    assertErrors(source, [StaticWarningCode.COMMENT_REFERENCE_UNDECLARED_CONSTRUCTOR]);
-    verify([source]);
-  }
-  void fail_commentReferenceUndeclaredIdentifier() {
-    Source source = addSource(EngineTestCase.createSource([]));
-    resolve(source);
-    assertErrors(source, [StaticWarningCode.COMMENT_REFERENCE_UNDECLARED_IDENTIFIER]);
-    verify([source]);
-  }
-  void fail_commentReferenceUriNotLibrary() {
-    Source source = addSource(EngineTestCase.createSource([]));
-    resolve(source);
-    assertErrors(source, [StaticWarningCode.COMMENT_REFERENCE_URI_NOT_LIBRARY]);
-    verify([source]);
-  }
-  void fail_mismatchedAccessorTypes_getterAndSuperSetter() {
-    Source source = addSource(EngineTestCase.createSource([
-        "class A {",
-        "  int get g { return 0; }",
-        "  set g(int v) {}",
-        "}",
-        "class B extends A {",
-        "  set g(String v) {}",
-        "}"]));
-    resolve(source);
-    assertErrors(source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
-    verify([source]);
-  }
-  void fail_mismatchedAccessorTypes_superGetterAndSetter() {
-    Source source = addSource(EngineTestCase.createSource([
-        "class A {",
-        "  int get g { return 0; }",
-        "  set g(int v) {}",
-        "}",
-        "class B extends A {",
-        "  String get g { return ''; }",
-        "}"]));
-    resolve(source);
-    assertErrors(source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
-    verify([source]);
-  }
   void fail_undefinedGetter() {
     Source source = addSource(EngineTestCase.createSource([]));
     resolve(source);
@@ -13505,21 +13956,6 @@
     assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_CONST]);
     verify([source]);
   }
-  void test_assignmentToFinal_excludedSetter() {
-    Source source = addSource(EngineTestCase.createSource([
-        "class A {",
-        "  var v;",
-        "}",
-        "class B extends A {",
-        "  final v = 0;",
-        "}",
-        "main() {",
-        "  new B().v = 1;",
-        "}"]));
-    resolve(source);
-    assertErrors(source, [StaticWarningCode.ASSIGNMENT_TO_FINAL]);
-    verify([source]);
-  }
   void test_assignmentToFinal_instanceVariable() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
@@ -14308,12 +14744,78 @@
     assertErrors(source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
     verify([source]);
   }
+  void test_mismatchedAccessorTypes_getterAndSuperSetter() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {",
+        "  int get g { return 0; }",
+        "}",
+        "class B extends A {",
+        "  set g(String v) {}",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE]);
+    verify([source]);
+  }
+  void test_mismatchedAccessorTypes_setterAndSuperGetter() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {",
+        "  set g(int v) {}",
+        "}",
+        "class B extends A {",
+        "  String get g { return ''; }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE]);
+    verify([source]);
+  }
   void test_mismatchedAccessorTypes_topLevel() {
     Source source = addSource(EngineTestCase.createSource(["int get g { return 0; }", "set g(String v) {}"]));
     resolve(source);
     assertErrors(source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
     verify([source]);
   }
+  void test_mixedReturnTypes_localFunction() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class C {",
+        "  m(int x) {",
+        "    return (int y) {",
+        "      if (y < 0) {",
+        "        return;",
+        "      }",
+        "      return 0;",
+        "    };",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.MIXED_RETURN_TYPES]);
+    verify([source]);
+  }
+  void test_mixedReturnTypes_method() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class C {",
+        "  m(int x) {",
+        "    if (x < 0) {",
+        "      return;",
+        "    }",
+        "    return 0;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.MIXED_RETURN_TYPES]);
+    verify([source]);
+  }
+  void test_mixedReturnTypes_topLevelFunction() {
+    Source source = addSource(EngineTestCase.createSource([
+        "f(int x) {",
+        "  if (x < 0) {",
+        "    return;",
+        "  }",
+        "  return 0;",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.MIXED_RETURN_TYPES]);
+    verify([source]);
+  }
   void test_newWithAbstractClass() {
     Source source = addSource(EngineTestCase.createSource([
         "abstract class A {}",
@@ -14481,18 +14983,6 @@
     assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
-  void test_nonAbstractClassInheritsAbstractMemberOne_setter_excluded() {
-    Source source = addSource(EngineTestCase.createSource([
-        "class A {",
-        "  final int x = 0;",
-        "}",
-        "class B implements A {",
-        "  int get x => 42;",
-        "}"]));
-    resolve(source);
-    assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
-    verify([source]);
-  }
   void test_nonAbstractClassInheritsAbstractMemberOne_setter_fromInterface() {
     Source source = addSource(EngineTestCase.createSource([
         "class I {",
@@ -14767,6 +15257,20 @@
     assertErrors(source, [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]);
     verify([source]);
   }
+  void test_typePromotion_functionType_arg_InterToDyn() {
+    Source source = addSource(EngineTestCase.createSource([
+        "typedef FuncDyn(x);",
+        "typedef FuncA(A a);",
+        "class A {}",
+        "class B {}",
+        "main(FuncA f) {",
+        "  if (f is FuncDyn) {",
+        "    f(new B());",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+  }
   void test_typeTestNonType() {
     Source source = addSource(EngineTestCase.createSource(["var A = 0;", "f(var p) {", "  if (p is A) {", "  }", "}"]));
     resolve(source);
@@ -14817,41 +15321,6 @@
     assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
     verify([source]);
   }
-  void test_undefinedIdentifier_hideInBlock_function() {
-    Source source = addSource(EngineTestCase.createSource([
-        "var v = 1;",
-        "main() {",
-        "  print(v);",
-        "  v() {}",
-        "}",
-        "print(x) {}"]));
-    resolve(source);
-    assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
-  }
-  void test_undefinedIdentifier_hideInBlock_local() {
-    Source source = addSource(EngineTestCase.createSource([
-        "var v = 1;",
-        "main() {",
-        "  print(v);",
-        "  var v = 2;",
-        "}",
-        "print(x) {}"]));
-    resolve(source);
-    assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
-  }
-  void test_undefinedIdentifier_hideInBlock_subBlock() {
-    Source source = addSource(EngineTestCase.createSource([
-        "var v = 1;",
-        "main() {",
-        "  {",
-        "    print(v);",
-        "  }",
-        "  var v = 2;",
-        "}",
-        "print(x) {}"]));
-    resolve(source);
-    assertErrors(source, [StaticWarningCode.UNDEFINED_IDENTIFIER]);
-  }
   void test_undefinedIdentifier_initializer() {
     Source source = addSource(EngineTestCase.createSource(["var a = b;"]));
     resolve(source);
@@ -15055,10 +15524,6 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_assignmentToConst_localVariable);
       });
-      _ut.test('test_assignmentToFinal_excludedSetter', () {
-        final __test = new StaticWarningCodeTest();
-        runJUnitTest(__test, __test.test_assignmentToFinal_excludedSetter);
-      });
       _ut.test('test_assignmentToFinal_instanceVariable', () {
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_assignmentToFinal_instanceVariable);
@@ -15363,10 +15828,30 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_mismatchedAccessorTypes_class);
       });
+      _ut.test('test_mismatchedAccessorTypes_getterAndSuperSetter', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_mismatchedAccessorTypes_getterAndSuperSetter);
+      });
+      _ut.test('test_mismatchedAccessorTypes_setterAndSuperGetter', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_mismatchedAccessorTypes_setterAndSuperGetter);
+      });
       _ut.test('test_mismatchedAccessorTypes_topLevel', () {
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_mismatchedAccessorTypes_topLevel);
       });
+      _ut.test('test_mixedReturnTypes_localFunction', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_mixedReturnTypes_localFunction);
+      });
+      _ut.test('test_mixedReturnTypes_method', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_mixedReturnTypes_method);
+      });
+      _ut.test('test_mixedReturnTypes_topLevelFunction', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_mixedReturnTypes_topLevelFunction);
+      });
       _ut.test('test_newWithAbstractClass', () {
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_newWithAbstractClass);
@@ -15427,10 +15912,6 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_method_optionalParamCount);
       });
-      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_setter_excluded', () {
-        final __test = new StaticWarningCodeTest();
-        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_setter_excluded);
-      });
       _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_setter_fromInterface', () {
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_setter_fromInterface);
@@ -15559,6 +16040,10 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_typeParameterReferencedByStatic_setter);
       });
+      _ut.test('test_typePromotion_functionType_arg_InterToDyn', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_typePromotion_functionType_arg_InterToDyn);
+      });
       _ut.test('test_typeTestNonType', () {
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_typeTestNonType);
@@ -15591,18 +16076,6 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_undefinedIdentifier_function_prefix);
       });
-      _ut.test('test_undefinedIdentifier_hideInBlock_function', () {
-        final __test = new StaticWarningCodeTest();
-        runJUnitTest(__test, __test.test_undefinedIdentifier_hideInBlock_function);
-      });
-      _ut.test('test_undefinedIdentifier_hideInBlock_local', () {
-        final __test = new StaticWarningCodeTest();
-        runJUnitTest(__test, __test.test_undefinedIdentifier_hideInBlock_local);
-      });
-      _ut.test('test_undefinedIdentifier_hideInBlock_subBlock', () {
-        final __test = new StaticWarningCodeTest();
-        runJUnitTest(__test, __test.test_undefinedIdentifier_hideInBlock_subBlock);
-      });
       _ut.test('test_undefinedIdentifier_initializer', () {
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_undefinedIdentifier_initializer);
@@ -17852,20 +18325,75 @@
     assertNoErrors(source);
     verify([source]);
   }
-  void test_unnecessaryCast_13855_parameter_A() {
+  void test_proxy_annotation_prefixed() {
     Source source = addSource(EngineTestCase.createSource([
-        "class A{",
-        "  a() {}",
-        "}",
-        "class B<E> {",
-        "  E e;",
-        "  m() {",
-        "    (e as A).a();",
-        "  }",
+        "library L;",
+        "import 'meta.dart';",
+        "@proxy",
+        "class A {}",
+        "f(var a) {",
+        "  a = new A();",
+        "  a.m();",
+        "  var x = a.g;",
+        "  a.s = 1;",
+        "  var y = a + a;",
+        "  a++;",
+        "  ++a;",
         "}"]));
+    addSource2("/meta.dart", EngineTestCase.createSource([
+        "library meta;",
+        "const proxy = const _Proxy();",
+        "class _Proxy { const _Proxy(); }"]));
     resolve(source);
     assertNoErrors(source);
-    verify([source]);
+  }
+  void test_proxy_annotation_prefixed2() {
+    Source source = addSource(EngineTestCase.createSource([
+        "library L;",
+        "import 'meta.dart';",
+        "@proxy",
+        "class A {}",
+        "class B {",
+        "  f(var a) {",
+        "    a = new A();",
+        "    a.m();",
+        "    var x = a.g;",
+        "    a.s = 1;",
+        "    var y = a + a;",
+        "    a++;",
+        "    ++a;",
+        "  }",
+        "}"]));
+    addSource2("/meta.dart", EngineTestCase.createSource([
+        "library meta;",
+        "const proxy = const _Proxy();",
+        "class _Proxy { const _Proxy(); }"]));
+    resolve(source);
+    assertNoErrors(source);
+  }
+  void test_proxy_annotation_prefixed3() {
+    Source source = addSource(EngineTestCase.createSource([
+        "library L;",
+        "import 'meta.dart';",
+        "class B {",
+        "  f(var a) {",
+        "    a = new A();",
+        "    a.m();",
+        "    var x = a.g;",
+        "    a.s = 1;",
+        "    var y = a + a;",
+        "    a++;",
+        "    ++a;",
+        "  }",
+        "}",
+        "@proxy",
+        "class A {}"]));
+    addSource2("/meta.dart", EngineTestCase.createSource([
+        "library meta;",
+        "const proxy = const _Proxy();",
+        "class _Proxy { const _Proxy(); }"]));
+    resolve(source);
+    assertNoErrors(source);
   }
   void test_undefinedGetter_inSubtype() {
     Source source = addSource(EngineTestCase.createSource([
@@ -18006,6 +18534,21 @@
     resolve(source);
     assertNoErrors(source);
   }
+  void test_unnecessaryCast_13855_parameter_A() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A{",
+        "  a() {}",
+        "}",
+        "class B<E> {",
+        "  E e;",
+        "  m() {",
+        "    (e as A).a();",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
   void test_unnecessaryCast_dynamic_type() {
     Source source = addSource(EngineTestCase.createSource(["m(v) {", "  var b = v as Object;", "}"]));
     resolve(source);
@@ -18151,6 +18694,18 @@
         final __test = new NonHintCodeTest();
         runJUnitTest(__test, __test.test_overrideEqualsButNotHashCode);
       });
+      _ut.test('test_proxy_annotation_prefixed', () {
+        final __test = new NonHintCodeTest();
+        runJUnitTest(__test, __test.test_proxy_annotation_prefixed);
+      });
+      _ut.test('test_proxy_annotation_prefixed2', () {
+        final __test = new NonHintCodeTest();
+        runJUnitTest(__test, __test.test_proxy_annotation_prefixed2);
+      });
+      _ut.test('test_proxy_annotation_prefixed3', () {
+        final __test = new NonHintCodeTest();
+        runJUnitTest(__test, __test.test_proxy_annotation_prefixed3);
+      });
       _ut.test('test_undefinedGetter_inSubtype', () {
         final __test = new NonHintCodeTest();
         runJUnitTest(__test, __test.test_undefinedGetter_inSubtype);
@@ -18234,7 +18789,7 @@
   void test_define_duplicate() {
     LibraryElement definingLibrary2 = createTestLibrary();
     GatheringErrorListener errorListener2 = new GatheringErrorListener();
-    Scope rootScope = new Scope_20(definingLibrary2, errorListener2);
+    Scope rootScope = new Scope_21(definingLibrary2, errorListener2);
     EnclosedScope scope = new EnclosedScope(rootScope);
     VariableElement element1 = ElementFactory.localVariableElement(ASTFactory.identifier3("v1"));
     VariableElement element2 = ElementFactory.localVariableElement(ASTFactory.identifier3("v1"));
@@ -18245,7 +18800,7 @@
   void test_define_normal() {
     LibraryElement definingLibrary3 = createTestLibrary();
     GatheringErrorListener errorListener3 = new GatheringErrorListener();
-    Scope rootScope = new Scope_21(definingLibrary3, errorListener3);
+    Scope rootScope = new Scope_22(definingLibrary3, errorListener3);
     EnclosedScope outerScope = new EnclosedScope(rootScope);
     EnclosedScope innerScope = new EnclosedScope(outerScope);
     VariableElement element1 = ElementFactory.localVariableElement(ASTFactory.identifier3("v1"));
@@ -18267,18 +18822,18 @@
     });
   }
 }
-class Scope_20 extends Scope {
+class Scope_21 extends Scope {
   LibraryElement definingLibrary2;
   GatheringErrorListener errorListener2;
-  Scope_20(this.definingLibrary2, this.errorListener2) : super();
+  Scope_21(this.definingLibrary2, this.errorListener2) : super();
   LibraryElement get definingLibrary => definingLibrary2;
   AnalysisErrorListener get errorListener => errorListener2;
   Element lookup3(Identifier identifier, String name, LibraryElement referencingLibrary) => null;
 }
-class Scope_21 extends Scope {
+class Scope_22 extends Scope {
   LibraryElement definingLibrary3;
   GatheringErrorListener errorListener3;
-  Scope_21(this.definingLibrary3, this.errorListener3) : super();
+  Scope_22(this.definingLibrary3, this.errorListener3) : super();
   LibraryElement get definingLibrary => definingLibrary3;
   AnalysisErrorListener get errorListener => errorListener3;
   Element lookup3(Identifier identifier, String name, LibraryElement referencingLibrary) => null;
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
new file mode 100644
index 0000000..1f830c6
--- /dev/null
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -0,0 +1,1740 @@
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+library engine.scanner_test;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_junit.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:unittest/unittest.dart' as _ut;
+import 'test_support.dart';
+class KeywordStateTest extends JUnitTestCase {
+  void test_KeywordState() {
+    List<Keyword> keywords = Keyword.values;
+    int keywordCount = keywords.length;
+    List<String> textToTest = new List<String>(keywordCount * 3);
+    for (int i = 0; i < keywordCount; i++) {
+      String syntax = keywords[i].syntax;
+      textToTest[i] = syntax;
+      textToTest[i + keywordCount] = "${syntax}x";
+      textToTest[i + keywordCount * 2] = syntax.substring(0, syntax.length - 1);
+    }
+    KeywordState firstState = KeywordState.KEYWORD_STATE;
+    for (int i = 0; i < textToTest.length; i++) {
+      String text = textToTest[i];
+      int index = 0;
+      int length = text.length;
+      KeywordState state = firstState;
+      while (index < length && state != null) {
+        state = state.next(text.codeUnitAt(index));
+        index++;
+      }
+      if (i < keywordCount) {
+        JUnitTestCase.assertNotNull(state);
+        JUnitTestCase.assertNotNull(state.keyword());
+        JUnitTestCase.assertEquals(keywords[i], state.keyword());
+      } else if (i < keywordCount * 2) {
+        JUnitTestCase.assertNull(state);
+      } else {
+        JUnitTestCase.assertNotNull(state);
+      }
+    }
+  }
+  static dartSuite() {
+    _ut.group('KeywordStateTest', () {
+      _ut.test('test_KeywordState', () {
+        final __test = new KeywordStateTest();
+        runJUnitTest(__test, __test.test_KeywordState);
+      });
+    });
+  }
+}
+class CharSequenceReaderTest extends JUnitTestCase {
+  void test_advance() {
+    CharSequenceReader reader = new CharSequenceReader(new CharSequence("x"));
+    JUnitTestCase.assertEquals(0x78, reader.advance());
+    JUnitTestCase.assertEquals(-1, reader.advance());
+    JUnitTestCase.assertEquals(-1, reader.advance());
+  }
+  void test_creation() {
+    JUnitTestCase.assertNotNull(new CharSequenceReader(new CharSequence("x")));
+  }
+  void test_getOffset() {
+    CharSequenceReader reader = new CharSequenceReader(new CharSequence("x"));
+    JUnitTestCase.assertEquals(-1, reader.offset);
+    reader.advance();
+    JUnitTestCase.assertEquals(0, reader.offset);
+    reader.advance();
+    JUnitTestCase.assertEquals(0, reader.offset);
+  }
+  void test_getString() {
+    CharSequenceReader reader = new CharSequenceReader(new CharSequence("xyzzy"));
+    reader.offset = 3;
+    JUnitTestCase.assertEquals("yzz", reader.getString(1, 0));
+    JUnitTestCase.assertEquals("zzy", reader.getString(2, 1));
+  }
+  void test_peek() {
+    CharSequenceReader reader = new CharSequenceReader(new CharSequence("xy"));
+    JUnitTestCase.assertEquals(0x78, reader.peek());
+    JUnitTestCase.assertEquals(0x78, reader.peek());
+    reader.advance();
+    JUnitTestCase.assertEquals(0x79, reader.peek());
+    JUnitTestCase.assertEquals(0x79, reader.peek());
+    reader.advance();
+    JUnitTestCase.assertEquals(-1, reader.peek());
+    JUnitTestCase.assertEquals(-1, reader.peek());
+  }
+  void test_setOffset() {
+    CharSequenceReader reader = new CharSequenceReader(new CharSequence("xyz"));
+    reader.offset = 2;
+    JUnitTestCase.assertEquals(2, reader.offset);
+  }
+  static dartSuite() {
+    _ut.group('CharSequenceReaderTest', () {
+      _ut.test('test_advance', () {
+        final __test = new CharSequenceReaderTest();
+        runJUnitTest(__test, __test.test_advance);
+      });
+      _ut.test('test_creation', () {
+        final __test = new CharSequenceReaderTest();
+        runJUnitTest(__test, __test.test_creation);
+      });
+      _ut.test('test_getOffset', () {
+        final __test = new CharSequenceReaderTest();
+        runJUnitTest(__test, __test.test_getOffset);
+      });
+      _ut.test('test_getString', () {
+        final __test = new CharSequenceReaderTest();
+        runJUnitTest(__test, __test.test_getString);
+      });
+      _ut.test('test_peek', () {
+        final __test = new CharSequenceReaderTest();
+        runJUnitTest(__test, __test.test_peek);
+      });
+      _ut.test('test_setOffset', () {
+        final __test = new CharSequenceReaderTest();
+        runJUnitTest(__test, __test.test_setOffset);
+      });
+    });
+  }
+}
+class TokenTypeTest extends EngineTestCase {
+  void test_isOperator() {
+    JUnitTestCase.assertTrue(TokenType.AMPERSAND.isOperator);
+    JUnitTestCase.assertTrue(TokenType.AMPERSAND_AMPERSAND.isOperator);
+    JUnitTestCase.assertTrue(TokenType.AMPERSAND_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.BANG.isOperator);
+    JUnitTestCase.assertTrue(TokenType.BANG_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.BAR.isOperator);
+    JUnitTestCase.assertTrue(TokenType.BAR_BAR.isOperator);
+    JUnitTestCase.assertTrue(TokenType.BAR_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.CARET.isOperator);
+    JUnitTestCase.assertTrue(TokenType.CARET_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.EQ_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.GT.isOperator);
+    JUnitTestCase.assertTrue(TokenType.GT_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.GT_GT.isOperator);
+    JUnitTestCase.assertTrue(TokenType.GT_GT_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.INDEX.isOperator);
+    JUnitTestCase.assertTrue(TokenType.INDEX_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.IS.isOperator);
+    JUnitTestCase.assertTrue(TokenType.LT.isOperator);
+    JUnitTestCase.assertTrue(TokenType.LT_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.LT_LT.isOperator);
+    JUnitTestCase.assertTrue(TokenType.LT_LT_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.MINUS.isOperator);
+    JUnitTestCase.assertTrue(TokenType.MINUS_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.MINUS_MINUS.isOperator);
+    JUnitTestCase.assertTrue(TokenType.PERCENT.isOperator);
+    JUnitTestCase.assertTrue(TokenType.PERCENT_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.PERIOD_PERIOD.isOperator);
+    JUnitTestCase.assertTrue(TokenType.PLUS.isOperator);
+    JUnitTestCase.assertTrue(TokenType.PLUS_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.PLUS_PLUS.isOperator);
+    JUnitTestCase.assertTrue(TokenType.QUESTION.isOperator);
+    JUnitTestCase.assertTrue(TokenType.SLASH.isOperator);
+    JUnitTestCase.assertTrue(TokenType.SLASH_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.STAR.isOperator);
+    JUnitTestCase.assertTrue(TokenType.STAR_EQ.isOperator);
+    JUnitTestCase.assertTrue(TokenType.TILDE.isOperator);
+    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH.isOperator);
+    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH_EQ.isOperator);
+  }
+  void test_isUserDefinableOperator() {
+    JUnitTestCase.assertTrue(TokenType.AMPERSAND.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.BAR.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.CARET.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.EQ_EQ.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.GT.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.GT_EQ.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.GT_GT.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.INDEX.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.INDEX_EQ.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.LT.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.LT_EQ.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.LT_LT.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.MINUS.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.PERCENT.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.PLUS.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.SLASH.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.STAR.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.TILDE.isUserDefinableOperator);
+    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH.isUserDefinableOperator);
+  }
+  static dartSuite() {
+    _ut.group('TokenTypeTest', () {
+      _ut.test('test_isOperator', () {
+        final __test = new TokenTypeTest();
+        runJUnitTest(__test, __test.test_isOperator);
+      });
+      _ut.test('test_isUserDefinableOperator', () {
+        final __test = new TokenTypeTest();
+        runJUnitTest(__test, __test.test_isUserDefinableOperator);
+      });
+    });
+  }
+}
+/**
+ * The class `TokenFactory` defines utility methods that can be used to create tokens.
+ */
+class TokenFactory {
+  static Token token(Keyword keyword) => new KeywordToken(keyword, 0);
+  static Token token2(String lexeme) => new StringToken(TokenType.STRING, lexeme, 0);
+  static Token token3(TokenType type) => new Token(type, 0);
+  static Token token4(TokenType type, String lexeme) => new StringToken(type, lexeme, 0);
+}
+/**
+ * Instances of the class `TokenStreamValidator` are used to validate the correct construction
+ * of a stream of tokens.
+ */
+class TokenStreamValidator {
+
+  /**
+   * Validate that the stream of tokens that starts with the given token is correct.
+   *
+   * @param token the first token in the stream of tokens to be validated
+   */
+  void validate(Token token) {
+    JavaStringBuilder builder = new JavaStringBuilder();
+    validateStream(builder, token);
+    if (builder.length > 0) {
+      JUnitTestCase.fail(builder.toString());
+    }
+  }
+  void validateStream(JavaStringBuilder builder, Token token) {
+    if (token == null) {
+      return;
+    }
+    Token previousToken = null;
+    int previousEnd = -1;
+    Token currentToken = token;
+    while (currentToken != null && currentToken.type != TokenType.EOF) {
+      validateStream(builder, currentToken.precedingComments);
+      TokenType type = currentToken.type;
+      if (identical(type, TokenType.OPEN_CURLY_BRACKET) || identical(type, TokenType.OPEN_PAREN) || identical(type, TokenType.OPEN_SQUARE_BRACKET) || identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
+        if (currentToken is! BeginToken) {
+          builder.append("\r\nExpected BeginToken, found ");
+          builder.append(currentToken.runtimeType.toString());
+          builder.append(" ");
+          writeToken(builder, currentToken);
+        }
+      }
+      int currentStart = currentToken.offset;
+      int currentLength = currentToken.length;
+      int currentEnd = currentStart + currentLength - 1;
+      if (currentStart <= previousEnd) {
+        builder.append("\r\nInvalid token sequence: ");
+        writeToken(builder, previousToken);
+        builder.append(" followed by ");
+        writeToken(builder, currentToken);
+      }
+      previousEnd = currentEnd;
+      previousToken = currentToken;
+      currentToken = currentToken.next;
+    }
+  }
+  void writeToken(JavaStringBuilder builder, Token token) {
+    builder.append("[");
+    builder.append(token.type);
+    builder.append(", '");
+    builder.append(token.lexeme);
+    builder.append("', ");
+    builder.append(token.offset);
+    builder.append(", ");
+    builder.append(token.length);
+    builder.append("]");
+  }
+}
+class ScannerTest extends JUnitTestCase {
+  void test_ampersand() {
+    assertToken(TokenType.AMPERSAND, "&");
+  }
+  void test_ampersand_ampersand() {
+    assertToken(TokenType.AMPERSAND_AMPERSAND, "&&");
+  }
+  void test_ampersand_eq() {
+    assertToken(TokenType.AMPERSAND_EQ, "&=");
+  }
+  void test_at() {
+    assertToken(TokenType.AT, "@");
+  }
+  void test_backping() {
+    assertToken(TokenType.BACKPING, "`");
+  }
+  void test_backslash() {
+    assertToken(TokenType.BACKSLASH, "\\");
+  }
+  void test_bang() {
+    assertToken(TokenType.BANG, "!");
+  }
+  void test_bang_eq() {
+    assertToken(TokenType.BANG_EQ, "!=");
+  }
+  void test_bar() {
+    assertToken(TokenType.BAR, "|");
+  }
+  void test_bar_bar() {
+    assertToken(TokenType.BAR_BAR, "||");
+  }
+  void test_bar_eq() {
+    assertToken(TokenType.BAR_EQ, "|=");
+  }
+  void test_caret() {
+    assertToken(TokenType.CARET, "^");
+  }
+  void test_caret_eq() {
+    assertToken(TokenType.CARET_EQ, "^=");
+  }
+  void test_close_curly_bracket() {
+    assertToken(TokenType.CLOSE_CURLY_BRACKET, "}");
+  }
+  void test_close_paren() {
+    assertToken(TokenType.CLOSE_PAREN, ")");
+  }
+  void test_close_quare_bracket() {
+    assertToken(TokenType.CLOSE_SQUARE_BRACKET, "]");
+  }
+  void test_colon() {
+    assertToken(TokenType.COLON, ":");
+  }
+  void test_comma() {
+    assertToken(TokenType.COMMA, ",");
+  }
+  void test_comment_multi() {
+    assertComment(TokenType.MULTI_LINE_COMMENT, "/* comment */");
+  }
+  void test_comment_multi_unterminated() {
+    assertError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, 3, "/* x");
+  }
+  void test_comment_nested() {
+    assertComment(TokenType.MULTI_LINE_COMMENT, "/* comment /* within a */ comment */");
+  }
+  void test_comment_single() {
+    assertComment(TokenType.SINGLE_LINE_COMMENT, "// comment");
+  }
+  void test_double_both_e() {
+    assertToken(TokenType.DOUBLE, "0.123e4");
+  }
+  void test_double_both_E() {
+    assertToken(TokenType.DOUBLE, "0.123E4");
+  }
+  void test_double_fraction() {
+    assertToken(TokenType.DOUBLE, ".123");
+  }
+  void test_double_fraction_e() {
+    assertToken(TokenType.DOUBLE, ".123e4");
+  }
+  void test_double_fraction_E() {
+    assertToken(TokenType.DOUBLE, ".123E4");
+  }
+  void test_double_missingDigitInExponent() {
+    assertError(ScannerErrorCode.MISSING_DIGIT, 1, "1e");
+  }
+  void test_double_whole_e() {
+    assertToken(TokenType.DOUBLE, "12e4");
+  }
+  void test_double_whole_E() {
+    assertToken(TokenType.DOUBLE, "12E4");
+  }
+  void test_eq() {
+    assertToken(TokenType.EQ, "=");
+  }
+  void test_eq_eq() {
+    assertToken(TokenType.EQ_EQ, "==");
+  }
+  void test_gt() {
+    assertToken(TokenType.GT, ">");
+  }
+  void test_gt_eq() {
+    assertToken(TokenType.GT_EQ, ">=");
+  }
+  void test_gt_gt() {
+    assertToken(TokenType.GT_GT, ">>");
+  }
+  void test_gt_gt_eq() {
+    assertToken(TokenType.GT_GT_EQ, ">>=");
+  }
+  void test_hash() {
+    assertToken(TokenType.HASH, "#");
+  }
+  void test_hexidecimal() {
+    assertToken(TokenType.HEXADECIMAL, "0x1A2B3C");
+  }
+  void test_hexidecimal_missingDigit() {
+    assertError(ScannerErrorCode.MISSING_HEX_DIGIT, 1, "0x");
+  }
+  void test_identifier() {
+    assertToken(TokenType.IDENTIFIER, "result");
+  }
+  void test_illegalChar_cyrillicLetter_middle() {
+    assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 0, "Shche\u0433lov");
+  }
+  void test_illegalChar_cyrillicLetter_start() {
+    assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 0, "\u0429");
+  }
+  void test_illegalChar_nbsp() {
+    assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 0, "\u00A0");
+  }
+  void test_illegalChar_notLetter() {
+    assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 0, "\u0312");
+  }
+  void test_index() {
+    assertToken(TokenType.INDEX, "[]");
+  }
+  void test_index_eq() {
+    assertToken(TokenType.INDEX_EQ, "[]=");
+  }
+  void test_int() {
+    assertToken(TokenType.INT, "123");
+  }
+  void test_int_initialZero() {
+    assertToken(TokenType.INT, "0123");
+  }
+  void test_keyword_abstract() {
+    assertKeywordToken("abstract");
+  }
+  void test_keyword_as() {
+    assertKeywordToken("as");
+  }
+  void test_keyword_assert() {
+    assertKeywordToken("assert");
+  }
+  void test_keyword_break() {
+    assertKeywordToken("break");
+  }
+  void test_keyword_case() {
+    assertKeywordToken("case");
+  }
+  void test_keyword_catch() {
+    assertKeywordToken("catch");
+  }
+  void test_keyword_class() {
+    assertKeywordToken("class");
+  }
+  void test_keyword_const() {
+    assertKeywordToken("const");
+  }
+  void test_keyword_continue() {
+    assertKeywordToken("continue");
+  }
+  void test_keyword_default() {
+    assertKeywordToken("default");
+  }
+  void test_keyword_do() {
+    assertKeywordToken("do");
+  }
+  void test_keyword_dynamic() {
+    assertKeywordToken("dynamic");
+  }
+  void test_keyword_else() {
+    assertKeywordToken("else");
+  }
+  void test_keyword_enum() {
+    assertKeywordToken("enum");
+  }
+  void test_keyword_export() {
+    assertKeywordToken("export");
+  }
+  void test_keyword_extends() {
+    assertKeywordToken("extends");
+  }
+  void test_keyword_factory() {
+    assertKeywordToken("factory");
+  }
+  void test_keyword_false() {
+    assertKeywordToken("false");
+  }
+  void test_keyword_final() {
+    assertKeywordToken("final");
+  }
+  void test_keyword_finally() {
+    assertKeywordToken("finally");
+  }
+  void test_keyword_for() {
+    assertKeywordToken("for");
+  }
+  void test_keyword_get() {
+    assertKeywordToken("get");
+  }
+  void test_keyword_if() {
+    assertKeywordToken("if");
+  }
+  void test_keyword_implements() {
+    assertKeywordToken("implements");
+  }
+  void test_keyword_import() {
+    assertKeywordToken("import");
+  }
+  void test_keyword_in() {
+    assertKeywordToken("in");
+  }
+  void test_keyword_is() {
+    assertKeywordToken("is");
+  }
+  void test_keyword_library() {
+    assertKeywordToken("library");
+  }
+  void test_keyword_new() {
+    assertKeywordToken("new");
+  }
+  void test_keyword_null() {
+    assertKeywordToken("null");
+  }
+  void test_keyword_operator() {
+    assertKeywordToken("operator");
+  }
+  void test_keyword_part() {
+    assertKeywordToken("part");
+  }
+  void test_keyword_rethrow() {
+    assertKeywordToken("rethrow");
+  }
+  void test_keyword_return() {
+    assertKeywordToken("return");
+  }
+  void test_keyword_set() {
+    assertKeywordToken("set");
+  }
+  void test_keyword_static() {
+    assertKeywordToken("static");
+  }
+  void test_keyword_super() {
+    assertKeywordToken("super");
+  }
+  void test_keyword_switch() {
+    assertKeywordToken("switch");
+  }
+  void test_keyword_this() {
+    assertKeywordToken("this");
+  }
+  void test_keyword_throw() {
+    assertKeywordToken("throw");
+  }
+  void test_keyword_true() {
+    assertKeywordToken("true");
+  }
+  void test_keyword_try() {
+    assertKeywordToken("try");
+  }
+  void test_keyword_typedef() {
+    assertKeywordToken("typedef");
+  }
+  void test_keyword_var() {
+    assertKeywordToken("var");
+  }
+  void test_keyword_void() {
+    assertKeywordToken("void");
+  }
+  void test_keyword_while() {
+    assertKeywordToken("while");
+  }
+  void test_keyword_with() {
+    assertKeywordToken("with");
+  }
+  void test_lineInfo_multilineComment() {
+    String source = "/*\r *\r */";
+    assertLineInfo(source, [
+        new ScannerTest_ExpectedLocation(0, 1, 1),
+        new ScannerTest_ExpectedLocation(4, 2, 2),
+        new ScannerTest_ExpectedLocation(source.length - 1, 3, 3)]);
+  }
+  void test_lineInfo_multilineString() {
+    String source = "'''a\r\nbc\r\nd'''";
+    assertLineInfo(source, [
+        new ScannerTest_ExpectedLocation(0, 1, 1),
+        new ScannerTest_ExpectedLocation(7, 2, 2),
+        new ScannerTest_ExpectedLocation(source.length - 1, 3, 4)]);
+  }
+  void test_lineInfo_simpleClass() {
+    String source = "class Test {\r\n    String s = '...';\r\n    int get x => s.MISSING_GETTER;\r\n}";
+    assertLineInfo(source, [
+        new ScannerTest_ExpectedLocation(0, 1, 1),
+        new ScannerTest_ExpectedLocation(source.indexOf("MISSING_GETTER"), 3, 20),
+        new ScannerTest_ExpectedLocation(source.length - 1, 4, 1)]);
+  }
+  void test_lineInfo_slashN() {
+    String source = "class Test {\n}";
+    assertLineInfo(source, [
+        new ScannerTest_ExpectedLocation(0, 1, 1),
+        new ScannerTest_ExpectedLocation(source.indexOf("}"), 2, 1)]);
+  }
+  void test_lt() {
+    assertToken(TokenType.LT, "<");
+  }
+  void test_lt_eq() {
+    assertToken(TokenType.LT_EQ, "<=");
+  }
+  void test_lt_lt() {
+    assertToken(TokenType.LT_LT, "<<");
+  }
+  void test_lt_lt_eq() {
+    assertToken(TokenType.LT_LT_EQ, "<<=");
+  }
+  void test_minus() {
+    assertToken(TokenType.MINUS, "-");
+  }
+  void test_minus_eq() {
+    assertToken(TokenType.MINUS_EQ, "-=");
+  }
+  void test_minus_minus() {
+    assertToken(TokenType.MINUS_MINUS, "--");
+  }
+  void test_open_curly_bracket() {
+    assertToken(TokenType.OPEN_CURLY_BRACKET, "{");
+  }
+  void test_open_paren() {
+    assertToken(TokenType.OPEN_PAREN, "(");
+  }
+  void test_open_square_bracket() {
+    assertToken(TokenType.OPEN_SQUARE_BRACKET, "[");
+  }
+  void test_openSquareBracket() {
+    assertToken(TokenType.OPEN_SQUARE_BRACKET, "[");
+  }
+  void test_percent() {
+    assertToken(TokenType.PERCENT, "%");
+  }
+  void test_percent_eq() {
+    assertToken(TokenType.PERCENT_EQ, "%=");
+  }
+  void test_period() {
+    assertToken(TokenType.PERIOD, ".");
+  }
+  void test_period_period() {
+    assertToken(TokenType.PERIOD_PERIOD, "..");
+  }
+  void test_period_period_period() {
+    assertToken(TokenType.PERIOD_PERIOD_PERIOD, "...");
+  }
+  void test_periodAfterNumberNotIncluded_identifier() {
+    assertTokens("42.isEven()", [
+        new StringToken(TokenType.INT, "42", 0),
+        new Token(TokenType.PERIOD, 2),
+        new StringToken(TokenType.IDENTIFIER, "isEven", 3),
+        new Token(TokenType.OPEN_PAREN, 9),
+        new Token(TokenType.CLOSE_PAREN, 10)]);
+  }
+  void test_periodAfterNumberNotIncluded_period() {
+    assertTokens("42..isEven()", [
+        new StringToken(TokenType.INT, "42", 0),
+        new Token(TokenType.PERIOD_PERIOD, 2),
+        new StringToken(TokenType.IDENTIFIER, "isEven", 4),
+        new Token(TokenType.OPEN_PAREN, 10),
+        new Token(TokenType.CLOSE_PAREN, 11)]);
+  }
+  void test_plus() {
+    assertToken(TokenType.PLUS, "+");
+  }
+  void test_plus_eq() {
+    assertToken(TokenType.PLUS_EQ, "+=");
+  }
+  void test_plus_plus() {
+    assertToken(TokenType.PLUS_PLUS, "++");
+  }
+  void test_question() {
+    assertToken(TokenType.QUESTION, "?");
+  }
+  void test_scriptTag_withArgs() {
+    assertToken(TokenType.SCRIPT_TAG, "#!/bin/dart -debug");
+  }
+  void test_scriptTag_withoutSpace() {
+    assertToken(TokenType.SCRIPT_TAG, "#!/bin/dart");
+  }
+  void test_scriptTag_withSpace() {
+    assertToken(TokenType.SCRIPT_TAG, "#! /bin/dart");
+  }
+  void test_semicolon() {
+    assertToken(TokenType.SEMICOLON, ";");
+  }
+  void test_setSourceStart() {
+    int offsetDelta = 42;
+    GatheringErrorListener listener = new GatheringErrorListener();
+    Scanner scanner = new Scanner(null, new SubSequenceReader(new CharSequence("a"), offsetDelta), listener);
+    scanner.setSourceStart(3, 9);
+    scanner.tokenize();
+    List<int> lineStarts = scanner.lineStarts;
+    JUnitTestCase.assertNotNull(lineStarts);
+    JUnitTestCase.assertEquals(3, lineStarts.length);
+    JUnitTestCase.assertEquals(33, lineStarts[2]);
+  }
+  void test_slash() {
+    assertToken(TokenType.SLASH, "/");
+  }
+  void test_slash_eq() {
+    assertToken(TokenType.SLASH_EQ, "/=");
+  }
+  void test_star() {
+    assertToken(TokenType.STAR, "*");
+  }
+  void test_star_eq() {
+    assertToken(TokenType.STAR_EQ, "*=");
+  }
+  void test_startAndEnd() {
+    Token token = scan("a");
+    Token previous = token.previous;
+    JUnitTestCase.assertEquals(token, previous.next);
+    JUnitTestCase.assertEquals(previous, previous.previous);
+    Token next = token.next;
+    JUnitTestCase.assertEquals(next, next.next);
+    JUnitTestCase.assertEquals(token, next.previous);
+  }
+  void test_string_multi_double() {
+    assertToken(TokenType.STRING, "\"\"\"line1\nline2\"\"\"");
+  }
+  void test_string_multi_embeddedQuotes() {
+    assertToken(TokenType.STRING, "\"\"\"line1\n\"\"\nline2\"\"\"");
+  }
+  void test_string_multi_embeddedQuotes_escapedChar() {
+    assertToken(TokenType.STRING, "\"\"\"a\"\"\\tb\"\"\"");
+  }
+  void test_string_multi_interpolation_block() {
+    assertTokens("\"Hello \${name}!\"", [
+        new StringToken(TokenType.STRING, "\"Hello ", 0),
+        new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 7),
+        new StringToken(TokenType.IDENTIFIER, "name", 9),
+        new Token(TokenType.CLOSE_CURLY_BRACKET, 13),
+        new StringToken(TokenType.STRING, "!\"", 14)]);
+  }
+  void test_string_multi_interpolation_identifier() {
+    assertTokens("\"Hello \$name!\"", [
+        new StringToken(TokenType.STRING, "\"Hello ", 0),
+        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 7),
+        new StringToken(TokenType.IDENTIFIER, "name", 8),
+        new StringToken(TokenType.STRING, "!\"", 12)]);
+  }
+  void test_string_multi_single() {
+    assertToken(TokenType.STRING, "'''string'''");
+  }
+  void test_string_multi_slashEnter() {
+    assertError(ScannerErrorCode.CHARACTER_EXPECTED_AFTER_SLASH, 0, "'''\\\n'''");
+  }
+  void test_string_multi_unterminated() {
+    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 8, "'''string");
+  }
+  void test_string_raw_multi_double() {
+    assertToken(TokenType.STRING, "r\"\"\"line1\nline2\"\"\"");
+  }
+  void test_string_raw_multi_single() {
+    assertToken(TokenType.STRING, "r'''string'''");
+  }
+  void test_string_raw_multi_unterminated() {
+    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 9, "r'''string");
+  }
+  void test_string_raw_simple_double() {
+    assertToken(TokenType.STRING, "r\"string\"");
+  }
+  void test_string_raw_simple_single() {
+    assertToken(TokenType.STRING, "r'string'");
+  }
+  void test_string_raw_simple_unterminated_eof() {
+    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 7, "r'string");
+  }
+  void test_string_raw_simple_unterminated_eol() {
+    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 8, "r'string\n");
+  }
+  void test_string_simple_double() {
+    assertToken(TokenType.STRING, "\"string\"");
+  }
+  void test_string_simple_escapedDollar() {
+    assertToken(TokenType.STRING, "'a\\\$b'");
+  }
+  void test_string_simple_interpolation_adjacentIdentifiers() {
+    assertTokens("'\$a\$b'", [
+        new StringToken(TokenType.STRING, "'", 0),
+        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1),
+        new StringToken(TokenType.IDENTIFIER, "a", 2),
+        new StringToken(TokenType.STRING, "", 3),
+        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 3),
+        new StringToken(TokenType.IDENTIFIER, "b", 4),
+        new StringToken(TokenType.STRING, "'", 5)]);
+  }
+  void test_string_simple_interpolation_block() {
+    assertTokens("'Hello \${name}!'", [
+        new StringToken(TokenType.STRING, "'Hello ", 0),
+        new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 7),
+        new StringToken(TokenType.IDENTIFIER, "name", 9),
+        new Token(TokenType.CLOSE_CURLY_BRACKET, 13),
+        new StringToken(TokenType.STRING, "!'", 14)]);
+  }
+  void test_string_simple_interpolation_blockWithNestedMap() {
+    assertTokens("'a \${f({'b' : 'c'})} d'", [
+        new StringToken(TokenType.STRING, "'a ", 0),
+        new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 3),
+        new StringToken(TokenType.IDENTIFIER, "f", 5),
+        new Token(TokenType.OPEN_PAREN, 6),
+        new Token(TokenType.OPEN_CURLY_BRACKET, 7),
+        new StringToken(TokenType.STRING, "'b'", 8),
+        new Token(TokenType.COLON, 12),
+        new StringToken(TokenType.STRING, "'c'", 14),
+        new Token(TokenType.CLOSE_CURLY_BRACKET, 17),
+        new Token(TokenType.CLOSE_PAREN, 18),
+        new Token(TokenType.CLOSE_CURLY_BRACKET, 19),
+        new StringToken(TokenType.STRING, " d'", 20)]);
+  }
+  void test_string_simple_interpolation_firstAndLast() {
+    assertTokens("'\$greeting \$name'", [
+        new StringToken(TokenType.STRING, "'", 0),
+        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1),
+        new StringToken(TokenType.IDENTIFIER, "greeting", 2),
+        new StringToken(TokenType.STRING, " ", 10),
+        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 11),
+        new StringToken(TokenType.IDENTIFIER, "name", 12),
+        new StringToken(TokenType.STRING, "'", 16)]);
+  }
+  void test_string_simple_interpolation_identifier() {
+    assertTokens("'Hello \$name!'", [
+        new StringToken(TokenType.STRING, "'Hello ", 0),
+        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 7),
+        new StringToken(TokenType.IDENTIFIER, "name", 8),
+        new StringToken(TokenType.STRING, "!'", 12)]);
+  }
+  void test_string_simple_interpolation_missingIdentifier() {
+    assertTokens("'\$x\$'", [
+        new StringToken(TokenType.STRING, "'", 0),
+        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1),
+        new StringToken(TokenType.IDENTIFIER, "x", 2),
+        new StringToken(TokenType.STRING, "", 3),
+        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 3),
+        new StringToken(TokenType.STRING, "'", 4)]);
+  }
+  void test_string_simple_interpolation_nonIdentifier() {
+    assertTokens("'\$1'", [
+        new StringToken(TokenType.STRING, "'", 0),
+        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1),
+        new StringToken(TokenType.STRING, "1'", 2)]);
+  }
+  void test_string_simple_single() {
+    assertToken(TokenType.STRING, "'string'");
+  }
+  void test_string_simple_unterminated_eof() {
+    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 6, "'string");
+  }
+  void test_string_simple_unterminated_eol() {
+    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 7, "'string\r");
+  }
+  void test_tilde() {
+    assertToken(TokenType.TILDE, "~");
+  }
+  void test_tilde_slash() {
+    assertToken(TokenType.TILDE_SLASH, "~/");
+  }
+  void test_tilde_slash_eq() {
+    assertToken(TokenType.TILDE_SLASH_EQ, "~/=");
+  }
+  void test_unclosedPairInInterpolation() {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    scan2("'\${(}'", listener);
+  }
+  void assertComment(TokenType commentType, String source) {
+    Token token = scan(source);
+    JUnitTestCase.assertNotNull(token);
+    JUnitTestCase.assertEquals(TokenType.EOF, token.type);
+    Token comment = token.precedingComments;
+    JUnitTestCase.assertNotNull(comment);
+    JUnitTestCase.assertEquals(commentType, comment.type);
+    JUnitTestCase.assertEquals(0, comment.offset);
+    JUnitTestCase.assertEquals(source.length, comment.length);
+    JUnitTestCase.assertEquals(source, comment.lexeme);
+    token = scan("${source}\n");
+    JUnitTestCase.assertNotNull(token);
+    JUnitTestCase.assertEquals(TokenType.EOF, token.type);
+    comment = token.precedingComments;
+    JUnitTestCase.assertNotNull(comment);
+    JUnitTestCase.assertEquals(commentType, comment.type);
+    JUnitTestCase.assertEquals(0, comment.offset);
+    JUnitTestCase.assertEquals(source.length, comment.length);
+    JUnitTestCase.assertEquals(source, comment.lexeme);
+  }
+
+  /**
+   * Assert that scanning the given source produces an error with the given code.
+   *
+   * @param illegalCharacter
+   * @param i
+   * @param source the source to be scanned to produce the error
+   */
+  void assertError(ScannerErrorCode expectedError, int expectedOffset, String source) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    scan2(source, listener);
+    listener.assertErrors([new AnalysisError.con2(null, expectedOffset, 1, expectedError, [source.codeUnitAt(expectedOffset) as int])]);
+  }
+
+  /**
+   * Assert that when scanned the given source contains a single keyword token with the same lexeme
+   * as the original source.
+   *
+   * @param source the source to be scanned
+   */
+  void assertKeywordToken(String source) {
+    Token token = scan(source);
+    JUnitTestCase.assertNotNull(token);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, token.type);
+    JUnitTestCase.assertEquals(0, token.offset);
+    JUnitTestCase.assertEquals(source.length, token.length);
+    JUnitTestCase.assertEquals(source, token.lexeme);
+    Object value = token.value();
+    JUnitTestCase.assertTrue(value is Keyword);
+    JUnitTestCase.assertEquals(source, ((value as Keyword)).syntax);
+    token = scan(" ${source} ");
+    JUnitTestCase.assertNotNull(token);
+    JUnitTestCase.assertEquals(TokenType.KEYWORD, token.type);
+    JUnitTestCase.assertEquals(1, token.offset);
+    JUnitTestCase.assertEquals(source.length, token.length);
+    JUnitTestCase.assertEquals(source, token.lexeme);
+    value = token.value();
+    JUnitTestCase.assertTrue(value is Keyword);
+    JUnitTestCase.assertEquals(source, ((value as Keyword)).syntax);
+    JUnitTestCase.assertEquals(TokenType.EOF, token.next.type);
+  }
+  void assertLineInfo(String source, List<ScannerTest_ExpectedLocation> expectedLocations) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    scan2(source, listener);
+    listener.assertNoErrors();
+    LineInfo info = listener.getLineInfo(new TestSource());
+    JUnitTestCase.assertNotNull(info);
+    for (ScannerTest_ExpectedLocation expectedLocation in expectedLocations) {
+      LineInfo_Location location = info.getLocation(expectedLocation._offset);
+      JUnitTestCase.assertEquals(expectedLocation._lineNumber, location.lineNumber);
+      JUnitTestCase.assertEquals(expectedLocation._columnNumber, location.columnNumber);
+    }
+  }
+
+  /**
+   * Assert that the token scanned from the given source has the expected type.
+   *
+   * @param expectedType the expected type of the token
+   * @param source the source to be scanned to produce the actual token
+   */
+  Token assertToken(TokenType expectedType, String source) {
+    Token originalToken = scan(source);
+    JUnitTestCase.assertNotNull(originalToken);
+    JUnitTestCase.assertEquals(expectedType, originalToken.type);
+    JUnitTestCase.assertEquals(0, originalToken.offset);
+    JUnitTestCase.assertEquals(source.length, originalToken.length);
+    JUnitTestCase.assertEquals(source, originalToken.lexeme);
+    if (identical(expectedType, TokenType.SCRIPT_TAG)) {
+      return originalToken;
+    } else if (identical(expectedType, TokenType.SINGLE_LINE_COMMENT)) {
+      Token tokenWithSpaces = scan(" ${source}");
+      JUnitTestCase.assertNotNull(tokenWithSpaces);
+      JUnitTestCase.assertEquals(expectedType, tokenWithSpaces.type);
+      JUnitTestCase.assertEquals(1, tokenWithSpaces.offset);
+      JUnitTestCase.assertEquals(source.length, tokenWithSpaces.length);
+      JUnitTestCase.assertEquals(source, tokenWithSpaces.lexeme);
+      return originalToken;
+    } else if (identical(expectedType, TokenType.INT) || identical(expectedType, TokenType.DOUBLE)) {
+      Token tokenWithLowerD = scan("${source}d");
+      JUnitTestCase.assertNotNull(tokenWithLowerD);
+      JUnitTestCase.assertEquals(expectedType, tokenWithLowerD.type);
+      JUnitTestCase.assertEquals(0, tokenWithLowerD.offset);
+      JUnitTestCase.assertEquals(source.length, tokenWithLowerD.length);
+      JUnitTestCase.assertEquals(source, tokenWithLowerD.lexeme);
+      Token tokenWithUpperD = scan("${source}D");
+      JUnitTestCase.assertNotNull(tokenWithUpperD);
+      JUnitTestCase.assertEquals(expectedType, tokenWithUpperD.type);
+      JUnitTestCase.assertEquals(0, tokenWithUpperD.offset);
+      JUnitTestCase.assertEquals(source.length, tokenWithUpperD.length);
+      JUnitTestCase.assertEquals(source, tokenWithUpperD.lexeme);
+    }
+    Token tokenWithSpaces = scan(" ${source} ");
+    JUnitTestCase.assertNotNull(tokenWithSpaces);
+    JUnitTestCase.assertEquals(expectedType, tokenWithSpaces.type);
+    JUnitTestCase.assertEquals(1, tokenWithSpaces.offset);
+    JUnitTestCase.assertEquals(source.length, tokenWithSpaces.length);
+    JUnitTestCase.assertEquals(source, tokenWithSpaces.lexeme);
+    JUnitTestCase.assertEquals(TokenType.EOF, originalToken.next.type);
+    return originalToken;
+  }
+
+  /**
+   * Assert that when scanned the given source contains a sequence of tokens identical to the given
+   * tokens.
+   *
+   * @param source the source to be scanned
+   * @param expectedTokens the tokens that are expected to be in the source
+   */
+  void assertTokens(String source, List<Token> expectedTokens) {
+    Token token = scan(source);
+    JUnitTestCase.assertNotNull(token);
+    for (int i = 0; i < expectedTokens.length; i++) {
+      Token expectedToken = expectedTokens[i];
+      JUnitTestCase.assertEqualsMsg("Wrong type for token ${i}", expectedToken.type, token.type);
+      JUnitTestCase.assertEqualsMsg("Wrong offset for token ${i}", expectedToken.offset, token.offset);
+      JUnitTestCase.assertEqualsMsg("Wrong length for token ${i}", expectedToken.length, token.length);
+      JUnitTestCase.assertEqualsMsg("Wrong lexeme for token ${i}", expectedToken.lexeme, token.lexeme);
+      token = token.next;
+      JUnitTestCase.assertNotNull(token);
+    }
+    JUnitTestCase.assertEquals(TokenType.EOF, token.type);
+  }
+  Token scan(String source) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    Token token = scan2(source, listener);
+    listener.assertNoErrors();
+    return token;
+  }
+  Token scan2(String source, GatheringErrorListener listener) {
+    Scanner scanner = new Scanner(null, new CharSequenceReader(new CharSequence(source)), listener);
+    Token result = scanner.tokenize();
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    return result;
+  }
+  static dartSuite() {
+    _ut.group('ScannerTest', () {
+      _ut.test('test_ampersand', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_ampersand);
+      });
+      _ut.test('test_ampersand_ampersand', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_ampersand_ampersand);
+      });
+      _ut.test('test_ampersand_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_ampersand_eq);
+      });
+      _ut.test('test_at', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_at);
+      });
+      _ut.test('test_backping', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_backping);
+      });
+      _ut.test('test_backslash', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_backslash);
+      });
+      _ut.test('test_bang', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_bang);
+      });
+      _ut.test('test_bang_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_bang_eq);
+      });
+      _ut.test('test_bar', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_bar);
+      });
+      _ut.test('test_bar_bar', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_bar_bar);
+      });
+      _ut.test('test_bar_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_bar_eq);
+      });
+      _ut.test('test_caret', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_caret);
+      });
+      _ut.test('test_caret_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_caret_eq);
+      });
+      _ut.test('test_close_curly_bracket', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_close_curly_bracket);
+      });
+      _ut.test('test_close_paren', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_close_paren);
+      });
+      _ut.test('test_close_quare_bracket', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_close_quare_bracket);
+      });
+      _ut.test('test_colon', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_colon);
+      });
+      _ut.test('test_comma', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_comma);
+      });
+      _ut.test('test_comment_multi', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_comment_multi);
+      });
+      _ut.test('test_comment_multi_unterminated', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_comment_multi_unterminated);
+      });
+      _ut.test('test_comment_nested', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_comment_nested);
+      });
+      _ut.test('test_comment_single', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_comment_single);
+      });
+      _ut.test('test_double_both_E', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_double_both_E);
+      });
+      _ut.test('test_double_both_e', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_double_both_e);
+      });
+      _ut.test('test_double_fraction', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction);
+      });
+      _ut.test('test_double_fraction_E', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_E);
+      });
+      _ut.test('test_double_fraction_e', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_double_fraction_e);
+      });
+      _ut.test('test_double_missingDigitInExponent', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_double_missingDigitInExponent);
+      });
+      _ut.test('test_double_whole_E', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_E);
+      });
+      _ut.test('test_double_whole_e', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_double_whole_e);
+      });
+      _ut.test('test_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_eq);
+      });
+      _ut.test('test_eq_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_eq_eq);
+      });
+      _ut.test('test_gt', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_gt);
+      });
+      _ut.test('test_gt_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_gt_eq);
+      });
+      _ut.test('test_gt_gt', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_gt_gt);
+      });
+      _ut.test('test_gt_gt_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_gt_gt_eq);
+      });
+      _ut.test('test_hash', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_hash);
+      });
+      _ut.test('test_hexidecimal', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_hexidecimal);
+      });
+      _ut.test('test_hexidecimal_missingDigit', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_hexidecimal_missingDigit);
+      });
+      _ut.test('test_identifier', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_identifier);
+      });
+      _ut.test('test_illegalChar_cyrillicLetter_middle', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_illegalChar_cyrillicLetter_middle);
+      });
+      _ut.test('test_illegalChar_cyrillicLetter_start', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_illegalChar_cyrillicLetter_start);
+      });
+      _ut.test('test_illegalChar_nbsp', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_illegalChar_nbsp);
+      });
+      _ut.test('test_illegalChar_notLetter', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_illegalChar_notLetter);
+      });
+      _ut.test('test_index', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_index);
+      });
+      _ut.test('test_index_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_index_eq);
+      });
+      _ut.test('test_int', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_int);
+      });
+      _ut.test('test_int_initialZero', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_int_initialZero);
+      });
+      _ut.test('test_keyword_abstract', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_abstract);
+      });
+      _ut.test('test_keyword_as', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_as);
+      });
+      _ut.test('test_keyword_assert', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_assert);
+      });
+      _ut.test('test_keyword_break', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_break);
+      });
+      _ut.test('test_keyword_case', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_case);
+      });
+      _ut.test('test_keyword_catch', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_catch);
+      });
+      _ut.test('test_keyword_class', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_class);
+      });
+      _ut.test('test_keyword_const', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_const);
+      });
+      _ut.test('test_keyword_continue', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_continue);
+      });
+      _ut.test('test_keyword_default', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_default);
+      });
+      _ut.test('test_keyword_do', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_do);
+      });
+      _ut.test('test_keyword_dynamic', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_dynamic);
+      });
+      _ut.test('test_keyword_else', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_else);
+      });
+      _ut.test('test_keyword_enum', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_enum);
+      });
+      _ut.test('test_keyword_export', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_export);
+      });
+      _ut.test('test_keyword_extends', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_extends);
+      });
+      _ut.test('test_keyword_factory', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_factory);
+      });
+      _ut.test('test_keyword_false', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_false);
+      });
+      _ut.test('test_keyword_final', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_final);
+      });
+      _ut.test('test_keyword_finally', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_finally);
+      });
+      _ut.test('test_keyword_for', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_for);
+      });
+      _ut.test('test_keyword_get', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_get);
+      });
+      _ut.test('test_keyword_if', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_if);
+      });
+      _ut.test('test_keyword_implements', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_implements);
+      });
+      _ut.test('test_keyword_import', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_import);
+      });
+      _ut.test('test_keyword_in', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_in);
+      });
+      _ut.test('test_keyword_is', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_is);
+      });
+      _ut.test('test_keyword_library', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_library);
+      });
+      _ut.test('test_keyword_new', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_new);
+      });
+      _ut.test('test_keyword_null', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_null);
+      });
+      _ut.test('test_keyword_operator', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_operator);
+      });
+      _ut.test('test_keyword_part', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_part);
+      });
+      _ut.test('test_keyword_rethrow', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_rethrow);
+      });
+      _ut.test('test_keyword_return', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_return);
+      });
+      _ut.test('test_keyword_set', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_set);
+      });
+      _ut.test('test_keyword_static', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_static);
+      });
+      _ut.test('test_keyword_super', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_super);
+      });
+      _ut.test('test_keyword_switch', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_switch);
+      });
+      _ut.test('test_keyword_this', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_this);
+      });
+      _ut.test('test_keyword_throw', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_throw);
+      });
+      _ut.test('test_keyword_true', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_true);
+      });
+      _ut.test('test_keyword_try', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_try);
+      });
+      _ut.test('test_keyword_typedef', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_typedef);
+      });
+      _ut.test('test_keyword_var', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_var);
+      });
+      _ut.test('test_keyword_void', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_void);
+      });
+      _ut.test('test_keyword_while', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_while);
+      });
+      _ut.test('test_keyword_with', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_with);
+      });
+      _ut.test('test_lineInfo_multilineComment', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_lineInfo_multilineComment);
+      });
+      _ut.test('test_lineInfo_multilineString', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_lineInfo_multilineString);
+      });
+      _ut.test('test_lineInfo_simpleClass', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_lineInfo_simpleClass);
+      });
+      _ut.test('test_lineInfo_slashN', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_lineInfo_slashN);
+      });
+      _ut.test('test_lt', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_lt);
+      });
+      _ut.test('test_lt_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_lt_eq);
+      });
+      _ut.test('test_lt_lt', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_lt_lt);
+      });
+      _ut.test('test_lt_lt_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_lt_lt_eq);
+      });
+      _ut.test('test_minus', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_minus);
+      });
+      _ut.test('test_minus_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_minus_eq);
+      });
+      _ut.test('test_minus_minus', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_minus_minus);
+      });
+      _ut.test('test_openSquareBracket', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_openSquareBracket);
+      });
+      _ut.test('test_open_curly_bracket', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_open_curly_bracket);
+      });
+      _ut.test('test_open_paren', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_open_paren);
+      });
+      _ut.test('test_open_square_bracket', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_open_square_bracket);
+      });
+      _ut.test('test_percent', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_percent);
+      });
+      _ut.test('test_percent_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_percent_eq);
+      });
+      _ut.test('test_period', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_period);
+      });
+      _ut.test('test_periodAfterNumberNotIncluded_identifier', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_periodAfterNumberNotIncluded_identifier);
+      });
+      _ut.test('test_periodAfterNumberNotIncluded_period', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_periodAfterNumberNotIncluded_period);
+      });
+      _ut.test('test_period_period', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_period_period);
+      });
+      _ut.test('test_period_period_period', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_period_period_period);
+      });
+      _ut.test('test_plus', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_plus);
+      });
+      _ut.test('test_plus_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_plus_eq);
+      });
+      _ut.test('test_plus_plus', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_plus_plus);
+      });
+      _ut.test('test_question', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_question);
+      });
+      _ut.test('test_scriptTag_withArgs', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_scriptTag_withArgs);
+      });
+      _ut.test('test_scriptTag_withSpace', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_scriptTag_withSpace);
+      });
+      _ut.test('test_scriptTag_withoutSpace', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_scriptTag_withoutSpace);
+      });
+      _ut.test('test_semicolon', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_semicolon);
+      });
+      _ut.test('test_setSourceStart', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_setSourceStart);
+      });
+      _ut.test('test_slash', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_slash);
+      });
+      _ut.test('test_slash_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_slash_eq);
+      });
+      _ut.test('test_star', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_star);
+      });
+      _ut.test('test_star_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_star_eq);
+      });
+      _ut.test('test_startAndEnd', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_startAndEnd);
+      });
+      _ut.test('test_string_multi_double', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_double);
+      });
+      _ut.test('test_string_multi_embeddedQuotes', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_embeddedQuotes);
+      });
+      _ut.test('test_string_multi_embeddedQuotes_escapedChar', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_embeddedQuotes_escapedChar);
+      });
+      _ut.test('test_string_multi_interpolation_block', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_interpolation_block);
+      });
+      _ut.test('test_string_multi_interpolation_identifier', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_interpolation_identifier);
+      });
+      _ut.test('test_string_multi_single', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_single);
+      });
+      _ut.test('test_string_multi_slashEnter', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_slashEnter);
+      });
+      _ut.test('test_string_multi_unterminated', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_multi_unterminated);
+      });
+      _ut.test('test_string_raw_multi_double', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_multi_double);
+      });
+      _ut.test('test_string_raw_multi_single', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_multi_single);
+      });
+      _ut.test('test_string_raw_multi_unterminated', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_multi_unterminated);
+      });
+      _ut.test('test_string_raw_simple_double', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_simple_double);
+      });
+      _ut.test('test_string_raw_simple_single', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_simple_single);
+      });
+      _ut.test('test_string_raw_simple_unterminated_eof', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_simple_unterminated_eof);
+      });
+      _ut.test('test_string_raw_simple_unterminated_eol', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_raw_simple_unterminated_eol);
+      });
+      _ut.test('test_string_simple_double', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_double);
+      });
+      _ut.test('test_string_simple_escapedDollar', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_escapedDollar);
+      });
+      _ut.test('test_string_simple_interpolation_adjacentIdentifiers', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_adjacentIdentifiers);
+      });
+      _ut.test('test_string_simple_interpolation_block', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_block);
+      });
+      _ut.test('test_string_simple_interpolation_blockWithNestedMap', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_blockWithNestedMap);
+      });
+      _ut.test('test_string_simple_interpolation_firstAndLast', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_firstAndLast);
+      });
+      _ut.test('test_string_simple_interpolation_identifier', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_identifier);
+      });
+      _ut.test('test_string_simple_interpolation_missingIdentifier', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_missingIdentifier);
+      });
+      _ut.test('test_string_simple_interpolation_nonIdentifier', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_interpolation_nonIdentifier);
+      });
+      _ut.test('test_string_simple_single', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_single);
+      });
+      _ut.test('test_string_simple_unterminated_eof', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_unterminated_eof);
+      });
+      _ut.test('test_string_simple_unterminated_eol', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_string_simple_unterminated_eol);
+      });
+      _ut.test('test_tilde', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_tilde);
+      });
+      _ut.test('test_tilde_slash', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_tilde_slash);
+      });
+      _ut.test('test_tilde_slash_eq', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_tilde_slash_eq);
+      });
+      _ut.test('test_unclosedPairInInterpolation', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_unclosedPairInInterpolation);
+      });
+    });
+  }
+}
+/**
+ * Instances of the class `ExpectedLocation` encode information about the expected location
+ * of a given offset in source code.
+ */
+class ScannerTest_ExpectedLocation {
+  int _offset = 0;
+  int _lineNumber = 0;
+  int _columnNumber = 0;
+  ScannerTest_ExpectedLocation(int offset, int lineNumber, int columnNumber) {
+    this._offset = offset;
+    this._lineNumber = lineNumber;
+    this._columnNumber = columnNumber;
+  }
+}
+class IncrementalScannerTest extends JUnitTestCase {
+  void test_rescan_addedToIdentifier() {
+    assertTokens("a + b;", "abs + b;");
+  }
+  void test_rescan_insertedPeriod() {
+    assertTokens("a + b;", "a + b.;");
+  }
+  void test_rescan_oneFunctionToTwo() {
+    assertTokens("f() {}", "f() => 0; g() {}");
+  }
+  void assertTokens(String originalContents, String modifiedContents) {
+    int originalLength = originalContents.length;
+    int modifiedLength = modifiedContents.length;
+    int replaceStart = 0;
+    while (replaceStart < originalLength && replaceStart < modifiedLength && originalContents.codeUnitAt(replaceStart) == modifiedContents.codeUnitAt(replaceStart)) {
+      replaceStart++;
+    }
+    int originalEnd = originalLength - 1;
+    int modifiedEnd = modifiedLength - 1;
+    while (originalEnd >= replaceStart && modifiedEnd >= replaceStart && originalContents.codeUnitAt(originalEnd) == modifiedContents.codeUnitAt(modifiedEnd)) {
+      originalEnd--;
+      modifiedEnd--;
+    }
+    Source source = new TestSource();
+    GatheringErrorListener originalListener = new GatheringErrorListener();
+    Scanner originalScanner = new Scanner(source, new CharSequenceReader(new CharSequence(originalContents)), originalListener);
+    Token originalToken = originalScanner.tokenize();
+    JUnitTestCase.assertNotNull(originalToken);
+    GatheringErrorListener modifiedListener = new GatheringErrorListener();
+    Scanner modifiedScanner = new Scanner(source, new CharSequenceReader(new CharSequence(modifiedContents)), modifiedListener);
+    Token modifiedToken = modifiedScanner.tokenize();
+    JUnitTestCase.assertNotNull(modifiedToken);
+    GatheringErrorListener incrementalListener = new GatheringErrorListener();
+    IncrementalScanner incrementalScanner = new IncrementalScanner(source, new CharSequenceReader(new CharSequence(modifiedContents)), incrementalListener);
+    Token incrementalToken = incrementalScanner.rescan(originalToken, replaceStart, originalEnd - replaceStart + 1, modifiedEnd - replaceStart + 1);
+    JUnitTestCase.assertNotNull(incrementalToken);
+    while (incrementalToken.type != TokenType.EOF && modifiedToken.type != TokenType.EOF) {
+      JUnitTestCase.assertSameMsg("Wrong type for token", modifiedToken.type, incrementalToken.type);
+      JUnitTestCase.assertEqualsMsg("Wrong offset for token", modifiedToken.offset, incrementalToken.offset);
+      JUnitTestCase.assertEqualsMsg("Wrong length for token", modifiedToken.length, incrementalToken.length);
+      JUnitTestCase.assertEqualsMsg("Wrong lexeme for token", modifiedToken.lexeme, incrementalToken.lexeme);
+      incrementalToken = incrementalToken.next;
+      modifiedToken = modifiedToken.next;
+    }
+    JUnitTestCase.assertSameMsg("Too many tokens", TokenType.EOF, incrementalToken.type);
+    JUnitTestCase.assertSameMsg("Not enough tokens", TokenType.EOF, modifiedToken.type);
+  }
+  static dartSuite() {
+    _ut.group('IncrementalScannerTest', () {
+      _ut.test('test_rescan_addedToIdentifier', () {
+        final __test = new IncrementalScannerTest();
+        runJUnitTest(__test, __test.test_rescan_addedToIdentifier);
+      });
+      _ut.test('test_rescan_insertedPeriod', () {
+        final __test = new IncrementalScannerTest();
+        runJUnitTest(__test, __test.test_rescan_insertedPeriod);
+      });
+      _ut.test('test_rescan_oneFunctionToTwo', () {
+        final __test = new IncrementalScannerTest();
+        runJUnitTest(__test, __test.test_rescan_oneFunctionToTwo);
+      });
+    });
+  }
+}
+main() {
+  CharSequenceReaderTest.dartSuite();
+  IncrementalScannerTest.dartSuite();
+  KeywordStateTest.dartSuite();
+  ScannerTest.dartSuite();
+  TokenTypeTest.dartSuite();
+}
\ No newline at end of file
diff --git a/pkg/analyzer_experimental/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
similarity index 97%
rename from pkg/analyzer_experimental/test/generated/test_support.dart
rename to pkg/analyzer/test/generated/test_support.dart
index 90af45a..aebb0d2 100644
--- a/pkg/analyzer_experimental/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -1,14 +1,14 @@
 // This code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 library engine.test_support;
-import 'package:analyzer_experimental/src/generated/java_core.dart';
-import 'package:analyzer_experimental/src/generated/java_junit.dart';
-import 'package:analyzer_experimental/src/generated/source.dart';
-import 'package:analyzer_experimental/src/generated/error.dart';
-import 'package:analyzer_experimental/src/generated/scanner.dart';
-import 'package:analyzer_experimental/src/generated/ast.dart' show ASTNode, NodeLocator;
-import 'package:analyzer_experimental/src/generated/element.dart' show InterfaceType, MethodElement, PropertyAccessorElement;
-import 'package:analyzer_experimental/src/generated/engine.dart' show AnalysisContext, AnalysisContextImpl, RecordingErrorListener;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_junit.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/ast.dart' show ASTNode, NodeLocator;
+import 'package:analyzer/src/generated/element.dart' show InterfaceType, MethodElement, PropertyAccessorElement;
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext, AnalysisContextImpl, RecordingErrorListener;
 import 'package:unittest/unittest.dart' as _ut;
 /**
  * Instances of the class `GatheringErrorListener` implement an error listener that collects
diff --git a/pkg/analyzer_experimental/test/options_test.dart b/pkg/analyzer/test/options_test.dart
similarity index 96%
rename from pkg/analyzer_experimental/test/options_test.dart
rename to pkg/analyzer/test/options_test.dart
index c4c9a34..6dde78b 100644
--- a/pkg/analyzer_experimental/test/options_test.dart
+++ b/pkg/analyzer/test/options_test.dart
@@ -5,7 +5,7 @@
 library options_test;
 
 import 'package:unittest/unittest.dart';
-import 'package:analyzer_experimental/options.dart';
+import 'package:analyzer/options.dart';
 
 main() {
 
@@ -36,13 +36,13 @@
           .parse(['--dart-sdk', '.', '-p', 'bar', 'foo.dart']);
       expect(options.packageRootPath, equals('bar'));
     });
-    
+
     test('package warnings', () {
       CommandLineOptions options = CommandLineOptions
           .parse(['--dart-sdk', '.', '--package-warnings', 'foo.dart']);
       expect(options.showPackageWarnings, isTrue);
     });
-    
+
     test('sdk warnings', () {
       CommandLineOptions options = CommandLineOptions
           .parse(['--dart-sdk', '.', '--warnings', 'foo.dart']);
diff --git a/pkg/analyzer_experimental/test/parse_compilation_unit_test.dart b/pkg/analyzer/test/parse_compilation_unit_test.dart
similarity index 95%
rename from pkg/analyzer_experimental/test/parse_compilation_unit_test.dart
rename to pkg/analyzer/test/parse_compilation_unit_test.dart
index 69389b8..91bb9e9 100644
--- a/pkg/analyzer_experimental/test/parse_compilation_unit_test.dart
+++ b/pkg/analyzer/test/parse_compilation_unit_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer_experimental/analyzer.dart';
+import 'package:analyzer/analyzer.dart';
 import 'package:unittest/unittest.dart';
 
 void main() {
diff --git a/pkg/analyzer_experimental/test/services/formatter_test.dart b/pkg/analyzer/test/services/formatter_test.dart
similarity index 98%
rename from pkg/analyzer_experimental/test/services/formatter_test.dart
rename to pkg/analyzer/test/services/formatter_test.dart
index 160aba2..72f010b 100644
--- a/pkg/analyzer_experimental/test/services/formatter_test.dart
+++ b/pkg/analyzer/test/services/formatter_test.dart
@@ -4,9 +4,10 @@
 
 import 'package:unittest/unittest.dart';
 
-import 'package:analyzer_experimental/src/generated/scanner.dart';
-import 'package:analyzer_experimental/src/services/formatter_impl.dart';
-import 'package:analyzer_experimental/src/services/writer.dart';
+import 'package:analyzer/src/generated/java_core.dart' show CharSequence;
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/services/formatter_impl.dart';
+import 'package:analyzer/src/services/writer.dart';
 
 main() {
 
@@ -720,7 +721,7 @@
         '    ..toString();'
       );
     });
-    
+
     test('stmt (generics)', () {
       expectStmtFormatsTo(
         'var numbers = <int>[1, 2, (3 + 4)];',
@@ -1038,7 +1039,10 @@
 String formatStatement(src, {options: const FormatterOptions()}) =>
     new CodeFormatter(options).format(CodeKind.STATEMENT, src).source;
 
-Token tokenize(String str) => new StringScanner(null, str, null).tokenize();
+Token tokenize(String str) {
+  var reader = new CharSequenceReader(new CharSequence(str));
+  return new Scanner(null, reader, null).tokenize();
+}
 
 expectSelectedPostFormat(src, token) {
   var preOffset = src.indexOf(token);
diff --git a/pkg/analyzer_experimental/test/services/test_utils.dart b/pkg/analyzer/test/services/test_utils.dart
similarity index 90%
rename from pkg/analyzer_experimental/test/services/test_utils.dart
rename to pkg/analyzer/test/services/test_utils.dart
index 3c7765e..65960a1 100644
--- a/pkg/analyzer_experimental/test/services/test_utils.dart
+++ b/pkg/analyzer/test/services/test_utils.dart
@@ -6,12 +6,13 @@
 
 import 'package:unittest/unittest.dart';
 
-import 'package:analyzer_experimental/src/generated/engine.dart' show AnalysisContext, AnalysisContextImpl;
-import 'package:analyzer_experimental/src/generated/source.dart';
-import 'package:analyzer_experimental/src/generated/error.dart';
-import 'package:analyzer_experimental/src/generated/scanner.dart';
-import 'package:analyzer_experimental/src/generated/ast.dart';
-import 'package:analyzer_experimental/src/generated/parser.dart';
+import 'package:analyzer/src/generated/java_core.dart' show CharSequence;
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext, AnalysisContextImpl;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/parser.dart';
 
 
 /// Instances of the class [_GatheringErrorListener] implement an error listener
@@ -197,7 +198,8 @@
 Statement parseStatement(String source, [List<ErrorCode> expectedErrorCodes]) {
 
   var listener = new _GatheringErrorListener();
-  var scanner = new StringScanner(null, source, listener);
+  var reader = new CharSequenceReader(new CharSequence(source));
+  var scanner = new Scanner(null, reader, listener);
   listener.setLineInfo(new _TestSource(), scanner.lineStarts);
 
   var token = scanner.tokenize();
diff --git a/pkg/analyzer_experimental/test/utils.dart b/pkg/analyzer/test/utils.dart
similarity index 92%
rename from pkg/analyzer_experimental/test/utils.dart
rename to pkg/analyzer/test/utils.dart
index df22ff8..a3c36ac 100644
--- a/pkg/analyzer_experimental/test/utils.dart
+++ b/pkg/analyzer/test/utils.dart
@@ -6,7 +6,7 @@
 
 import 'dart:io';
 
-import 'package:analyzer_experimental/analyzer.dart';
+import 'package:analyzer/analyzer.dart';
 import 'package:path/path.dart' as pathos;
 
 /// Returns the string representation of the [AnalyzerErrorGroup] thrown when
@@ -39,7 +39,7 @@
 /// Returns the return value of [fn].
 dynamic withTempDir(fn(String path)) {
   var tempDir =
-      Directory.systemTemp.createTempSync('analyzer_experimental_').path;
+      Directory.systemTemp.createTempSync('analyzer_').path;
   try {
     return fn(tempDir);
   } finally {
diff --git a/pkg/analyzer_experimental/pubspec.yaml b/pkg/analyzer_experimental/pubspec.yaml
deleted file mode 100644
index 6e556fc..0000000
--- a/pkg/analyzer_experimental/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: analyzer_experimental
-author: Dart Team <misc@dartlang.org>
-description: Experimental static analyzer for Dart.
-homepage: http://www.dartlang.org
-dependencies:
-  args: any
-  logging: any
-  path: any
-dev_dependencies:
-  unittest: any
diff --git a/pkg/analyzer_experimental/test/generated/scanner_test.dart b/pkg/analyzer_experimental/test/generated/scanner_test.dart
deleted file mode 100644
index 9c31c55..0000000
--- a/pkg/analyzer_experimental/test/generated/scanner_test.dart
+++ /dev/null
@@ -1,2266 +0,0 @@
-// This code was auto-generated, is not intended to be edited, and is subject to
-// significant change. Please see the README file for more information.
-library engine.scanner_test;
-import 'package:analyzer_experimental/src/generated/java_core.dart';
-import 'package:analyzer_experimental/src/generated/java_junit.dart';
-import 'package:analyzer_experimental/src/generated/source.dart';
-import 'package:analyzer_experimental/src/generated/error.dart';
-import 'package:analyzer_experimental/src/generated/scanner.dart';
-import 'package:unittest/unittest.dart' as _ut;
-import 'test_support.dart';
-class KeywordStateTest extends JUnitTestCase {
-  void test_KeywordState() {
-    List<Keyword> keywords = Keyword.values;
-    int keywordCount = keywords.length;
-    List<String> textToTest = new List<String>(keywordCount * 3);
-    for (int i = 0; i < keywordCount; i++) {
-      String syntax = keywords[i].syntax;
-      textToTest[i] = syntax;
-      textToTest[i + keywordCount] = "${syntax}x";
-      textToTest[i + keywordCount * 2] = syntax.substring(0, syntax.length - 1);
-    }
-    KeywordState firstState = KeywordState.KEYWORD_STATE;
-    for (int i = 0; i < textToTest.length; i++) {
-      String text = textToTest[i];
-      int index = 0;
-      int length = text.length;
-      KeywordState state = firstState;
-      while (index < length && state != null) {
-        state = state.next(text.codeUnitAt(index));
-        index++;
-      }
-      if (i < keywordCount) {
-        JUnitTestCase.assertNotNull(state);
-        JUnitTestCase.assertNotNull(state.keyword());
-        JUnitTestCase.assertEquals(keywords[i], state.keyword());
-      } else if (i < keywordCount * 2) {
-        JUnitTestCase.assertNull(state);
-      } else {
-        JUnitTestCase.assertNotNull(state);
-      }
-    }
-  }
-  static dartSuite() {
-    _ut.group('KeywordStateTest', () {
-      _ut.test('test_KeywordState', () {
-        final __test = new KeywordStateTest();
-        runJUnitTest(__test, __test.test_KeywordState);
-      });
-    });
-  }
-}
-class TokenTypeTest extends EngineTestCase {
-  void test_isOperator() {
-    JUnitTestCase.assertTrue(TokenType.AMPERSAND.isOperator);
-    JUnitTestCase.assertTrue(TokenType.AMPERSAND_AMPERSAND.isOperator);
-    JUnitTestCase.assertTrue(TokenType.AMPERSAND_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.BANG.isOperator);
-    JUnitTestCase.assertTrue(TokenType.BANG_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.BAR.isOperator);
-    JUnitTestCase.assertTrue(TokenType.BAR_BAR.isOperator);
-    JUnitTestCase.assertTrue(TokenType.BAR_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.CARET.isOperator);
-    JUnitTestCase.assertTrue(TokenType.CARET_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.EQ_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.GT.isOperator);
-    JUnitTestCase.assertTrue(TokenType.GT_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.GT_GT.isOperator);
-    JUnitTestCase.assertTrue(TokenType.GT_GT_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.INDEX.isOperator);
-    JUnitTestCase.assertTrue(TokenType.INDEX_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.IS.isOperator);
-    JUnitTestCase.assertTrue(TokenType.LT.isOperator);
-    JUnitTestCase.assertTrue(TokenType.LT_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.LT_LT.isOperator);
-    JUnitTestCase.assertTrue(TokenType.LT_LT_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.MINUS.isOperator);
-    JUnitTestCase.assertTrue(TokenType.MINUS_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.MINUS_MINUS.isOperator);
-    JUnitTestCase.assertTrue(TokenType.PERCENT.isOperator);
-    JUnitTestCase.assertTrue(TokenType.PERCENT_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.PERIOD_PERIOD.isOperator);
-    JUnitTestCase.assertTrue(TokenType.PLUS.isOperator);
-    JUnitTestCase.assertTrue(TokenType.PLUS_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.PLUS_PLUS.isOperator);
-    JUnitTestCase.assertTrue(TokenType.QUESTION.isOperator);
-    JUnitTestCase.assertTrue(TokenType.SLASH.isOperator);
-    JUnitTestCase.assertTrue(TokenType.SLASH_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.STAR.isOperator);
-    JUnitTestCase.assertTrue(TokenType.STAR_EQ.isOperator);
-    JUnitTestCase.assertTrue(TokenType.TILDE.isOperator);
-    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH.isOperator);
-    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH_EQ.isOperator);
-  }
-  void test_isUserDefinableOperator() {
-    JUnitTestCase.assertTrue(TokenType.AMPERSAND.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.BAR.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.CARET.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.EQ_EQ.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.GT.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.GT_EQ.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.GT_GT.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.INDEX.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.INDEX_EQ.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.LT.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.LT_EQ.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.LT_LT.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.MINUS.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.PERCENT.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.PLUS.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.SLASH.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.STAR.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.TILDE.isUserDefinableOperator);
-    JUnitTestCase.assertTrue(TokenType.TILDE_SLASH.isUserDefinableOperator);
-  }
-  static dartSuite() {
-    _ut.group('TokenTypeTest', () {
-      _ut.test('test_isOperator', () {
-        final __test = new TokenTypeTest();
-        runJUnitTest(__test, __test.test_isOperator);
-      });
-      _ut.test('test_isUserDefinableOperator', () {
-        final __test = new TokenTypeTest();
-        runJUnitTest(__test, __test.test_isUserDefinableOperator);
-      });
-    });
-  }
-}
-/**
- * The class `TokenFactory` defines utility methods that can be used to create tokens.
- */
-class TokenFactory {
-  static Token token(Keyword keyword) => new KeywordToken(keyword, 0);
-  static Token token2(String lexeme) => new StringToken(TokenType.STRING, lexeme, 0);
-  static Token token3(TokenType type) => new Token(type, 0);
-  static Token token4(TokenType type, String lexeme) => new StringToken(type, lexeme, 0);
-}
-class CharBufferScannerTest extends AbstractScannerTest {
-  Token scan(String source, GatheringErrorListener listener) {
-    CharBuffer buffer = CharBuffer.wrap(source);
-    CharBufferScanner scanner = new CharBufferScanner(null, buffer, listener);
-    Token result = scanner.tokenize();
-    listener.setLineInfo(new TestSource(), scanner.lineStarts);
-    return result;
-  }
-  static dartSuite() {
-    _ut.group('CharBufferScannerTest', () {
-      _ut.test('test_ampersand', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_ampersand);
-      });
-      _ut.test('test_ampersand_ampersand', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_ampersand_ampersand);
-      });
-      _ut.test('test_ampersand_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_ampersand_eq);
-      });
-      _ut.test('test_at', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_at);
-      });
-      _ut.test('test_backping', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_backping);
-      });
-      _ut.test('test_backslash', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_backslash);
-      });
-      _ut.test('test_bang', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_bang);
-      });
-      _ut.test('test_bang_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_bang_eq);
-      });
-      _ut.test('test_bar', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_bar);
-      });
-      _ut.test('test_bar_bar', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_bar_bar);
-      });
-      _ut.test('test_bar_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_bar_eq);
-      });
-      _ut.test('test_caret', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_caret);
-      });
-      _ut.test('test_caret_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_caret_eq);
-      });
-      _ut.test('test_close_curly_bracket', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_close_curly_bracket);
-      });
-      _ut.test('test_close_paren', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_close_paren);
-      });
-      _ut.test('test_close_quare_bracket', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_close_quare_bracket);
-      });
-      _ut.test('test_colon', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_colon);
-      });
-      _ut.test('test_comma', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_comma);
-      });
-      _ut.test('test_comment_multi', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_comment_multi);
-      });
-      _ut.test('test_comment_multi_unterminated', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_comment_multi_unterminated);
-      });
-      _ut.test('test_comment_nested', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_comment_nested);
-      });
-      _ut.test('test_comment_single', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_comment_single);
-      });
-      _ut.test('test_double_both_E', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_double_both_E);
-      });
-      _ut.test('test_double_both_e', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_double_both_e);
-      });
-      _ut.test('test_double_fraction', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_double_fraction);
-      });
-      _ut.test('test_double_fraction_E', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_double_fraction_E);
-      });
-      _ut.test('test_double_fraction_e', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_double_fraction_e);
-      });
-      _ut.test('test_double_missingDigitInExponent', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_double_missingDigitInExponent);
-      });
-      _ut.test('test_double_whole_E', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_double_whole_E);
-      });
-      _ut.test('test_double_whole_e', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_double_whole_e);
-      });
-      _ut.test('test_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_eq);
-      });
-      _ut.test('test_eq_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_eq_eq);
-      });
-      _ut.test('test_gt', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_gt);
-      });
-      _ut.test('test_gt_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_gt_eq);
-      });
-      _ut.test('test_gt_gt', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_gt_gt);
-      });
-      _ut.test('test_gt_gt_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_gt_gt_eq);
-      });
-      _ut.test('test_hash', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_hash);
-      });
-      _ut.test('test_hexidecimal', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_hexidecimal);
-      });
-      _ut.test('test_hexidecimal_missingDigit', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_hexidecimal_missingDigit);
-      });
-      _ut.test('test_identifier', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_identifier);
-      });
-      _ut.test('test_illegalChar_cyrillicLetter_middle', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_illegalChar_cyrillicLetter_middle);
-      });
-      _ut.test('test_illegalChar_cyrillicLetter_start', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_illegalChar_cyrillicLetter_start);
-      });
-      _ut.test('test_illegalChar_nbsp', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_illegalChar_nbsp);
-      });
-      _ut.test('test_illegalChar_notLetter', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_illegalChar_notLetter);
-      });
-      _ut.test('test_index', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_index);
-      });
-      _ut.test('test_index_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_index_eq);
-      });
-      _ut.test('test_int', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_int);
-      });
-      _ut.test('test_int_initialZero', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_int_initialZero);
-      });
-      _ut.test('test_keyword_abstract', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_abstract);
-      });
-      _ut.test('test_keyword_as', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_as);
-      });
-      _ut.test('test_keyword_assert', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_assert);
-      });
-      _ut.test('test_keyword_break', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_break);
-      });
-      _ut.test('test_keyword_case', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_case);
-      });
-      _ut.test('test_keyword_catch', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_catch);
-      });
-      _ut.test('test_keyword_class', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_class);
-      });
-      _ut.test('test_keyword_const', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_const);
-      });
-      _ut.test('test_keyword_continue', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_continue);
-      });
-      _ut.test('test_keyword_default', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_default);
-      });
-      _ut.test('test_keyword_do', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_do);
-      });
-      _ut.test('test_keyword_dynamic', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_dynamic);
-      });
-      _ut.test('test_keyword_else', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_else);
-      });
-      _ut.test('test_keyword_enum', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_enum);
-      });
-      _ut.test('test_keyword_export', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_export);
-      });
-      _ut.test('test_keyword_extends', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_extends);
-      });
-      _ut.test('test_keyword_factory', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_factory);
-      });
-      _ut.test('test_keyword_false', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_false);
-      });
-      _ut.test('test_keyword_final', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_final);
-      });
-      _ut.test('test_keyword_finally', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_finally);
-      });
-      _ut.test('test_keyword_for', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_for);
-      });
-      _ut.test('test_keyword_get', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_get);
-      });
-      _ut.test('test_keyword_if', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_if);
-      });
-      _ut.test('test_keyword_implements', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_implements);
-      });
-      _ut.test('test_keyword_import', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_import);
-      });
-      _ut.test('test_keyword_in', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_in);
-      });
-      _ut.test('test_keyword_is', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_is);
-      });
-      _ut.test('test_keyword_library', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_library);
-      });
-      _ut.test('test_keyword_new', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_new);
-      });
-      _ut.test('test_keyword_null', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_null);
-      });
-      _ut.test('test_keyword_operator', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_operator);
-      });
-      _ut.test('test_keyword_part', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_part);
-      });
-      _ut.test('test_keyword_rethrow', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_rethrow);
-      });
-      _ut.test('test_keyword_return', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_return);
-      });
-      _ut.test('test_keyword_set', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_set);
-      });
-      _ut.test('test_keyword_static', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_static);
-      });
-      _ut.test('test_keyword_super', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_super);
-      });
-      _ut.test('test_keyword_switch', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_switch);
-      });
-      _ut.test('test_keyword_this', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_this);
-      });
-      _ut.test('test_keyword_throw', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_throw);
-      });
-      _ut.test('test_keyword_true', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_true);
-      });
-      _ut.test('test_keyword_try', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_try);
-      });
-      _ut.test('test_keyword_typedef', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_typedef);
-      });
-      _ut.test('test_keyword_var', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_var);
-      });
-      _ut.test('test_keyword_void', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_void);
-      });
-      _ut.test('test_keyword_while', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_while);
-      });
-      _ut.test('test_keyword_with', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_keyword_with);
-      });
-      _ut.test('test_lineInfo_multilineComment', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_lineInfo_multilineComment);
-      });
-      _ut.test('test_lineInfo_multilineString', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_lineInfo_multilineString);
-      });
-      _ut.test('test_lineInfo_simpleClass', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_lineInfo_simpleClass);
-      });
-      _ut.test('test_lineInfo_slashN', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_lineInfo_slashN);
-      });
-      _ut.test('test_lt', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_lt);
-      });
-      _ut.test('test_lt_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_lt_eq);
-      });
-      _ut.test('test_lt_lt', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_lt_lt);
-      });
-      _ut.test('test_lt_lt_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_lt_lt_eq);
-      });
-      _ut.test('test_minus', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_minus);
-      });
-      _ut.test('test_minus_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_minus_eq);
-      });
-      _ut.test('test_minus_minus', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_minus_minus);
-      });
-      _ut.test('test_openSquareBracket', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_openSquareBracket);
-      });
-      _ut.test('test_open_curly_bracket', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_open_curly_bracket);
-      });
-      _ut.test('test_open_paren', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_open_paren);
-      });
-      _ut.test('test_open_square_bracket', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_open_square_bracket);
-      });
-      _ut.test('test_percent', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_percent);
-      });
-      _ut.test('test_percent_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_percent_eq);
-      });
-      _ut.test('test_period', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_period);
-      });
-      _ut.test('test_periodAfterNumberNotIncluded_identifier', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_periodAfterNumberNotIncluded_identifier);
-      });
-      _ut.test('test_periodAfterNumberNotIncluded_period', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_periodAfterNumberNotIncluded_period);
-      });
-      _ut.test('test_period_period', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_period_period);
-      });
-      _ut.test('test_period_period_period', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_period_period_period);
-      });
-      _ut.test('test_plus', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_plus);
-      });
-      _ut.test('test_plus_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_plus_eq);
-      });
-      _ut.test('test_plus_plus', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_plus_plus);
-      });
-      _ut.test('test_question', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_question);
-      });
-      _ut.test('test_scriptTag_withArgs', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_scriptTag_withArgs);
-      });
-      _ut.test('test_scriptTag_withSpace', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_scriptTag_withSpace);
-      });
-      _ut.test('test_scriptTag_withoutSpace', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_scriptTag_withoutSpace);
-      });
-      _ut.test('test_semicolon', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_semicolon);
-      });
-      _ut.test('test_slash', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_slash);
-      });
-      _ut.test('test_slash_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_slash_eq);
-      });
-      _ut.test('test_star', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_star);
-      });
-      _ut.test('test_star_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_star_eq);
-      });
-      _ut.test('test_startAndEnd', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_startAndEnd);
-      });
-      _ut.test('test_string_multi_double', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_double);
-      });
-      _ut.test('test_string_multi_embeddedQuotes', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_embeddedQuotes);
-      });
-      _ut.test('test_string_multi_embeddedQuotes_escapedChar', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_embeddedQuotes_escapedChar);
-      });
-      _ut.test('test_string_multi_interpolation_block', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_interpolation_block);
-      });
-      _ut.test('test_string_multi_interpolation_identifier', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_interpolation_identifier);
-      });
-      _ut.test('test_string_multi_single', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_single);
-      });
-      _ut.test('test_string_multi_slashEnter', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_slashEnter);
-      });
-      _ut.test('test_string_multi_unterminated', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_unterminated);
-      });
-      _ut.test('test_string_raw_multi_double', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_multi_double);
-      });
-      _ut.test('test_string_raw_multi_single', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_multi_single);
-      });
-      _ut.test('test_string_raw_multi_unterminated', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_multi_unterminated);
-      });
-      _ut.test('test_string_raw_simple_double', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_simple_double);
-      });
-      _ut.test('test_string_raw_simple_single', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_simple_single);
-      });
-      _ut.test('test_string_raw_simple_unterminated_eof', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_simple_unterminated_eof);
-      });
-      _ut.test('test_string_raw_simple_unterminated_eol', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_simple_unterminated_eol);
-      });
-      _ut.test('test_string_simple_double', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_double);
-      });
-      _ut.test('test_string_simple_escapedDollar', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_escapedDollar);
-      });
-      _ut.test('test_string_simple_interpolation_adjacentIdentifiers', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_adjacentIdentifiers);
-      });
-      _ut.test('test_string_simple_interpolation_block', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_block);
-      });
-      _ut.test('test_string_simple_interpolation_blockWithNestedMap', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_blockWithNestedMap);
-      });
-      _ut.test('test_string_simple_interpolation_firstAndLast', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_firstAndLast);
-      });
-      _ut.test('test_string_simple_interpolation_identifier', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_identifier);
-      });
-      _ut.test('test_string_simple_interpolation_missingIdentifier', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_missingIdentifier);
-      });
-      _ut.test('test_string_simple_interpolation_nonIdentifier', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_nonIdentifier);
-      });
-      _ut.test('test_string_simple_single', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_single);
-      });
-      _ut.test('test_string_simple_unterminated_eof', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_unterminated_eof);
-      });
-      _ut.test('test_string_simple_unterminated_eol', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_unterminated_eol);
-      });
-      _ut.test('test_tilde', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_tilde);
-      });
-      _ut.test('test_tilde_slash', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_tilde_slash);
-      });
-      _ut.test('test_tilde_slash_eq', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_tilde_slash_eq);
-      });
-      _ut.test('test_unclosedPairInInterpolation', () {
-        final __test = new CharBufferScannerTest();
-        runJUnitTest(__test, __test.test_unclosedPairInInterpolation);
-      });
-    });
-  }
-}
-class StringScannerTest extends AbstractScannerTest {
-  void test_setSourceStart() {
-    int offsetDelta = 42;
-    GatheringErrorListener listener = new GatheringErrorListener();
-    StringScanner scanner = new StringScanner(null, "a", listener);
-    scanner.setSourceStart(3, 9, offsetDelta);
-    scanner.tokenize();
-    List<int> lineStarts = scanner.lineStarts;
-    JUnitTestCase.assertNotNull(lineStarts);
-    JUnitTestCase.assertEquals(3, lineStarts.length);
-    JUnitTestCase.assertEquals(33, lineStarts[2]);
-  }
-  Token scan(String source, GatheringErrorListener listener) {
-    StringScanner scanner = new StringScanner(null, source, listener);
-    Token result = scanner.tokenize();
-    listener.setLineInfo(new TestSource(), scanner.lineStarts);
-    return result;
-  }
-  static dartSuite() {
-    _ut.group('StringScannerTest', () {
-      _ut.test('test_ampersand', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_ampersand);
-      });
-      _ut.test('test_ampersand_ampersand', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_ampersand_ampersand);
-      });
-      _ut.test('test_ampersand_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_ampersand_eq);
-      });
-      _ut.test('test_at', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_at);
-      });
-      _ut.test('test_backping', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_backping);
-      });
-      _ut.test('test_backslash', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_backslash);
-      });
-      _ut.test('test_bang', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_bang);
-      });
-      _ut.test('test_bang_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_bang_eq);
-      });
-      _ut.test('test_bar', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_bar);
-      });
-      _ut.test('test_bar_bar', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_bar_bar);
-      });
-      _ut.test('test_bar_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_bar_eq);
-      });
-      _ut.test('test_caret', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_caret);
-      });
-      _ut.test('test_caret_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_caret_eq);
-      });
-      _ut.test('test_close_curly_bracket', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_close_curly_bracket);
-      });
-      _ut.test('test_close_paren', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_close_paren);
-      });
-      _ut.test('test_close_quare_bracket', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_close_quare_bracket);
-      });
-      _ut.test('test_colon', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_colon);
-      });
-      _ut.test('test_comma', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_comma);
-      });
-      _ut.test('test_comment_multi', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_comment_multi);
-      });
-      _ut.test('test_comment_multi_unterminated', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_comment_multi_unterminated);
-      });
-      _ut.test('test_comment_nested', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_comment_nested);
-      });
-      _ut.test('test_comment_single', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_comment_single);
-      });
-      _ut.test('test_double_both_E', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_double_both_E);
-      });
-      _ut.test('test_double_both_e', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_double_both_e);
-      });
-      _ut.test('test_double_fraction', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_double_fraction);
-      });
-      _ut.test('test_double_fraction_E', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_double_fraction_E);
-      });
-      _ut.test('test_double_fraction_e', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_double_fraction_e);
-      });
-      _ut.test('test_double_missingDigitInExponent', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_double_missingDigitInExponent);
-      });
-      _ut.test('test_double_whole_E', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_double_whole_E);
-      });
-      _ut.test('test_double_whole_e', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_double_whole_e);
-      });
-      _ut.test('test_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_eq);
-      });
-      _ut.test('test_eq_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_eq_eq);
-      });
-      _ut.test('test_gt', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_gt);
-      });
-      _ut.test('test_gt_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_gt_eq);
-      });
-      _ut.test('test_gt_gt', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_gt_gt);
-      });
-      _ut.test('test_gt_gt_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_gt_gt_eq);
-      });
-      _ut.test('test_hash', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_hash);
-      });
-      _ut.test('test_hexidecimal', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_hexidecimal);
-      });
-      _ut.test('test_hexidecimal_missingDigit', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_hexidecimal_missingDigit);
-      });
-      _ut.test('test_identifier', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_identifier);
-      });
-      _ut.test('test_illegalChar_cyrillicLetter_middle', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_illegalChar_cyrillicLetter_middle);
-      });
-      _ut.test('test_illegalChar_cyrillicLetter_start', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_illegalChar_cyrillicLetter_start);
-      });
-      _ut.test('test_illegalChar_nbsp', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_illegalChar_nbsp);
-      });
-      _ut.test('test_illegalChar_notLetter', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_illegalChar_notLetter);
-      });
-      _ut.test('test_index', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_index);
-      });
-      _ut.test('test_index_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_index_eq);
-      });
-      _ut.test('test_int', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_int);
-      });
-      _ut.test('test_int_initialZero', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_int_initialZero);
-      });
-      _ut.test('test_keyword_abstract', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_abstract);
-      });
-      _ut.test('test_keyword_as', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_as);
-      });
-      _ut.test('test_keyword_assert', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_assert);
-      });
-      _ut.test('test_keyword_break', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_break);
-      });
-      _ut.test('test_keyword_case', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_case);
-      });
-      _ut.test('test_keyword_catch', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_catch);
-      });
-      _ut.test('test_keyword_class', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_class);
-      });
-      _ut.test('test_keyword_const', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_const);
-      });
-      _ut.test('test_keyword_continue', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_continue);
-      });
-      _ut.test('test_keyword_default', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_default);
-      });
-      _ut.test('test_keyword_do', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_do);
-      });
-      _ut.test('test_keyword_dynamic', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_dynamic);
-      });
-      _ut.test('test_keyword_else', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_else);
-      });
-      _ut.test('test_keyword_enum', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_enum);
-      });
-      _ut.test('test_keyword_export', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_export);
-      });
-      _ut.test('test_keyword_extends', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_extends);
-      });
-      _ut.test('test_keyword_factory', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_factory);
-      });
-      _ut.test('test_keyword_false', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_false);
-      });
-      _ut.test('test_keyword_final', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_final);
-      });
-      _ut.test('test_keyword_finally', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_finally);
-      });
-      _ut.test('test_keyword_for', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_for);
-      });
-      _ut.test('test_keyword_get', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_get);
-      });
-      _ut.test('test_keyword_if', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_if);
-      });
-      _ut.test('test_keyword_implements', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_implements);
-      });
-      _ut.test('test_keyword_import', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_import);
-      });
-      _ut.test('test_keyword_in', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_in);
-      });
-      _ut.test('test_keyword_is', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_is);
-      });
-      _ut.test('test_keyword_library', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_library);
-      });
-      _ut.test('test_keyword_new', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_new);
-      });
-      _ut.test('test_keyword_null', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_null);
-      });
-      _ut.test('test_keyword_operator', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_operator);
-      });
-      _ut.test('test_keyword_part', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_part);
-      });
-      _ut.test('test_keyword_rethrow', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_rethrow);
-      });
-      _ut.test('test_keyword_return', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_return);
-      });
-      _ut.test('test_keyword_set', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_set);
-      });
-      _ut.test('test_keyword_static', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_static);
-      });
-      _ut.test('test_keyword_super', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_super);
-      });
-      _ut.test('test_keyword_switch', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_switch);
-      });
-      _ut.test('test_keyword_this', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_this);
-      });
-      _ut.test('test_keyword_throw', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_throw);
-      });
-      _ut.test('test_keyword_true', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_true);
-      });
-      _ut.test('test_keyword_try', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_try);
-      });
-      _ut.test('test_keyword_typedef', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_typedef);
-      });
-      _ut.test('test_keyword_var', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_var);
-      });
-      _ut.test('test_keyword_void', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_void);
-      });
-      _ut.test('test_keyword_while', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_while);
-      });
-      _ut.test('test_keyword_with', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_keyword_with);
-      });
-      _ut.test('test_lineInfo_multilineComment', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_lineInfo_multilineComment);
-      });
-      _ut.test('test_lineInfo_multilineString', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_lineInfo_multilineString);
-      });
-      _ut.test('test_lineInfo_simpleClass', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_lineInfo_simpleClass);
-      });
-      _ut.test('test_lineInfo_slashN', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_lineInfo_slashN);
-      });
-      _ut.test('test_lt', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_lt);
-      });
-      _ut.test('test_lt_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_lt_eq);
-      });
-      _ut.test('test_lt_lt', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_lt_lt);
-      });
-      _ut.test('test_lt_lt_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_lt_lt_eq);
-      });
-      _ut.test('test_minus', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_minus);
-      });
-      _ut.test('test_minus_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_minus_eq);
-      });
-      _ut.test('test_minus_minus', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_minus_minus);
-      });
-      _ut.test('test_openSquareBracket', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_openSquareBracket);
-      });
-      _ut.test('test_open_curly_bracket', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_open_curly_bracket);
-      });
-      _ut.test('test_open_paren', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_open_paren);
-      });
-      _ut.test('test_open_square_bracket', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_open_square_bracket);
-      });
-      _ut.test('test_percent', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_percent);
-      });
-      _ut.test('test_percent_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_percent_eq);
-      });
-      _ut.test('test_period', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_period);
-      });
-      _ut.test('test_periodAfterNumberNotIncluded_identifier', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_periodAfterNumberNotIncluded_identifier);
-      });
-      _ut.test('test_periodAfterNumberNotIncluded_period', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_periodAfterNumberNotIncluded_period);
-      });
-      _ut.test('test_period_period', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_period_period);
-      });
-      _ut.test('test_period_period_period', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_period_period_period);
-      });
-      _ut.test('test_plus', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_plus);
-      });
-      _ut.test('test_plus_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_plus_eq);
-      });
-      _ut.test('test_plus_plus', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_plus_plus);
-      });
-      _ut.test('test_question', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_question);
-      });
-      _ut.test('test_scriptTag_withArgs', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_scriptTag_withArgs);
-      });
-      _ut.test('test_scriptTag_withSpace', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_scriptTag_withSpace);
-      });
-      _ut.test('test_scriptTag_withoutSpace', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_scriptTag_withoutSpace);
-      });
-      _ut.test('test_semicolon', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_semicolon);
-      });
-      _ut.test('test_setSourceStart', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_setSourceStart);
-      });
-      _ut.test('test_slash', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_slash);
-      });
-      _ut.test('test_slash_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_slash_eq);
-      });
-      _ut.test('test_star', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_star);
-      });
-      _ut.test('test_star_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_star_eq);
-      });
-      _ut.test('test_startAndEnd', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_startAndEnd);
-      });
-      _ut.test('test_string_multi_double', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_double);
-      });
-      _ut.test('test_string_multi_embeddedQuotes', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_embeddedQuotes);
-      });
-      _ut.test('test_string_multi_embeddedQuotes_escapedChar', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_embeddedQuotes_escapedChar);
-      });
-      _ut.test('test_string_multi_interpolation_block', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_interpolation_block);
-      });
-      _ut.test('test_string_multi_interpolation_identifier', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_interpolation_identifier);
-      });
-      _ut.test('test_string_multi_single', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_single);
-      });
-      _ut.test('test_string_multi_slashEnter', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_slashEnter);
-      });
-      _ut.test('test_string_multi_unterminated', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_multi_unterminated);
-      });
-      _ut.test('test_string_raw_multi_double', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_multi_double);
-      });
-      _ut.test('test_string_raw_multi_single', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_multi_single);
-      });
-      _ut.test('test_string_raw_multi_unterminated', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_multi_unterminated);
-      });
-      _ut.test('test_string_raw_simple_double', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_simple_double);
-      });
-      _ut.test('test_string_raw_simple_single', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_simple_single);
-      });
-      _ut.test('test_string_raw_simple_unterminated_eof', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_simple_unterminated_eof);
-      });
-      _ut.test('test_string_raw_simple_unterminated_eol', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_raw_simple_unterminated_eol);
-      });
-      _ut.test('test_string_simple_double', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_double);
-      });
-      _ut.test('test_string_simple_escapedDollar', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_escapedDollar);
-      });
-      _ut.test('test_string_simple_interpolation_adjacentIdentifiers', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_adjacentIdentifiers);
-      });
-      _ut.test('test_string_simple_interpolation_block', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_block);
-      });
-      _ut.test('test_string_simple_interpolation_blockWithNestedMap', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_blockWithNestedMap);
-      });
-      _ut.test('test_string_simple_interpolation_firstAndLast', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_firstAndLast);
-      });
-      _ut.test('test_string_simple_interpolation_identifier', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_identifier);
-      });
-      _ut.test('test_string_simple_interpolation_missingIdentifier', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_missingIdentifier);
-      });
-      _ut.test('test_string_simple_interpolation_nonIdentifier', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_interpolation_nonIdentifier);
-      });
-      _ut.test('test_string_simple_single', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_single);
-      });
-      _ut.test('test_string_simple_unterminated_eof', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_unterminated_eof);
-      });
-      _ut.test('test_string_simple_unterminated_eol', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_string_simple_unterminated_eol);
-      });
-      _ut.test('test_tilde', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_tilde);
-      });
-      _ut.test('test_tilde_slash', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_tilde_slash);
-      });
-      _ut.test('test_tilde_slash_eq', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_tilde_slash_eq);
-      });
-      _ut.test('test_unclosedPairInInterpolation', () {
-        final __test = new StringScannerTest();
-        runJUnitTest(__test, __test.test_unclosedPairInInterpolation);
-      });
-    });
-  }
-}
-/**
- * Instances of the class `TokenStreamValidator` are used to validate the correct construction
- * of a stream of tokens.
- */
-class TokenStreamValidator {
-
-  /**
-   * Validate that the stream of tokens that starts with the given token is correct.
-   *
-   * @param token the first token in the stream of tokens to be validated
-   */
-  void validate(Token token) {
-    JavaStringBuilder builder = new JavaStringBuilder();
-    validateStream(builder, token);
-    if (builder.length > 0) {
-      JUnitTestCase.fail(builder.toString());
-    }
-  }
-  void validateStream(JavaStringBuilder builder, Token token) {
-    if (token == null) {
-      return;
-    }
-    Token previousToken = null;
-    int previousEnd = -1;
-    Token currentToken = token;
-    while (currentToken != null && currentToken.type != TokenType.EOF) {
-      validateStream(builder, currentToken.precedingComments);
-      TokenType type = currentToken.type;
-      if (identical(type, TokenType.OPEN_CURLY_BRACKET) || identical(type, TokenType.OPEN_PAREN) || identical(type, TokenType.OPEN_SQUARE_BRACKET) || identical(type, TokenType.STRING_INTERPOLATION_EXPRESSION)) {
-        if (currentToken is! BeginToken) {
-          builder.append("\r\nExpected BeginToken, found ");
-          builder.append(currentToken.runtimeType.toString());
-          builder.append(" ");
-          writeToken(builder, currentToken);
-        }
-      }
-      int currentStart = currentToken.offset;
-      int currentLength = currentToken.length;
-      int currentEnd = currentStart + currentLength - 1;
-      if (currentStart <= previousEnd) {
-        builder.append("\r\nInvalid token sequence: ");
-        writeToken(builder, previousToken);
-        builder.append(" followed by ");
-        writeToken(builder, currentToken);
-      }
-      previousEnd = currentEnd;
-      previousToken = currentToken;
-      currentToken = currentToken.next;
-    }
-  }
-  void writeToken(JavaStringBuilder builder, Token token) {
-    builder.append("[");
-    builder.append(token.type);
-    builder.append(", '");
-    builder.append(token.lexeme);
-    builder.append("', ");
-    builder.append(token.offset);
-    builder.append(", ");
-    builder.append(token.length);
-    builder.append("]");
-  }
-}
-abstract class AbstractScannerTest extends JUnitTestCase {
-  void test_ampersand() {
-    assertToken(TokenType.AMPERSAND, "&");
-  }
-  void test_ampersand_ampersand() {
-    assertToken(TokenType.AMPERSAND_AMPERSAND, "&&");
-  }
-  void test_ampersand_eq() {
-    assertToken(TokenType.AMPERSAND_EQ, "&=");
-  }
-  void test_at() {
-    assertToken(TokenType.AT, "@");
-  }
-  void test_backping() {
-    assertToken(TokenType.BACKPING, "`");
-  }
-  void test_backslash() {
-    assertToken(TokenType.BACKSLASH, "\\");
-  }
-  void test_bang() {
-    assertToken(TokenType.BANG, "!");
-  }
-  void test_bang_eq() {
-    assertToken(TokenType.BANG_EQ, "!=");
-  }
-  void test_bar() {
-    assertToken(TokenType.BAR, "|");
-  }
-  void test_bar_bar() {
-    assertToken(TokenType.BAR_BAR, "||");
-  }
-  void test_bar_eq() {
-    assertToken(TokenType.BAR_EQ, "|=");
-  }
-  void test_caret() {
-    assertToken(TokenType.CARET, "^");
-  }
-  void test_caret_eq() {
-    assertToken(TokenType.CARET_EQ, "^=");
-  }
-  void test_close_curly_bracket() {
-    assertToken(TokenType.CLOSE_CURLY_BRACKET, "}");
-  }
-  void test_close_paren() {
-    assertToken(TokenType.CLOSE_PAREN, ")");
-  }
-  void test_close_quare_bracket() {
-    assertToken(TokenType.CLOSE_SQUARE_BRACKET, "]");
-  }
-  void test_colon() {
-    assertToken(TokenType.COLON, ":");
-  }
-  void test_comma() {
-    assertToken(TokenType.COMMA, ",");
-  }
-  void test_comment_multi() {
-    assertComment(TokenType.MULTI_LINE_COMMENT, "/* comment */");
-  }
-  void test_comment_multi_unterminated() {
-    assertError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, 3, "/* x");
-  }
-  void test_comment_nested() {
-    assertComment(TokenType.MULTI_LINE_COMMENT, "/* comment /* within a */ comment */");
-  }
-  void test_comment_single() {
-    assertComment(TokenType.SINGLE_LINE_COMMENT, "// comment");
-  }
-  void test_double_both_e() {
-    assertToken(TokenType.DOUBLE, "0.123e4");
-  }
-  void test_double_both_E() {
-    assertToken(TokenType.DOUBLE, "0.123E4");
-  }
-  void test_double_fraction() {
-    assertToken(TokenType.DOUBLE, ".123");
-  }
-  void test_double_fraction_e() {
-    assertToken(TokenType.DOUBLE, ".123e4");
-  }
-  void test_double_fraction_E() {
-    assertToken(TokenType.DOUBLE, ".123E4");
-  }
-  void test_double_missingDigitInExponent() {
-    assertError(ScannerErrorCode.MISSING_DIGIT, 1, "1e");
-  }
-  void test_double_whole_e() {
-    assertToken(TokenType.DOUBLE, "12e4");
-  }
-  void test_double_whole_E() {
-    assertToken(TokenType.DOUBLE, "12E4");
-  }
-  void test_eq() {
-    assertToken(TokenType.EQ, "=");
-  }
-  void test_eq_eq() {
-    assertToken(TokenType.EQ_EQ, "==");
-  }
-  void test_gt() {
-    assertToken(TokenType.GT, ">");
-  }
-  void test_gt_eq() {
-    assertToken(TokenType.GT_EQ, ">=");
-  }
-  void test_gt_gt() {
-    assertToken(TokenType.GT_GT, ">>");
-  }
-  void test_gt_gt_eq() {
-    assertToken(TokenType.GT_GT_EQ, ">>=");
-  }
-  void test_hash() {
-    assertToken(TokenType.HASH, "#");
-  }
-  void test_hexidecimal() {
-    assertToken(TokenType.HEXADECIMAL, "0x1A2B3C");
-  }
-  void test_hexidecimal_missingDigit() {
-    assertError(ScannerErrorCode.MISSING_HEX_DIGIT, 1, "0x");
-  }
-  void test_identifier() {
-    assertToken(TokenType.IDENTIFIER, "result");
-  }
-  void test_illegalChar_cyrillicLetter_middle() {
-    assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 0, "Shche\u0433lov");
-  }
-  void test_illegalChar_cyrillicLetter_start() {
-    assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 0, "\u0429");
-  }
-  void test_illegalChar_nbsp() {
-    assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 0, "\u00A0");
-  }
-  void test_illegalChar_notLetter() {
-    assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 0, "\u0312");
-  }
-  void test_index() {
-    assertToken(TokenType.INDEX, "[]");
-  }
-  void test_index_eq() {
-    assertToken(TokenType.INDEX_EQ, "[]=");
-  }
-  void test_int() {
-    assertToken(TokenType.INT, "123");
-  }
-  void test_int_initialZero() {
-    assertToken(TokenType.INT, "0123");
-  }
-  void test_keyword_abstract() {
-    assertKeywordToken("abstract");
-  }
-  void test_keyword_as() {
-    assertKeywordToken("as");
-  }
-  void test_keyword_assert() {
-    assertKeywordToken("assert");
-  }
-  void test_keyword_break() {
-    assertKeywordToken("break");
-  }
-  void test_keyword_case() {
-    assertKeywordToken("case");
-  }
-  void test_keyword_catch() {
-    assertKeywordToken("catch");
-  }
-  void test_keyword_class() {
-    assertKeywordToken("class");
-  }
-  void test_keyword_const() {
-    assertKeywordToken("const");
-  }
-  void test_keyword_continue() {
-    assertKeywordToken("continue");
-  }
-  void test_keyword_default() {
-    assertKeywordToken("default");
-  }
-  void test_keyword_do() {
-    assertKeywordToken("do");
-  }
-  void test_keyword_dynamic() {
-    assertKeywordToken("dynamic");
-  }
-  void test_keyword_else() {
-    assertKeywordToken("else");
-  }
-  void test_keyword_enum() {
-    assertKeywordToken("enum");
-  }
-  void test_keyword_export() {
-    assertKeywordToken("export");
-  }
-  void test_keyword_extends() {
-    assertKeywordToken("extends");
-  }
-  void test_keyword_factory() {
-    assertKeywordToken("factory");
-  }
-  void test_keyword_false() {
-    assertKeywordToken("false");
-  }
-  void test_keyword_final() {
-    assertKeywordToken("final");
-  }
-  void test_keyword_finally() {
-    assertKeywordToken("finally");
-  }
-  void test_keyword_for() {
-    assertKeywordToken("for");
-  }
-  void test_keyword_get() {
-    assertKeywordToken("get");
-  }
-  void test_keyword_if() {
-    assertKeywordToken("if");
-  }
-  void test_keyword_implements() {
-    assertKeywordToken("implements");
-  }
-  void test_keyword_import() {
-    assertKeywordToken("import");
-  }
-  void test_keyword_in() {
-    assertKeywordToken("in");
-  }
-  void test_keyword_is() {
-    assertKeywordToken("is");
-  }
-  void test_keyword_library() {
-    assertKeywordToken("library");
-  }
-  void test_keyword_new() {
-    assertKeywordToken("new");
-  }
-  void test_keyword_null() {
-    assertKeywordToken("null");
-  }
-  void test_keyword_operator() {
-    assertKeywordToken("operator");
-  }
-  void test_keyword_part() {
-    assertKeywordToken("part");
-  }
-  void test_keyword_rethrow() {
-    assertKeywordToken("rethrow");
-  }
-  void test_keyword_return() {
-    assertKeywordToken("return");
-  }
-  void test_keyword_set() {
-    assertKeywordToken("set");
-  }
-  void test_keyword_static() {
-    assertKeywordToken("static");
-  }
-  void test_keyword_super() {
-    assertKeywordToken("super");
-  }
-  void test_keyword_switch() {
-    assertKeywordToken("switch");
-  }
-  void test_keyword_this() {
-    assertKeywordToken("this");
-  }
-  void test_keyword_throw() {
-    assertKeywordToken("throw");
-  }
-  void test_keyword_true() {
-    assertKeywordToken("true");
-  }
-  void test_keyword_try() {
-    assertKeywordToken("try");
-  }
-  void test_keyword_typedef() {
-    assertKeywordToken("typedef");
-  }
-  void test_keyword_var() {
-    assertKeywordToken("var");
-  }
-  void test_keyword_void() {
-    assertKeywordToken("void");
-  }
-  void test_keyword_while() {
-    assertKeywordToken("while");
-  }
-  void test_keyword_with() {
-    assertKeywordToken("with");
-  }
-  void test_lineInfo_multilineComment() {
-    String source = "/*\r *\r */";
-    assertLineInfo(source, [
-        new AbstractScannerTest_ExpectedLocation(0, 1, 1),
-        new AbstractScannerTest_ExpectedLocation(4, 2, 2),
-        new AbstractScannerTest_ExpectedLocation(source.length - 1, 3, 3)]);
-  }
-  void test_lineInfo_multilineString() {
-    String source = "'''a\r\nbc\r\nd'''";
-    assertLineInfo(source, [
-        new AbstractScannerTest_ExpectedLocation(0, 1, 1),
-        new AbstractScannerTest_ExpectedLocation(7, 2, 2),
-        new AbstractScannerTest_ExpectedLocation(source.length - 1, 3, 4)]);
-  }
-  void test_lineInfo_simpleClass() {
-    String source = "class Test {\r\n    String s = '...';\r\n    int get x => s.MISSING_GETTER;\r\n}";
-    assertLineInfo(source, [
-        new AbstractScannerTest_ExpectedLocation(0, 1, 1),
-        new AbstractScannerTest_ExpectedLocation(source.indexOf("MISSING_GETTER"), 3, 20),
-        new AbstractScannerTest_ExpectedLocation(source.length - 1, 4, 1)]);
-  }
-  void test_lineInfo_slashN() {
-    String source = "class Test {\n}";
-    assertLineInfo(source, [
-        new AbstractScannerTest_ExpectedLocation(0, 1, 1),
-        new AbstractScannerTest_ExpectedLocation(source.indexOf("}"), 2, 1)]);
-  }
-  void test_lt() {
-    assertToken(TokenType.LT, "<");
-  }
-  void test_lt_eq() {
-    assertToken(TokenType.LT_EQ, "<=");
-  }
-  void test_lt_lt() {
-    assertToken(TokenType.LT_LT, "<<");
-  }
-  void test_lt_lt_eq() {
-    assertToken(TokenType.LT_LT_EQ, "<<=");
-  }
-  void test_minus() {
-    assertToken(TokenType.MINUS, "-");
-  }
-  void test_minus_eq() {
-    assertToken(TokenType.MINUS_EQ, "-=");
-  }
-  void test_minus_minus() {
-    assertToken(TokenType.MINUS_MINUS, "--");
-  }
-  void test_open_curly_bracket() {
-    assertToken(TokenType.OPEN_CURLY_BRACKET, "{");
-  }
-  void test_open_paren() {
-    assertToken(TokenType.OPEN_PAREN, "(");
-  }
-  void test_open_square_bracket() {
-    assertToken(TokenType.OPEN_SQUARE_BRACKET, "[");
-  }
-  void test_openSquareBracket() {
-    assertToken(TokenType.OPEN_SQUARE_BRACKET, "[");
-  }
-  void test_percent() {
-    assertToken(TokenType.PERCENT, "%");
-  }
-  void test_percent_eq() {
-    assertToken(TokenType.PERCENT_EQ, "%=");
-  }
-  void test_period() {
-    assertToken(TokenType.PERIOD, ".");
-  }
-  void test_period_period() {
-    assertToken(TokenType.PERIOD_PERIOD, "..");
-  }
-  void test_period_period_period() {
-    assertToken(TokenType.PERIOD_PERIOD_PERIOD, "...");
-  }
-  void test_periodAfterNumberNotIncluded_identifier() {
-    assertTokens("42.isEven()", [
-        new StringToken(TokenType.INT, "42", 0),
-        new Token(TokenType.PERIOD, 2),
-        new StringToken(TokenType.IDENTIFIER, "isEven", 3),
-        new Token(TokenType.OPEN_PAREN, 9),
-        new Token(TokenType.CLOSE_PAREN, 10)]);
-  }
-  void test_periodAfterNumberNotIncluded_period() {
-    assertTokens("42..isEven()", [
-        new StringToken(TokenType.INT, "42", 0),
-        new Token(TokenType.PERIOD_PERIOD, 2),
-        new StringToken(TokenType.IDENTIFIER, "isEven", 4),
-        new Token(TokenType.OPEN_PAREN, 10),
-        new Token(TokenType.CLOSE_PAREN, 11)]);
-  }
-  void test_plus() {
-    assertToken(TokenType.PLUS, "+");
-  }
-  void test_plus_eq() {
-    assertToken(TokenType.PLUS_EQ, "+=");
-  }
-  void test_plus_plus() {
-    assertToken(TokenType.PLUS_PLUS, "++");
-  }
-  void test_question() {
-    assertToken(TokenType.QUESTION, "?");
-  }
-  void test_scriptTag_withArgs() {
-    assertToken(TokenType.SCRIPT_TAG, "#!/bin/dart -debug");
-  }
-  void test_scriptTag_withoutSpace() {
-    assertToken(TokenType.SCRIPT_TAG, "#!/bin/dart");
-  }
-  void test_scriptTag_withSpace() {
-    assertToken(TokenType.SCRIPT_TAG, "#! /bin/dart");
-  }
-  void test_semicolon() {
-    assertToken(TokenType.SEMICOLON, ";");
-  }
-  void test_slash() {
-    assertToken(TokenType.SLASH, "/");
-  }
-  void test_slash_eq() {
-    assertToken(TokenType.SLASH_EQ, "/=");
-  }
-  void test_star() {
-    assertToken(TokenType.STAR, "*");
-  }
-  void test_star_eq() {
-    assertToken(TokenType.STAR_EQ, "*=");
-  }
-  void test_startAndEnd() {
-    Token token = scan2("a");
-    Token previous = token.previous;
-    JUnitTestCase.assertEquals(token, previous.next);
-    JUnitTestCase.assertEquals(previous, previous.previous);
-    Token next = token.next;
-    JUnitTestCase.assertEquals(next, next.next);
-    JUnitTestCase.assertEquals(token, next.previous);
-  }
-  void test_string_multi_double() {
-    assertToken(TokenType.STRING, "\"\"\"line1\nline2\"\"\"");
-  }
-  void test_string_multi_embeddedQuotes() {
-    assertToken(TokenType.STRING, "\"\"\"line1\n\"\"\nline2\"\"\"");
-  }
-  void test_string_multi_embeddedQuotes_escapedChar() {
-    assertToken(TokenType.STRING, "\"\"\"a\"\"\\tb\"\"\"");
-  }
-  void test_string_multi_interpolation_block() {
-    assertTokens("\"Hello \${name}!\"", [
-        new StringToken(TokenType.STRING, "\"Hello ", 0),
-        new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 7),
-        new StringToken(TokenType.IDENTIFIER, "name", 9),
-        new Token(TokenType.CLOSE_CURLY_BRACKET, 13),
-        new StringToken(TokenType.STRING, "!\"", 14)]);
-  }
-  void test_string_multi_interpolation_identifier() {
-    assertTokens("\"Hello \$name!\"", [
-        new StringToken(TokenType.STRING, "\"Hello ", 0),
-        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 7),
-        new StringToken(TokenType.IDENTIFIER, "name", 8),
-        new StringToken(TokenType.STRING, "!\"", 12)]);
-  }
-  void test_string_multi_single() {
-    assertToken(TokenType.STRING, "'''string'''");
-  }
-  void test_string_multi_slashEnter() {
-    assertError(ScannerErrorCode.CHARACTER_EXPECTED_AFTER_SLASH, 0, "'''\\\n'''");
-  }
-  void test_string_multi_unterminated() {
-    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 8, "'''string");
-  }
-  void test_string_raw_multi_double() {
-    assertToken(TokenType.STRING, "r\"\"\"line1\nline2\"\"\"");
-  }
-  void test_string_raw_multi_single() {
-    assertToken(TokenType.STRING, "r'''string'''");
-  }
-  void test_string_raw_multi_unterminated() {
-    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 9, "r'''string");
-  }
-  void test_string_raw_simple_double() {
-    assertToken(TokenType.STRING, "r\"string\"");
-  }
-  void test_string_raw_simple_single() {
-    assertToken(TokenType.STRING, "r'string'");
-  }
-  void test_string_raw_simple_unterminated_eof() {
-    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 7, "r'string");
-  }
-  void test_string_raw_simple_unterminated_eol() {
-    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 8, "r'string\n");
-  }
-  void test_string_simple_double() {
-    assertToken(TokenType.STRING, "\"string\"");
-  }
-  void test_string_simple_escapedDollar() {
-    assertToken(TokenType.STRING, "'a\\\$b'");
-  }
-  void test_string_simple_interpolation_adjacentIdentifiers() {
-    assertTokens("'\$a\$b'", [
-        new StringToken(TokenType.STRING, "'", 0),
-        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1),
-        new StringToken(TokenType.IDENTIFIER, "a", 2),
-        new StringToken(TokenType.STRING, "", 3),
-        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 3),
-        new StringToken(TokenType.IDENTIFIER, "b", 4),
-        new StringToken(TokenType.STRING, "'", 5)]);
-  }
-  void test_string_simple_interpolation_block() {
-    assertTokens("'Hello \${name}!'", [
-        new StringToken(TokenType.STRING, "'Hello ", 0),
-        new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 7),
-        new StringToken(TokenType.IDENTIFIER, "name", 9),
-        new Token(TokenType.CLOSE_CURLY_BRACKET, 13),
-        new StringToken(TokenType.STRING, "!'", 14)]);
-  }
-  void test_string_simple_interpolation_blockWithNestedMap() {
-    assertTokens("'a \${f({'b' : 'c'})} d'", [
-        new StringToken(TokenType.STRING, "'a ", 0),
-        new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 3),
-        new StringToken(TokenType.IDENTIFIER, "f", 5),
-        new Token(TokenType.OPEN_PAREN, 6),
-        new Token(TokenType.OPEN_CURLY_BRACKET, 7),
-        new StringToken(TokenType.STRING, "'b'", 8),
-        new Token(TokenType.COLON, 12),
-        new StringToken(TokenType.STRING, "'c'", 14),
-        new Token(TokenType.CLOSE_CURLY_BRACKET, 17),
-        new Token(TokenType.CLOSE_PAREN, 18),
-        new Token(TokenType.CLOSE_CURLY_BRACKET, 19),
-        new StringToken(TokenType.STRING, " d'", 20)]);
-  }
-  void test_string_simple_interpolation_firstAndLast() {
-    assertTokens("'\$greeting \$name'", [
-        new StringToken(TokenType.STRING, "'", 0),
-        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1),
-        new StringToken(TokenType.IDENTIFIER, "greeting", 2),
-        new StringToken(TokenType.STRING, " ", 10),
-        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 11),
-        new StringToken(TokenType.IDENTIFIER, "name", 12),
-        new StringToken(TokenType.STRING, "'", 16)]);
-  }
-  void test_string_simple_interpolation_identifier() {
-    assertTokens("'Hello \$name!'", [
-        new StringToken(TokenType.STRING, "'Hello ", 0),
-        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 7),
-        new StringToken(TokenType.IDENTIFIER, "name", 8),
-        new StringToken(TokenType.STRING, "!'", 12)]);
-  }
-  void test_string_simple_interpolation_missingIdentifier() {
-    assertTokens("'\$x\$'", [
-        new StringToken(TokenType.STRING, "'", 0),
-        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1),
-        new StringToken(TokenType.IDENTIFIER, "x", 2),
-        new StringToken(TokenType.STRING, "", 3),
-        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 3),
-        new StringToken(TokenType.STRING, "'", 4)]);
-  }
-  void test_string_simple_interpolation_nonIdentifier() {
-    assertTokens("'\$1'", [
-        new StringToken(TokenType.STRING, "'", 0),
-        new StringToken(TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 1),
-        new StringToken(TokenType.STRING, "1'", 2)]);
-  }
-  void test_string_simple_single() {
-    assertToken(TokenType.STRING, "'string'");
-  }
-  void test_string_simple_unterminated_eof() {
-    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 6, "'string");
-  }
-  void test_string_simple_unterminated_eol() {
-    assertError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 7, "'string\r");
-  }
-  void test_tilde() {
-    assertToken(TokenType.TILDE, "~");
-  }
-  void test_tilde_slash() {
-    assertToken(TokenType.TILDE_SLASH, "~/");
-  }
-  void test_tilde_slash_eq() {
-    assertToken(TokenType.TILDE_SLASH_EQ, "~/=");
-  }
-  void test_unclosedPairInInterpolation() {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    scan("'\${(}'", listener);
-  }
-  Token scan(String source, GatheringErrorListener listener);
-  void assertComment(TokenType commentType, String source) {
-    Token token = scan2(source);
-    JUnitTestCase.assertNotNull(token);
-    JUnitTestCase.assertEquals(TokenType.EOF, token.type);
-    Token comment = token.precedingComments;
-    JUnitTestCase.assertNotNull(comment);
-    JUnitTestCase.assertEquals(commentType, comment.type);
-    JUnitTestCase.assertEquals(0, comment.offset);
-    JUnitTestCase.assertEquals(source.length, comment.length);
-    JUnitTestCase.assertEquals(source, comment.lexeme);
-    token = scan2("${source}\n");
-    JUnitTestCase.assertNotNull(token);
-    JUnitTestCase.assertEquals(TokenType.EOF, token.type);
-    comment = token.precedingComments;
-    JUnitTestCase.assertNotNull(comment);
-    JUnitTestCase.assertEquals(commentType, comment.type);
-    JUnitTestCase.assertEquals(0, comment.offset);
-    JUnitTestCase.assertEquals(source.length, comment.length);
-    JUnitTestCase.assertEquals(source, comment.lexeme);
-  }
-
-  /**
-   * Assert that scanning the given source produces an error with the given code.
-   *
-   * @param illegalCharacter
-   * @param i
-   * @param source the source to be scanned to produce the error
-   */
-  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])]);
-  }
-
-  /**
-   * Assert that when scanned the given source contains a single keyword token with the same lexeme
-   * as the original source.
-   *
-   * @param source the source to be scanned
-   */
-  void assertKeywordToken(String source) {
-    Token token = scan2(source);
-    JUnitTestCase.assertNotNull(token);
-    JUnitTestCase.assertEquals(TokenType.KEYWORD, token.type);
-    JUnitTestCase.assertEquals(0, token.offset);
-    JUnitTestCase.assertEquals(source.length, token.length);
-    JUnitTestCase.assertEquals(source, token.lexeme);
-    Object value = token.value();
-    JUnitTestCase.assertTrue(value is Keyword);
-    JUnitTestCase.assertEquals(source, ((value as Keyword)).syntax);
-    token = scan2(" ${source} ");
-    JUnitTestCase.assertNotNull(token);
-    JUnitTestCase.assertEquals(TokenType.KEYWORD, token.type);
-    JUnitTestCase.assertEquals(1, token.offset);
-    JUnitTestCase.assertEquals(source.length, token.length);
-    JUnitTestCase.assertEquals(source, token.lexeme);
-    value = token.value();
-    JUnitTestCase.assertTrue(value is Keyword);
-    JUnitTestCase.assertEquals(source, ((value as Keyword)).syntax);
-    JUnitTestCase.assertEquals(TokenType.EOF, token.next.type);
-  }
-  void assertLineInfo(String source, List<AbstractScannerTest_ExpectedLocation> expectedLocations) {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    scan(source, listener);
-    listener.assertNoErrors();
-    LineInfo info = listener.getLineInfo(new TestSource());
-    JUnitTestCase.assertNotNull(info);
-    for (AbstractScannerTest_ExpectedLocation expectedLocation in expectedLocations) {
-      LineInfo_Location location = info.getLocation(expectedLocation._offset);
-      JUnitTestCase.assertEquals(expectedLocation._lineNumber, location.lineNumber);
-      JUnitTestCase.assertEquals(expectedLocation._columnNumber, location.columnNumber);
-    }
-  }
-
-  /**
-   * Assert that the token scanned from the given source has the expected type.
-   *
-   * @param expectedType the expected type of the token
-   * @param source the source to be scanned to produce the actual token
-   */
-  Token assertToken(TokenType expectedType, String source) {
-    Token originalToken = scan2(source);
-    JUnitTestCase.assertNotNull(originalToken);
-    JUnitTestCase.assertEquals(expectedType, originalToken.type);
-    JUnitTestCase.assertEquals(0, originalToken.offset);
-    JUnitTestCase.assertEquals(source.length, originalToken.length);
-    JUnitTestCase.assertEquals(source, originalToken.lexeme);
-    if (identical(expectedType, TokenType.SCRIPT_TAG)) {
-      return originalToken;
-    } else if (identical(expectedType, TokenType.SINGLE_LINE_COMMENT)) {
-      Token tokenWithSpaces = scan2(" ${source}");
-      JUnitTestCase.assertNotNull(tokenWithSpaces);
-      JUnitTestCase.assertEquals(expectedType, tokenWithSpaces.type);
-      JUnitTestCase.assertEquals(1, tokenWithSpaces.offset);
-      JUnitTestCase.assertEquals(source.length, tokenWithSpaces.length);
-      JUnitTestCase.assertEquals(source, tokenWithSpaces.lexeme);
-      return originalToken;
-    } else if (identical(expectedType, TokenType.INT) || identical(expectedType, TokenType.DOUBLE)) {
-      Token tokenWithLowerD = scan2("${source}d");
-      JUnitTestCase.assertNotNull(tokenWithLowerD);
-      JUnitTestCase.assertEquals(expectedType, tokenWithLowerD.type);
-      JUnitTestCase.assertEquals(0, tokenWithLowerD.offset);
-      JUnitTestCase.assertEquals(source.length, tokenWithLowerD.length);
-      JUnitTestCase.assertEquals(source, tokenWithLowerD.lexeme);
-      Token tokenWithUpperD = scan2("${source}D");
-      JUnitTestCase.assertNotNull(tokenWithUpperD);
-      JUnitTestCase.assertEquals(expectedType, tokenWithUpperD.type);
-      JUnitTestCase.assertEquals(0, tokenWithUpperD.offset);
-      JUnitTestCase.assertEquals(source.length, tokenWithUpperD.length);
-      JUnitTestCase.assertEquals(source, tokenWithUpperD.lexeme);
-    }
-    Token tokenWithSpaces = scan2(" ${source} ");
-    JUnitTestCase.assertNotNull(tokenWithSpaces);
-    JUnitTestCase.assertEquals(expectedType, tokenWithSpaces.type);
-    JUnitTestCase.assertEquals(1, tokenWithSpaces.offset);
-    JUnitTestCase.assertEquals(source.length, tokenWithSpaces.length);
-    JUnitTestCase.assertEquals(source, tokenWithSpaces.lexeme);
-    JUnitTestCase.assertEquals(TokenType.EOF, originalToken.next.type);
-    return originalToken;
-  }
-
-  /**
-   * Assert that when scanned the given source contains a sequence of tokens identical to the given
-   * tokens.
-   *
-   * @param source the source to be scanned
-   * @param expectedTokens the tokens that are expected to be in the source
-   */
-  void assertTokens(String source, List<Token> expectedTokens) {
-    Token token = scan2(source);
-    JUnitTestCase.assertNotNull(token);
-    for (int i = 0; i < expectedTokens.length; i++) {
-      Token expectedToken = expectedTokens[i];
-      JUnitTestCase.assertEqualsMsg("Wrong type for token ${i}", expectedToken.type, token.type);
-      JUnitTestCase.assertEqualsMsg("Wrong offset for token ${i}", expectedToken.offset, token.offset);
-      JUnitTestCase.assertEqualsMsg("Wrong length for token ${i}", expectedToken.length, token.length);
-      JUnitTestCase.assertEqualsMsg("Wrong lexeme for token ${i}", expectedToken.lexeme, token.lexeme);
-      token = token.next;
-      JUnitTestCase.assertNotNull(token);
-    }
-    JUnitTestCase.assertEquals(TokenType.EOF, token.type);
-  }
-  Token scan2(String source) {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    Token token = scan(source, listener);
-    listener.assertNoErrors();
-    return token;
-  }
-}
-/**
- * Instances of the class `ExpectedLocation` encode information about the expected location
- * of a given offset in source code.
- */
-class AbstractScannerTest_ExpectedLocation {
-  int _offset = 0;
-  int _lineNumber = 0;
-  int _columnNumber = 0;
-  AbstractScannerTest_ExpectedLocation(int offset, int lineNumber, int columnNumber) {
-    this._offset = offset;
-    this._lineNumber = lineNumber;
-    this._columnNumber = columnNumber;
-  }
-}
-main() {
-  CharBufferScannerTest.dartSuite();
-  KeywordStateTest.dartSuite();
-  StringScannerTest.dartSuite();
-  TokenTypeTest.dartSuite();
-}
\ No newline at end of file
diff --git a/pkg/custom_element/lib/custom-elements.debug.js b/pkg/custom_element/lib/custom-elements.debug.js
index 510dc2c..11ae624 100644
--- a/pkg/custom_element/lib/custom-elements.debug.js
+++ b/pkg/custom_element/lib/custom-elements.debug.js
@@ -1176,7 +1176,7 @@
     // HTMLElement.prototype, so we add a test
     // the idea is to avoid mixing in native prototypes, so adding
     // the second test is WLOG
-    while (p !== inNative && p !== HTMLUnknownElement.prototype) {
+    while (p && p !== inNative && p !== HTMLUnknownElement.prototype) {
       var keys = Object.getOwnPropertyNames(p);
       for (var i=0, k; k=keys[i]; i++) {
         if (!used[k]) {
diff --git a/pkg/custom_element/lib/custom-elements.min.js b/pkg/custom_element/lib/custom-elements.min.js
index 5ed2b0d..68a7b78 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.performedInitialDocumentUpgrade)&&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),CustomElements.performedInitialDocumentUpgrade=!0;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(){function a(){}if(HTMLElement.prototype.createShadowRoot){var b=HTMLElement.prototype.createShadowRoot;HTMLElement.prototype.createShadowRoot=function(){var a=b.call(this);return a.host=this,a}}if(window.ShadowDOMPolyfill){CustomElements.watchShadow=a,CustomElements.watchAllShadows=a;var c=["upgradeAll","upgradeSubtree","observeDocument","upgradeDocument"],d={};c.forEach(function(a){d[a]=CustomElements[a]}),c.forEach(function(a){CustomElements[a]=function(b){return d[a](ShadowDOMPolyfill.wrapIfNeeded(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.performedInitialDocumentUpgrade)&&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&&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),CustomElements.performedInitialDocumentUpgrade=!0;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(){function a(){}if(HTMLElement.prototype.createShadowRoot){var b=HTMLElement.prototype.createShadowRoot;HTMLElement.prototype.createShadowRoot=function(){var a=b.call(this);return a.host=this,a}}if(window.ShadowDOMPolyfill){CustomElements.watchShadow=a,CustomElements.watchAllShadows=a;var c=["upgradeAll","upgradeSubtree","observeDocument","upgradeDocument"],d={};c.forEach(function(a){d[a]=CustomElements[a]}),c.forEach(function(a){CustomElements[a]=function(b){return d[a](ShadowDOMPolyfill.wrapIfNeeded(b))}})}}();
diff --git a/pkg/custom_element/lib/custom_element.dart b/pkg/custom_element/lib/custom_element.dart
index acabe00..02c7569 100644
--- a/pkg/custom_element/lib/custom_element.dart
+++ b/pkg/custom_element/lib/custom_element.dart
@@ -110,27 +110,6 @@
   /** Invoked when any attribute of the component is modified. */
   void attributeChanged(String name, String oldValue) {}
 
-  get model => host.model;
-
-  void set model(newModel) {
-    host.model = newModel;
-  }
-
-  get templateInstance => host.templateInstance;
-  get isTemplate => host.isTemplate;
-  get ref => host.ref;
-  get content => host.content;
-  DocumentFragment createInstance(model, [BindingDelegate delegate]) =>
-      host.createInstance(model, delegate);
-  createBinding(String name, model, String path) =>
-      host.createBinding(name, model, path);
-  bind(String name, model, String path) => host.bind(name, model, path);
-  void unbind(String name) => host.unbind(name);
-  void unbindAll() => host.unbindAll();
-  get bindings => host.bindings;
-  BindingDelegate get bindingDelegate => host.bindingDelegate;
-  set bindingDelegate(BindingDelegate value) { host.bindingDelegate = value; }
-
   // TODO(efortuna): Update these when we decide what to do with these
   // properties.
   @deprecated
diff --git a/pkg/fixnum/lib/fixnum.dart b/pkg/fixnum/lib/fixnum.dart
index 72a0c50..fe21c47 100644
--- a/pkg/fixnum/lib/fixnum.dart
+++ b/pkg/fixnum/lib/fixnum.dart
@@ -14,8 +14,6 @@
  */
 library fixnum;
 
-import 'package:meta/meta.dart';
-
 part 'src/intx.dart';
 part 'src/int32.dart';
 part 'src/int64.dart';
diff --git a/pkg/fixnum/lib/src/int32.dart b/pkg/fixnum/lib/src/int32.dart
index d700040..b2da0fa 100644
--- a/pkg/fixnum/lib/src/int32.dart
+++ b/pkg/fixnum/lib/src/int32.dart
@@ -138,13 +138,6 @@
    */
   Int32([int i=0]) : _i = (i & 0x7fffffff) - (i & 0x80000000);
 
-  /**
-   * Constructs an [Int32] from an [int].  Only the low 32 bits of the input
-   * are used.
-   */
-  @deprecated
-  Int32.fromInt(int i) : this(i);
-
   // Returns the [int] representation of the specified value. Throws
   // [ArgumentError] for non-integer arguments.
   int _toInt(val) {
diff --git a/pkg/fixnum/lib/src/int64.dart b/pkg/fixnum/lib/src/int64.dart
index 192b11f..7801920 100644
--- a/pkg/fixnum/lib/src/int64.dart
+++ b/pkg/fixnum/lib/src/int64.dart
@@ -148,12 +148,6 @@
     return new Int64._bits(v0, v1, v2);
   }
 
-  /**
-   * Constructs an [Int64] with a given [int] value.
-   */
-  @deprecated
-  factory Int64.fromInt(int value) => new Int64(value);
-
   factory Int64.fromBytes(List<int> bytes) {
     int top = bytes[7] & 0xff;
     top <<= 8;
diff --git a/pkg/fixnum/pubspec.yaml b/pkg/fixnum/pubspec.yaml
index 336c9e6..c582394 100644
--- a/pkg/fixnum/pubspec.yaml
+++ b/pkg/fixnum/pubspec.yaml
@@ -2,7 +2,5 @@
 author: Dart Team <misc@dartlang.org>
 description: Library for 32- and 64-bit fixed size integers.
 homepage: http://www.dartlang.org
-dependencies:
-  meta: any
 dev_dependencies:
   unittest: any
diff --git a/pkg/http_server/pubspec.yaml b/pkg/http_server/pubspec.yaml
index 7292837..10896aa 100644
--- a/pkg/http_server/pubspec.yaml
+++ b/pkg/http_server/pubspec.yaml
@@ -5,5 +5,6 @@
 documentation: http://api.dartlang.org/docs/pkg/http_server
 dependencies:
   mime: any
+  path: any
 dev_dependencies:
   unittest: any
diff --git a/pkg/intl/lib/extract_messages.dart b/pkg/intl/lib/extract_messages.dart
index 412c3a8..e57574d 100644
--- a/pkg/intl/lib/extract_messages.dart
+++ b/pkg/intl/lib/extract_messages.dart
@@ -11,7 +11,7 @@
  * and [parseFile] methods which
  * can extract messages that conform to the expected pattern:
  *       (parameters) => Intl.message("Message $parameters", desc: ...);
- * It uses the analyzer_experimental package to do the parsing, so may
+ * It uses the analyzer package to do the parsing, so may
  * break if there are changes to the API that it provides.
  * An example can be found in test/message_extraction/extract_to_json.dart
  *
@@ -23,7 +23,7 @@
 
 import 'dart:io';
 
-import 'package:analyzer_experimental/analyzer.dart';
+import 'package:analyzer/analyzer.dart';
 import 'package:intl/src/intl_message.dart';
 
 /**
diff --git a/pkg/intl/lib/src/intl_message.dart b/pkg/intl/lib/src/intl_message.dart
index 7da13ee..13aad62 100644
--- a/pkg/intl/lib/src/intl_message.dart
+++ b/pkg/intl/lib/src/intl_message.dart
@@ -33,7 +33,7 @@
  */
 library intl_message;
 
-import 'package:analyzer_experimental/analyzer.dart';
+import 'package:analyzer/analyzer.dart';
 
 /** A default function for the [Message.expanded] method. */
 _nullTransform(msg, chunk) => chunk;
diff --git a/pkg/intl/pubspec.yaml b/pkg/intl/pubspec.yaml
index a1bd29e..9cccb36 100644
--- a/pkg/intl/pubspec.yaml
+++ b/pkg/intl/pubspec.yaml
@@ -4,7 +4,7 @@
 homepage: http://www.dartlang.org
 documentation: http://api.dartlang.org/docs/pkg/intl
 dependencies:
-  analyzer_experimental: any
+  analyzer: any
   meta: any
   path: any
 dev_dependencies:
diff --git a/pkg/logging/lib/logging.dart b/pkg/logging/lib/logging.dart
index 3376145..071b496 100644
--- a/pkg/logging/lib/logging.dart
+++ b/pkg/logging/lib/logging.dart
@@ -5,9 +5,8 @@
 /**
  * Support for debugging and error logging.
  *
- * This library introduces abstractions similar to
- * those used in other languages, such as the Closure JS
- * Logger and java.util.logging.Logger.
+ * This library introduces abstractions similar to those used in other
+ * languages, such as the Closure JS Logger and java.util.logging.Logger.
  *
  * For information on installing and importing this library, see the
  * [logging package on pub.dartlang.org]
@@ -16,6 +15,8 @@
 library logging;
 
 import 'dart:async';
+import 'package:meta/meta.dart';
+import 'package:unmodifiable_collection/unmodifiable_collection.dart';
 
 /**
  * Whether to allow fine-grain logging and configuration of loggers in a
@@ -48,26 +49,26 @@
   /** Logging [Level] used for entries generated on this logger. */
   Level _level;
 
+  final Map<String, Logger> _children;
+
   /** Children in the hierarchy of loggers, indexed by their simple names. */
-  Map<String, Logger> children;
+  final Map<String, Logger> children;
 
   /** Controller used to notify when log entries are added to this logger. */
   StreamController<LogRecord> _controller;
 
-  /** The broadcast stream associated with the controller. */
-  Stream _stream;
-
   /**
    * Singleton constructor. Calling `new Logger(name)` will return the same
    * actual instance whenever it is called with the same string name.
    */
   factory Logger(String name) {
+    return _loggers.putIfAbsent(name, () => new Logger._named(name));
+  }
+
+  factory Logger._named(String name) {
     if (name.startsWith('.')) {
       throw new ArgumentError("name shouldn't start with a '.'");
     }
-    if (_loggers == null) _loggers = <String, Logger>{};
-    if (_loggers.containsKey(name)) return _loggers[name];
-
     // Split hierarchical names (separated with '.').
     int dot = name.lastIndexOf('.');
     Logger parent = null;
@@ -79,14 +80,13 @@
       parent = new Logger(name.substring(0, dot));
       thisName = name.substring(dot + 1);
     }
-    final res = new Logger._internal(thisName, parent);
-    _loggers[name] = res;
-    return res;
+    return new Logger._internal(thisName, parent, new Map<String, Logger>());
   }
 
-  Logger._internal(this.name, this.parent)
-      : children = new Map<String, Logger>() {
-    if (parent != null) parent.children[name] = this;
+  Logger._internal(this.name, this.parent, Map<String, Logger> children) :
+    this._children = children,
+    this.children = new UnmodifiableMapView(children) {
+    if (parent != null) parent._children[name] = this;
   }
 
   /**
@@ -102,7 +102,7 @@
   }
 
   /** Override the level for this particular [Logger] and its children. */
-  set level(Level value) {
+  void set level(Level value) {
     if (hierarchicalLoggingEnabled && parent != null) {
       _level = value;
     } else {
@@ -138,14 +138,18 @@
 
   /**
    * Adds a log record for a [message] at a particular [logLevel] if
-   * `isLoggable(logLevel)` is true. Use this method to create log entries for
-   * user-defined levels. To record a message at a predefined level (e.g.
-   * [Level.INFO], [Level.WARNING], etc) you can use their specialized methods
-   * instead (e.g. [info], [warning], etc).
+   * `isLoggable(logLevel)` is true.
+   *
+   * Use this method to create log entries for user-defined levels. To record a
+   * message at a predefined level (e.g. [Level.INFO], [Level.WARNING], etc) you
+   * can use their specialized methods instead (e.g. [info], [warning], etc).
    */
-  void log(Level logLevel, String message, [exception]) {
+  void log(Level logLevel, String message, [Object error,
+                                            StackTrace stackTrace]) {
     if (isLoggable(logLevel)) {
-      var record = new LogRecord(logLevel, message, fullName, exception);
+      var record = new LogRecord(logLevel, message, fullName, error,
+          stackTrace);
+
       if (hierarchicalLoggingEnabled) {
         var target = this;
         while (target != null) {
@@ -159,44 +163,43 @@
   }
 
   /** Log message at level [Level.FINEST]. */
-  void finest(String message, [exception]) =>
-      log(Level.FINEST, message, exception);
+  void finest(String message, [Object error, StackTrace stackTrace]) =>
+      log(Level.FINEST, message, error, stackTrace);
 
   /** Log message at level [Level.FINER]. */
-  void finer(String message, [exception]) =>
-      log(Level.FINER, message, exception);
+  void finer(String message, [Object error, StackTrace stackTrace]) =>
+      log(Level.FINER, message, error, stackTrace);
 
   /** Log message at level [Level.FINE]. */
-  void fine(String message, [exception]) =>
-      log(Level.FINE, message, exception);
+  void fine(String message, [Object error, StackTrace stackTrace]) =>
+      log(Level.FINE, message, error, stackTrace);
 
   /** Log message at level [Level.CONFIG]. */
-  void config(String message, [exception]) =>
-      log(Level.CONFIG, message, exception);
+  void config(String message, [Object error, StackTrace stackTrace]) =>
+      log(Level.CONFIG, message, error, stackTrace);
 
   /** Log message at level [Level.INFO]. */
-  void info(String message, [exception]) =>
-      log(Level.INFO, message, exception);
+  void info(String message, [Object error, StackTrace stackTrace]) =>
+      log(Level.INFO, message, error, stackTrace);
 
   /** Log message at level [Level.WARNING]. */
-  void warning(String message, [exception]) =>
-      log(Level.WARNING, message, exception);
+  void warning(String message, [Object error, StackTrace stackTrace]) =>
+      log(Level.WARNING, message, error, stackTrace);
 
   /** Log message at level [Level.SEVERE]. */
-  void severe(String message, [exception]) =>
-      log(Level.SEVERE, message, exception);
+  void severe(String message, [Object error, StackTrace stackTrace]) =>
+      log(Level.SEVERE, message, error, stackTrace);
 
   /** Log message at level [Level.SHOUT]. */
-  void shout(String message, [exception]) =>
-      log(Level.SHOUT, message, exception);
+  void shout(String message, [Object error, StackTrace stackTrace]) =>
+      log(Level.SHOUT, message, error, stackTrace);
 
   Stream<LogRecord> _getStream() {
     if (hierarchicalLoggingEnabled || parent == null) {
       if (_controller == null) {
         _controller = new StreamController<LogRecord>.broadcast(sync: true);
-        _stream = _controller.stream;
       }
-      return _stream;
+      return _controller.stream;
     } else {
       return root._getStream();
     }
@@ -212,7 +215,7 @@
   static Logger get root => new Logger('');
 
   /** All [Logger]s in the system. */
-  static Map<String, Logger> _loggers;
+  static final Map<String, Logger> _loggers = <String, Logger>{};
 }
 
 
@@ -233,7 +236,6 @@
  */
 class Level implements Comparable<Level> {
 
-  // TODO(sigmund): mark name/value as 'const' when the language supports it.
   final String name;
 
   /**
@@ -274,7 +276,7 @@
   /** Key for extra debugging loudness ([value] = 1200). */
   static const Level SHOUT = const Level('SHOUT', 1200);
 
-  bool operator ==(Level other) => other != null && value == other.value;
+  bool operator ==(Object other) => other is Level && value == other.value;
   bool operator <(Level other) => value < other.value;
   bool operator <=(Level other) => value <= other.value;
   bool operator >(Level other) => value > other.value;
@@ -304,10 +306,21 @@
 
   static int _nextNumber = 0;
 
-  /** Associated exception (if any) when recording errors messages. */
-  var exception;
+  /** Associated error (if any) when recording errors messages. */
+  final Object error;
 
-  LogRecord(this.level, this.message, this.loggerName, [this.exception])
+  // TODO(kevmoo) - remove before V1
+  /**
+   * DEPRECATED. Use [error] instead.
+   */
+  @deprecated
+  Object get exception => error;
+
+  /** Associated stackTrace (if any) when recording errors messages. */
+  final StackTrace stackTrace;
+
+  LogRecord(this.level, this.message, this.loggerName, [this.error,
+                                                        this.stackTrace])
       : time = new DateTime.now(),
         sequenceNumber = LogRecord._nextNumber++;
 
diff --git a/pkg/logging/pubspec.yaml b/pkg/logging/pubspec.yaml
index 37ed46e..c23bd3e 100644
--- a/pkg/logging/pubspec.yaml
+++ b/pkg/logging/pubspec.yaml
@@ -3,5 +3,8 @@
 description: Provides APIs for debugging and error logging. This library introduces abstractions similar to those used in other languages, such as the Closure JS Logger and java.util.logging.Logger.
 homepage: http://www.dartlang.org
 documentation: http://api.dartlang.org/docs/pkg/logging
+dependencies:
+  meta: any
+  unmodifiable_collection: any
 dev_dependencies:
   unittest: any
diff --git a/pkg/logging/test/logging_test.dart b/pkg/logging/test/logging_test.dart
index a631e8c..1c97350 100644
--- a/pkg/logging/test/logging_test.dart
+++ b/pkg/logging/test/logging_test.dart
@@ -24,8 +24,8 @@
     expect(level2 > level1, isTrue);
 
     var level3 = const Level('NOT_REAL3', 253);
-    expect(!identical(level1, level3), isTrue); // different instances
-    expect(level1 == level3, isTrue); // same value.
+    expect(level1, isNot(same(level3))); // different instances
+    expect(level1, equals(level3)); // same value.
   });
 
   test('default levels are in order', () {
@@ -60,8 +60,8 @@
     var map = new Map<Level, String>();
     map[Level.INFO] = 'info';
     map[Level.SHOUT] = 'shout';
-    expect(map[Level.INFO], equals('info'));
-    expect(map[Level.SHOUT], equals('shout'));
+    expect(map[Level.INFO], same('info'));
+    expect(map[Level.SHOUT], same('shout'));
   });
 
   test('logger name cannot start with a "." ', () {
@@ -90,10 +90,10 @@
     Logger a = new Logger('a');
     Logger b = new Logger('a.b');
     Logger c = new Logger('a.c');
-    expect(a == b.parent, isTrue);
-    expect(a == c.parent, isTrue);
-    expect(a.children['b'] == b, isTrue);
-    expect(a.children['c'] == c, isTrue);
+    expect(a, same(b.parent));
+    expect(a, same(c.parent));
+    expect(a.children['b'], same(b));
+    expect(a.children['c'], same(c));
   });
 
   test('loggers are singletons', () {
@@ -101,10 +101,57 @@
     Logger a2 = new Logger('a');
     Logger b = new Logger('a.b');
     Logger root = Logger.root;
-    expect(identical(a1, a2), isTrue);
-    expect(identical(a1, b.parent), isTrue);
-    expect(identical(root, a1.parent), isTrue);
-    expect(identical(root, new Logger('')), isTrue);
+    expect(a1, same(a2));
+    expect(a1, same(b.parent));
+    expect(root, same(a1.parent));
+    expect(root, same(new Logger('')));
+  });
+
+  test('cannot directly manipulate Logger.children', () {
+    var loggerAB = new Logger('a.b');
+    var loggerA = loggerAB.parent;
+
+    expect(loggerA.children['b'], same(loggerAB), reason: 'can read Children');
+
+    expect(() {
+        loggerAB.children['test'] = null;
+    }, throwsUnsupportedError, reason: 'Children is read-only');
+  });
+
+  test('stackTrace gets throw to LogRecord', () {
+    Logger.root.level = Level.INFO;
+
+    var records = new List<LogRecord>();
+
+    var sub = Logger.root.onRecord.listen(records.add);
+
+    try {
+      throw new UnsupportedError('test exception');
+    } catch(error, stack) {
+      Logger.root.log(Level.SEVERE, 'severe', error, stack);
+      Logger.root.warning('warning', error, stack);
+    }
+
+    Logger.root.log(Level.SHOUT, 'shout');
+
+    sub.cancel();
+
+    expect(records, hasLength(3));
+
+    var severe = records[0];
+    expect(severe.message, 'severe');
+    expect(severe.error is UnsupportedError, isTrue);
+    expect(severe.stackTrace is StackTrace, isTrue);
+
+    var warning = records[1];
+    expect(warning.message, 'warning');
+    expect(warning.error is UnsupportedError, isTrue);
+    expect(warning.stackTrace is StackTrace, isTrue);
+
+    var shout = records[2];
+    expect(shout.message, 'shout');
+    expect(shout.error, isNull);
+    expect(shout.stackTrace, isNull);
   });
 
   group('mutating levels', () {
@@ -134,7 +181,7 @@
     });
 
     test('cannot set level if hierarchy is disabled', () {
-      expect(() {a.level = Level.FINE;}, throws);
+      expect(() {a.level = Level.FINE;}, throwsUnsupportedError);
     });
 
     test('loggers effective level - no hierarchy', () {
@@ -176,7 +223,7 @@
       expect(root.isLoggable(Level.WARNING), isFalse);
       expect(c.isLoggable(Level.FINEST), isTrue);
       expect(c.isLoggable(Level.FINE), isTrue);
-      expect(!e.isLoggable(Level.SHOUT), isTrue);
+      expect(e.isLoggable(Level.SHOUT), isFalse);
     });
 
     test('add/remove handlers - no hierarchy', () {
diff --git a/pkg/meta/lib/meta.dart b/pkg/meta/lib/meta.dart
index e3e4a25..98177b9 100644
--- a/pkg/meta/lib/meta.dart
+++ b/pkg/meta/lib/meta.dart
@@ -4,8 +4,10 @@
 
 /**
  * Constants for use in metadata annotations such as
- * `@deprecated`, `@override`, and `@proxy`.
- * 
+ * `@proxy`.
+ *
+ * See also `@deprecated` and `@override` in the `dart:core` library.
+ *
  * Annotations provide semantic information
  * that tools can use to provide a better user experience.
  * For example, an IDE might not autocomplete
@@ -22,29 +24,6 @@
 library meta;
 
 /**
- * An annotation used to mark a class, field, getter, setter, method, top-level
- * variable, or top-level function as one that should no longer be used. Tools
- * can use this annotation to provide a warning on references to the marked
- * element.
- */
-const deprecated = const _Deprecated();
-
-class _Deprecated {
-  const _Deprecated();
-}
-
-/**
- * An annotation used to mark an instance member (method, field, getter or
- * setter) as overriding an inherited class member. Tools can use this
- * annotation to provide a warning if there is no overridden member.
- */
-const override = const _Override();
-
-class _Override {
-  const _Override();
-}
-
-/**
  * An annotation used to mark a class that should be considered to implement
  * every possible getter, setter and method. Tools can use this annotation to
  * suppress warnings when there is no explicit implementation of a referenced
@@ -57,4 +36,4 @@
 
 class _Proxy {
   const _Proxy();
-}
\ No newline at end of file
+}
diff --git a/pkg/observe/lib/transform.dart b/pkg/observe/lib/transform.dart
index d8396b9..ede5a0d 100644
--- a/pkg/observe/lib/transform.dart
+++ b/pkg/observe/lib/transform.dart
@@ -10,10 +10,11 @@
 
 import 'dart:async';
 
-import 'package:analyzer_experimental/src/generated/ast.dart';
-import 'package:analyzer_experimental/src/generated/error.dart';
-import 'package:analyzer_experimental/src/generated/parser.dart';
-import 'package:analyzer_experimental/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/java_core.dart' show CharSequence;
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
 import 'package:barback/barback.dart';
 import 'package:source_maps/refactor.dart';
 import 'package:source_maps/span.dart' show SourceFile;
@@ -87,10 +88,11 @@
   return code;
 }
 
-/** Parse [code] using analyzer_experimental. */
+/** Parse [code] using analyzer. */
 CompilationUnit _parseCompilationUnit(String code) {
   var errorListener = new _ErrorCollector();
-  var scanner = new StringScanner(null, code, errorListener);
+  var reader = new CharSequenceReader(new CharSequence(code));
+  var scanner = new Scanner(null, reader, errorListener);
   var token = scanner.tokenize();
   var parser = new Parser(null, errorListener);
   return parser.parseCompilationUnit(token);
@@ -110,7 +112,7 @@
 
 // TODO(jmesserly): this isn't correct if the annotation has been imported
 // with a prefix, or cases like that. We should technically be resolving, but
-// that is expensive in analyzer_experimental, so it isn't feasible yet.
+// that is expensive in analyzer, so it isn't feasible yet.
 bool _isObservableAnnotation(Annotation node) =>
     _isAnnotationContant(node, 'observable') ||
     _isAnnotationContant(node, 'published') ||
diff --git a/pkg/observe/pubspec.yaml b/pkg/observe/pubspec.yaml
index 3f0b32f..36aa73b 100644
--- a/pkg/observe/pubspec.yaml
+++ b/pkg/observe/pubspec.yaml
@@ -8,7 +8,7 @@
   immediately assigned to the model.
 homepage: https://www.dartlang.org/polymer-dart/
 dependencies:
-  analyzer_experimental: any
+  analyzer: any
   barback: any
   logging: any
   meta: any
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 65ca59d..e5a8df6 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -23,7 +23,6 @@
 third_party/html5lib/test/browser/browser_test: Skip
 
 [ $compiler == dart2js ]
-analyzer_experimental/test/generated/ast_test: RuntimeError #Issue 12341
 collection_helpers/test/equality_test/01: Fail # Issue 1533
 collection_helpers/test/equality_test/02: Fail # Issue 1533
 collection_helpers/test/equality_test/03: Fail # Issue 1533
@@ -47,9 +46,12 @@
 polymer/test/bind_test: Skip # uses dart:html
 polymer/test/bind_mdv_test: Skip # uses dart:html
 polymer/test/custom_event_test: Skip # uses dart:html
+polymer/test/event_handlers_test: Skip #uses dart:html
+polymer/test/event_path_declarative_test: Skip #uses dart:html
 polymer/test/event_path_test: Skip #uses dart:html
 polymer/test/events_test: Skip #uses dart:html
 polymer/test/instance_attrs_test: Skip #uses dart:html
+polymer/test/noscript_test: Skip #uses dart:html
 polymer/test/prop_attr_bind_reflection_test: Skip #uses dart:html
 polymer/test/prop_attr_reflection_test: Skip #uses dart:html
 polymer/test/publish_attributes_test: Skip #uses dart:html
@@ -87,20 +89,23 @@
 [ $runtime == ie9 || $runtime == ie10 ]
 polymer/example/canonicalization/test/canonicalization_deploy_test: Pass, Timeout
 polymer/example/canonicalization/test/canonicalization_test: Fail, Timeout, OK # tests development only behavior
-polymer/test/attr_deserialize_test: Fail, Timeout # Issue 12865, 13197, 13260
-polymer/test/attr_mustache_test: Fail, Timeout # Issue 12865, 13197, 13260
-polymer/test/bind_test: Fail, Timeout # Issue 12865, 13197, 13260
-polymer/test/bind_mdv_test: Fail, Timeout # Issue 12865, 13197, 13260
-polymer/test/custom_event_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/prop_attr_bind_reflection_test: Fail, Timeout # Issue 12865, 13197, 13260
-polymer/test/publish_attributes_test: Fail, Timeout # Issue 12865, 13197, 13260
-polymer/test/register_test: Pass, Fail, Timeout # Issue 12865, 13197, 13260
-polymer/test/take_attributes_test: Fail, Timeout # Issue 12865, 13197, 13260
-polymer/test/template_distribute_dynamic_test: Fail, Timeout # Issue 12865, 13197, 13260
-polymer/test/unbind_test: Fail, Timeout # Issue 12865, 13197, 13260
+polymer/test/attr_deserialize_test: Pass, Timeout # Issue 13260
+polymer/test/attr_mustache_test: Pass, Timeout # Issue 13260
+polymer/test/bind_test: Pass, Timeout # Issue 13260
+polymer/test/bind_mdv_test: Fail, Timeout # Issue 14412, 13260
+polymer/test/custom_event_test: Pass, Timeout # Issue 13260
+polymer/test/event_handlers_test: Pass, Timeout # Issue 13260
+polymer/test/event_path_declarative_test: Pass, Timeout # Issue 13260
+polymer/test/event_path_test: Pass, Timeout # Issue 13260
+polymer/test/events_test: Pass, Timeout # Issue 13260
+polymer/test/noscript_test: Pass, Timeout # Issue 13260
+polymer/test/prop_attr_reflection_test: Pass, Timeout # Issue 13260
+polymer/test/prop_attr_bind_reflection_test: Pass, Timeout # Issue 13260
+polymer/test/publish_attributes_test: Pass, Timeout # Issue 13260
+polymer/test/register_test: Pass, Timeout # Issue 13260
+polymer/test/take_attributes_test: Pass, Timeout # Issue 13260
+polymer/test/template_distribute_dynamic_test: Pass, Timeout # Issue 13260
+polymer/test/unbind_test: Pass, Timeout # Issue 13260
 polymer_expressions/test/globals_test: Fail # Issue 13890
 
 # Skip browser-specific tests on VM
@@ -116,12 +121,18 @@
 [ $compiler == dart2js ]
 stack_trace/test/trace_test: Pass, Timeout # Issue 11645
 
-[ $compiler == dartanalyzer || $compiler == dart2analyzer]
+[ $compiler == dartanalyzer ]
 # These tests are runtime negative but statically positive, so we skip
 # them in the analyzer.
 unittest/test/mock_regexp_negative_test: Skip
 unittest/test/mock_stepwise_negative_test: Skip
-collection_helpers/test/equality_test/none: Fail # TODO(lrn): Figure out if it's an error.
+polymer/example/canonicalization: Skip
+
+[ $compiler == dart2analyzer ]
+# These tests are runtime negative but statically positive, so we skip
+# them in the analyzer.
+unittest/test/mock_regexp_negative_test: Skip
+unittest/test/mock_stepwise_negative_test: Skip
 polymer/example/canonicalization: Skip
 
 [ $compiler == dart2js && $runtime == none]
@@ -138,6 +149,7 @@
 # printed. Minified versions of these tests exist that test the behavior when
 # minified.
 unittest/test/*_unminified_test: Skip # DO NOT COPY THIS UNLESS YOU WORK ON DART2JS
+analyzer/test/generated/ast_test: Fail # Issue 12336
 
 [ $compiler == dart2js && $browser ]
 stack_trace/test/vm_test: Fail, OK # VM-specific traces
@@ -154,12 +166,12 @@
 http_server/test/http_body_test: Pass, Fail # Issue 14381
 
 [ $browser ]
-analyzer_experimental/test/error_test: Fail, Timeout, OK # Uses dart:io.
-analyzer_experimental/test/generated/element_test: Fail, OK # Uses dart:io.
-analyzer_experimental/test/generated/resolver_test: Fail, OK # Uses dart:io.
-analyzer_experimental/test/options_test: Fail, OK, Pass # Uses dart:io.
-analyzer_experimental/test/services/formatter_test: Fail, OK # Uses dart:io.
-analyzer_experimental/test/parse_compilation_unit_test: Fail, OK # Uses dart:io.
+analyzer/test/error_test: Fail, Timeout, OK # Uses dart:io.
+analyzer/test/generated/element_test: Fail, OK # Uses dart:io.
+analyzer/test/generated/resolver_test: Fail, OK # Uses dart:io.
+analyzer/test/options_test: Fail, OK, Pass # Uses dart:io.
+analyzer/test/services/formatter_test: Fail, OK # Uses dart:io.
+analyzer/test/parse_compilation_unit_test: Fail, OK # Uses dart:io.
 barback/test/*: Fail, OK # Uses dart:io.
 http/test/client_test: Fail, OK # Uses dart:io.
 http/test/http_test: Fail, OK # Uses dart:io.
@@ -259,8 +271,8 @@
 unittest/test/unittest_testcases_immutable_test: Fail # 13921
 unittest/test/unitttest_group_name_test: Fail # 13921
 template_binding/test/template_element_test: Pass, Fail # Flaky, 14330
+polymer_expressions/test/bindings_test: Pass, Fail # Flaky, 14330
 polymer/test/custom_event_test: Pass, Crash # 14360
-
 polymer/example/canonicalization/test/canonicalization_deploy_test: Fail, OK # tests deploy only behavior
 
 # Skip tests on the VM if the package depends on dart:html
@@ -284,18 +296,16 @@
 [ $runtime == vm ]
 intl/test/message_extraction/message_extraction_test: Pass, Fail # Issue 12930
 
-[ $compiler == none && $runtime == dartium ]
+[ $compiler == none && ($runtime == dartium || $runtime == drt) ]
 source_maps/test/parser_test: Pass, Timeout # Issue 13719: Please triage this failure.
+polymer_expressions/test/bindings_test: Fail, Pass # Issue 14445.
 
 [ $compiler == dartanalyzer ]
-# pkg issue 13944; Missing inherited members: 'ListChangeRecord.addedCount' and 'ListChangeRecord.removedCount'
+# pkg issue 13944; Missing inherited member 'Observable._mirror'
 custom_element/test/analyzer_test: fail
 template_binding/test/analyzer_test: fail
 observe/test/observe_test: fail
 
-# pkg issue 13945; Missing inherited member 'Trace.frames'
-observe/test/observe_test: fail
-
 [ $compiler == dart2analyzer ]
 # pkg issue 13944; Missing inherited members: 'ListChangeRecord.addedCount' and 'ListChangeRecord.removedCount'
 custom_element/test/analyzer_test: fail
diff --git a/pkg/polymer/example/component/news/web/index.html b/pkg/polymer/example/component/news/web/index.html
index f6e7ce0..8dda8f59 100644
--- a/pkg/polymer/example/component/news/web/index.html
+++ b/pkg/polymer/example/component/news/web/index.html
@@ -18,7 +18,7 @@
     <li><a href="//example.com/stories/4">Awesome story</a></li>
     <li class="breaking"><a href="//example.com/stories/5">Horrible story</a></li>
 </ul>
-  <script type="application/dart" src="packages/polymer/init.dart"></script>
+  <script type="application/dart">import 'package:polymer/init.dart';</script>
   <script src='packages/browser/dart.js'></script>
 </body>
 </html>
diff --git a/pkg/polymer/lib/boot.js b/pkg/polymer/lib/boot.js
index d46090f..0cb6714 100644
--- a/pkg/polymer/lib/boot.js
+++ b/pkg/polymer/lib/boot.js
@@ -5,7 +5,7 @@
 (function() {
   console.error('"boot.js" is now deprecated. Instead, you can initialize '
     + 'your polymer application by adding the following tags: \'' +
-    + '<script type="application/dart" src="packages/polymer/init.dart">'
+    + '<script type="application/dart">import "package:polymer/init.dart";'
     + '</script><script src="packages/browser/dart.js"></script>\'. '
     + 'Make sure these script tags come after all HTML imports.');
 })();
diff --git a/pkg/polymer/lib/deserialize.dart b/pkg/polymer/lib/deserialize.dart
index 9de4ea9..60e63f7 100644
--- a/pkg/polymer/lib/deserialize.dart
+++ b/pkg/polymer/lib/deserialize.dart
@@ -12,13 +12,13 @@
   var m = new Map();
   m[#dart.core.String] = (x, _) => x;
   m[#dart.core.Null] = (x, _) => x;
-  m[#dart.core.DateTime] = (x, _) {
+  m[#dart.core.DateTime] = (x, def) {
     // 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();
+      return def;
     }
   };
   m[#dart.core.bool] = (x, _) => x != 'false';
@@ -30,11 +30,11 @@
 }();
 
 /**
- * Convert representation of [value] based on type of [defaultValue].
+ * Convert representation of [value] based on type of [currentValue].
  */
-Object deserializeValue(String value, Object defaultValue, TypeMirror type) {
+Object deserializeValue(String value, Object currentValue, TypeMirror type) {
   var handler = _typeHandlers[type.qualifiedName];
-  if (handler != null) return handler(value, defaultValue);
+  if (handler != null) return handler(value, currentValue);
 
   try {
     // If the string is an object, we can parse is with the JSON library.
diff --git a/pkg/polymer/lib/init.dart b/pkg/polymer/lib/init.dart
index 8ca18c1..8eba9de 100644
--- a/pkg/polymer/lib/init.dart
+++ b/pkg/polymer/lib/init.dart
@@ -11,7 +11,7 @@
  * elements are created, then, instead of creating your own `main`, you can
  * simply include a script tag loading this library:
  *
- *    <script type="application/dart" src="packages/polymer/init.dart">
+ *    <script type="application/dart">import "package:polymer/init.dart";
  *    </script>
  *
  * This script tag should be placed after all HTML imports on your page.
diff --git a/pkg/polymer/lib/platform.dart b/pkg/polymer/lib/platform.dart
deleted file mode 100644
index ea26eb0..0000000
--- a/pkg/polymer/lib/platform.dart
+++ /dev/null
@@ -1,40 +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.
-
-/**
- * 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:async' show Completer;
-import 'dart:html' show Text, MutationObserver;
-import 'dart:collection' show Queue;
-import 'package:observe/observe.dart';
-
-void flush() => endOfMicrotask(Observable.dirtyCheck);
-
-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 a195ed8..48b7592 100644
--- a/pkg/polymer/lib/polymer.dart
+++ b/pkg/polymer/lib/polymer.dart
@@ -60,8 +60,6 @@
 import 'package:template_binding/template_binding.dart';
 
 import 'deserialize.dart' as deserialize;
-import 'job.dart';
-import 'platform.dart' as platform;
 import 'src/reflected_type.dart';
 
 export 'package:observe/observe.dart';
@@ -70,4 +68,5 @@
 part 'src/boot.dart';
 part 'src/declaration.dart';
 part 'src/instance.dart';
+part 'src/job.dart';
 part 'src/loader.dart';
diff --git a/pkg/polymer/lib/src/boot.dart b/pkg/polymer/lib/src/boot.dart
index 8e8618f..6c2eb79 100644
--- a/pkg/polymer/lib/src/boot.dart
+++ b/pkg/polymer/lib/src/boot.dart
@@ -6,17 +6,39 @@
 part of polymer;
 
 /** Prevent a flash of unstyled content. */
-preventFlashOfUnstyledContent() {
+_preventFlashOfUnstyledContent() {
+
   var style = new StyleElement();
-  style.text = r'body {opacity: 0;}';
+  style.text = '.$_VEILED_CLASS { '
+      'opacity: 0; } \n'
+      '.$_UNVEIL_CLASS{ '
+      '-webkit-transition: opacity ${_TRANSITION_TIME}s; '
+      'transition: opacity ${_TRANSITION_TIME}s; }\n';
+
   // Note: we use `query` and not `document.head` to make sure this code works
   // with the shadow_dom polyfill (a limitation of the polyfill is that it can't
   // override the definitions of document, document.head, or document.body).
-  var head = query('head');
+  var head = document.querySelector('head');
   head.insertBefore(style, head.firstChild);
 
+  _veilElements();
+
+  // hookup auto-unveiling
   Polymer.onReady.then((_) {
-    document.body.style.transition = 'opacity 0.3s';
-    document.body.style.opacity = '1';
+    Polymer.unveilElements();
   });
 }
+
+// add polymer styles
+const _VEILED_CLASS = 'polymer-veiled';
+const _UNVEIL_CLASS = 'polymer-unveil';
+const _TRANSITION_TIME = 0.3;
+
+// apply veiled class
+_veilElements() {
+  for (var selector in Polymer.veiledElements) {
+    for (var node in document.querySelectorAll(selector)) {
+      node.classes.add(_VEILED_CLASS);
+    }
+  }
+}
diff --git a/pkg/polymer/lib/src/build/code_extractor.dart b/pkg/polymer/lib/src/build/code_extractor.dart
index 5e9135d..e6c6445 100644
--- a/pkg/polymer/lib/src/build/code_extractor.dart
+++ b/pkg/polymer/lib/src/build/code_extractor.dart
@@ -7,10 +7,11 @@
 
 import 'dart:async';
 
-import 'package:analyzer_experimental/src/generated/ast.dart';
-import 'package:analyzer_experimental/src/generated/error.dart';
-import 'package:analyzer_experimental/src/generated/parser.dart';
-import 'package:analyzer_experimental/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/java_core.dart' show CharSequence;
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
 import 'package:barback/barback.dart';
 import 'package:path/path.dart' as path;
 
@@ -72,7 +73,9 @@
 /** Parse [code] and determine whether it has a library directive. */
 bool _hasLibraryDirective(String code) {
   var errorListener = new _ErrorCollector();
-  var token = new StringScanner(null, code, errorListener).tokenize();
+  var reader = new CharSequenceReader(new CharSequence(code));
+  var scanner = new Scanner(null, reader, errorListener);
+  var token = scanner.tokenize();
   var unit = new Parser(null, errorListener).parseCompilationUnit(token);
   return unit.directives.any((d) => d is LibraryDirective);
 }
diff --git a/pkg/polymer/lib/src/build/linter.dart b/pkg/polymer/lib/src/build/linter.dart
index 1227160..3f5fe0d 100644
--- a/pkg/polymer/lib/src/build/linter.dart
+++ b/pkg/polymer/lib/src/build/linter.dart
@@ -544,7 +544,7 @@
 const String USE_INIT_DART = 
     'To run a polymer applications, you need to call "initPolymer". You can '
     'either include a generic script tag that does this for you:'
-    '\'<script type="application/dart" src="packages/polymer/init.dart">'
+    '\'<script type="application/dart">import "package:polymer/init.dart";'
     '</script>\' or add your own script tag and call that function. '
     'Make sure the script tag is placed after all HTML imports.';
 
@@ -556,7 +556,7 @@
     '"boot.js" is now deprecated. Instead, you can initialize your polymer '
     'application by calling "initPolymer()" in your main. If you don\'t have a '
     'main, then you can include our generic main by adding the following '
-    'script tag to your page: \'<script type="application/dart" '
-    'src="packages/polymer/init.dart"> </script>\'. Additionally you need to '
+    'script tag to your page: \'<script type="application/dart">import '
+    '"package:polymer/init.dart";</script>\'. Additionally you need to '
     'include: \'<script src="packages/browser/dart.js"></script>\' in the page '
     'too. Make sure these script tags come after all HTML imports.';
diff --git a/pkg/polymer/lib/src/build/runner.dart b/pkg/polymer/lib/src/build/runner.dart
index e486fdf..e4a1049 100644
--- a/pkg/polymer/lib/src/build/runner.dart
+++ b/pkg/polymer/lib/src/build/runner.dart
@@ -104,7 +104,7 @@
 // TODO(sigmund): consider computing this list by recursively parsing
 // pubspec.yaml files in the `Options.packageDirs`.
 final Set<String> _polymerPackageDependencies = [
-    'analyzer_experimental', 'args', 'barback', 'browser', 'csslib',
+    'analyzer', 'args', 'barback', 'browser', 'csslib',
     'custom_element', 'fancy_syntax', 'html5lib', 'html_import', 'js',
     'logging', 'meta', 'mutation_observer', 'observe', 'path'
     'polymer_expressions', 'serialization', 'shadow_dom', 'source_maps',
diff --git a/pkg/polymer/lib/src/declaration.dart b/pkg/polymer/lib/src/declaration.dart
index 22c2e86..ba2beff 100644
--- a/pkg/polymer/lib/src/declaration.dart
+++ b/pkg/polymer/lib/src/declaration.dart
@@ -16,7 +16,7 @@
 
   factory PolymerDeclaration() => new Element.tag(_TAG);
   // Fully ported from revision:
-  // https://github.com/Polymer/polymer/blob/4dc481c11505991a7c43228d3797d28f21267779
+  // https://github.com/Polymer/polymer/blob/b7200854b2441a22ce89f6563963f36c50f5150d
   //
   //   src/declaration/attributes.js
   //   src/declaration/events.js
@@ -48,16 +48,16 @@
    * 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;
+  Map<Symbol, DeclarationMirror> _publish;
 
   /** The names of published properties for this polymer-element. */
-  Iterable<String> get publishedProperties =>
+  Iterable<Symbol> 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, Symbol> _observe;
 
   Map<String, Object> _instanceAttributes;
 
@@ -156,21 +156,10 @@
 
     // back reference declaration element
     // TODO(sjmiles): replace `element` with `elementElement` or `declaration`
-    _declarations[_type] = this;
+    _declarations[name] = 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, extendee);
-
+    desugar(name, extendee);
     // register our custom element
     registerType(name);
 
@@ -192,7 +181,7 @@
 
     // get basal prototype
     _supertype = _getRegisteredType(extendee);
-    if (supertype != null) _super = _getDeclaration(supertype);
+    if (_supertype != null) _super = _getDeclaration(extendee);
 
     var cls = reflectClass(_type);
 
@@ -208,21 +197,28 @@
     // 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
+    // x-platform fixup
   }
 
   /** Implement various declarative features. */
-  void desugar() {
+  void desugar(name, extendee) {
     // 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(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, extendee);
+
     var cls = reflectClass(type);
     // TODO(jmesserly): this feels unnatrual in Dart. Since we have convenient
     // lazy static initialization, can we get by without it?
@@ -231,7 +227,6 @@
         registered.isRegularMethod) {
       cls.invoke(#registerCallback, [this]);
     }
-
   }
 
   void registerType(String name) {
@@ -261,7 +256,9 @@
         attr = attr.trim();
 
         // do not override explicit entries
-        if (_publish != null && _publish.containsKey(attr)) continue;
+        if (attr != '' && _publish != null && _publish.containsKey(attr)) {
+          continue;
+        }
 
         var property = new Symbol(attr);
         var mirror = cls.variables[property];
@@ -275,7 +272,7 @@
           continue;
         }
         if (_publish == null) _publish = {};
-        _publish[attr] = mirror;
+        _publish[property] = mirror;
       }
     }
 
@@ -314,59 +311,16 @@
   void addAttributeDelegates(Map<String, String> delegates) {
     attributes.forEach((name, value) {
       if (_hasEventPrefix(name)) {
-        delegates[_removeEventPrefix(name)] = value;
+        var start = value.indexOf('{{');
+        var end = value.lastIndexOf('}}');
+        if (start >= 0 && end >= 0) {
+          delegates[_removeEventPrefix(name)] =
+              value.substring(start + 2, end).trim();
+        }
       }
     });
   }
 
-  /** Extracts events under the element's <template>. */
-  void parseLocalEvents() {
-    for (var t in this.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') {
-      accumulateChildEvents(templateBind(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('/');
@@ -438,7 +392,7 @@
   // TODO(sorvell): remove when wkb.ug/72462 is addressed.
   void installGlobalStyles() {
     var style = styleForScope(_STYLE_GLOBAL_SCOPE);
-    _applyStyleToScope(style, document.head);
+    Polymer.applyStyleToScope(style, document.head);
   }
 
   String cssTextForScope(String scopeDescriptor) {
@@ -483,9 +437,9 @@
 
       String name = MirrorSystem.getName(method.simpleName);
       if (name.endsWith(_OBSERVE_SUFFIX) && name != 'attributeChanged') {
-        if (_observe == null) _observe = {};
+        if (_observe == null) _observe = new Map();
         name = name.substring(0, name.length - 7);
-        _observe[name] = method.simpleName;
+        _observe[new Symbol(name)] = method.simpleName;
       }
     }
   }
@@ -495,10 +449,10 @@
     if (_publish != null) _publishLC = _lowerCaseMap(_publish);
   }
 
-  Map<String, dynamic> _lowerCaseMap(Map<String, dynamic> properties) {
+  Map<String, dynamic> _lowerCaseMap(Map<Symbol, dynamic> properties) {
     final map = new Map<String, dynamic>();
     properties.forEach((name, value) {
-      map[name.toLowerCase()] = value;
+      map[MirrorSystem.getName(name).toLowerCase()] = value;
     });
     return map;
   }
@@ -521,7 +475,6 @@
 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) {
@@ -530,14 +483,11 @@
   }
 }
 
-/// track document.register'ed tag names
-final Set _registered = new Set<String>();
+/// track document.register'ed tag names and their declarations
+final Map _declarations = new Map<String, PolymerDeclaration>();
 
-bool _isRegistered(name) => _registered.contains(name);
-
-final Map _declarations = new Map<Type, PolymerDeclaration>();
-
-PolymerDeclaration _getDeclaration(Type type) => _declarations[type];
+bool _isRegistered(String name) => _declarations.containsKey(name);
+PolymerDeclaration _getDeclaration(String name) => _declarations[name];
 
 final _objectType = reflectClass(Object);
 
@@ -548,7 +498,7 @@
     for (var meta in field.metadata) {
       if (matches(meta.reflectee)) {
         if (props == null) props = {};
-        props[MirrorSystem.getName(field.simpleName)] = field;
+        props[field.simpleName] = field;
         break;
       }
     }
@@ -561,7 +511,7 @@
       if (matches(meta.reflectee)) {
         if (_hasSetter(cls, getter)) {
           if (props == null) props = {};
-          props[MirrorSystem.getName(getter.simpleName)] = getter;
+          props[getter.simpleName] = getter;
         }
         break;
       }
@@ -605,24 +555,7 @@
 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);
-}
+const _STYLE_CONTROLLER_SCOPE = 'controller';
 
 String _cssTextFromSheet(Element sheet) {
   if (sheet == null || js.context == null) return '';
diff --git a/pkg/polymer/lib/src/instance.dart b/pkg/polymer/lib/src/instance.dart
index 815c6bd..e46fda3 100644
--- a/pkg/polymer/lib/src/instance.dart
+++ b/pkg/polymer/lib/src/instance.dart
@@ -27,17 +27,16 @@
  */
 abstract class Polymer implements Element, Observable, NodeBindExtension {
   // Fully ported from revision:
-  // https://github.com/Polymer/polymer/blob/4dc481c11505991a7c43228d3797d28f21267779
+  // https://github.com/Polymer/polymer/blob/b7200854b2441a22ce89f6563963f36c50f5150d
   //
+  //   src/boot.js (static APIs on "Polymer" object)
   //   src/instance/attributes.js
   //   src/instance/base.js
   //   src/instance/events.js
   //   src/instance/mdv.js
   //   src/instance/properties.js
+  //   src/instance/style.js
   //   src/instance/utils.js
-  //
-  // Not yet ported:
-  //   src/instance/style.js -- blocked on ShadowCSS.shimPolyfillDirectives
 
   // TODO(jmesserly): should this really be public?
   /** Regular expression that matches data-bindings. */
@@ -64,7 +63,8 @@
   }
 
   /// The one syntax to rule them all.
-  static final BindingDelegate _polymerSyntax = new PolymerExpressions();
+  static final BindingDelegate _polymerSyntax =
+      new _PolymerExpressionsWithEventDelegate();
 
   static int _preparingElements = 0;
 
@@ -81,15 +81,20 @@
   /** The most derived `<polymer-element>` declaration for this element. */
   PolymerDeclaration get declaration => _declaration;
 
-  Map<String, StreamSubscription> _elementObservers;
+  Map<String, StreamSubscription> _observers;
   bool _unbound; // lazy-initialized
-  Job _unbindAllJob;
+  _Job _unbindAllJob;
+
+  StreamSubscription _propertyObserver;
 
   bool get _elementPrepared => _declaration != null;
 
   bool get applyAuthorStyles => false;
   bool get resetStyleInheritance => false;
   bool get alwaysPrepare => false;
+  bool get preventDispose => false;
+
+  BindingDelegate syntax = _polymerSyntax;
 
   /**
    * Shadow roots created by [parseElement]. See [getShadowRoot].
@@ -102,8 +107,11 @@
   // * 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>();
+  // Note: this is observable to support $['someId'] being used in templates.
+  // The template is stamped before $ is populated, so we need observation if
+  // we want it to be usable in bindings.
+  @reflectable final Map<String, Element> $ =
+      new ObservableMap<String, Element>();
 
   /**
    * Gets the shadow root associated with the corresponding custom element.
@@ -116,17 +124,6 @@
   // TODO(jmesserly): Polymer does not have this feature. Reconcile.
   ShadowRoot getShadowRoot(String customTagName) => _shadowRoots[customTagName];
 
-  /**
-   * 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);
-
   void polymerCreated() {
     if (this.ownerDocument.window != null || alwaysPrepare ||
         _preparingElements > 0) {
@@ -134,9 +131,15 @@
     }
   }
 
+  /** Retrieves the custom element name by inspecting the host node. */
+  String get _customTagName {
+    var isAttr = attributes['is'];
+    return (isAttr == null || isAttr == '') ? localName : isAttr;
+  }
+
   void prepareElement() {
     // Dart note: get the _declaration, which also marks _elementPrepared
-    _declaration = _getDeclaration(this.runtimeType);
+    _declaration = _getDeclaration(_customTagName);
     // do this first so we can observe changes during initialization
     observeProperties();
     // install boilerplate attributes
@@ -145,10 +148,12 @@
     takeAttributes();
     // add event listeners
     addHostListeners();
-    // guarantees that while preparing, any sub-elements will also be prepared
+    // guarantees that while preparing, any
+    // sub-elements are also prepared
     _preparingElements++;
     // process declarative resources
     parseDeclarations(_declaration);
+    // decrement semaphore
     _preparingElements--;
     // user entry point
     ready();
@@ -165,7 +170,7 @@
   }
 
   void leftView() {
-    asyncUnbindAll();
+    if (!preventDispose) asyncUnbindAll();
   }
 
   /** Recursive ancestral <element> initialization, oldest first. */
@@ -180,7 +185,16 @@
    * Parse input `<polymer-element>` as needed, override for custom behavior.
    */
   void parseDeclaration(Element elementElement) {
-    var root = shadowFromTemplate(fetchTemplate(elementElement));
+    var template = fetchTemplate(elementElement);
+
+    var root = null;
+    if (template != null) {
+      if (_declaration.attributes.containsKey('lightdom')) {
+        lightFromTemplate(template);
+      } else {
+        root = shadowFromTemplate(template);
+      }
+    }
 
     // Dart note: the following code is to support the getShadowRoot method.
     if (root is! ShadowRoot) return;
@@ -197,6 +211,24 @@
       elementElement.query('template');
 
   /**
+   * Utility function that stamps a `<template>` into light-dom.
+   */
+  Node lightFromTemplate(Element template) {
+    if (template == null) return null;
+    // 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
+    append(dom);
+    // perform post-construction initialization tasks on shadow root
+    shadowRootReady(this, template);
+    // return the created shadow root
+    return dom;
+  }
+
+  /**
    * Utility function that creates a shadow root from a `<template>`.
    *
    * The base implementation will return a [ShadowRoot], but you can replace it
@@ -239,8 +271,6 @@
   void shadowRootReady(Node 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);
@@ -260,20 +290,20 @@
     }
   }
 
-  // TODO(jmesserly): use stream or future here?
+  // TODO(jmesserly): this could be a top level method.
   /**
-   * Run the `listener` callback *once*
-   * when `node` changes, or when its children or subtree changes.
-   *
-   *
-   * See [MutationObserver] if you want to listen to a stream of
+   * Returns a future when `node` changes, or when its children or subtree
    * changes.
+   *
+   * Use [MutationObserver] if you want to listen to a stream of changes.
    */
-  void onMutation(Node node, void listener(MutationObserver obs)) {
-    new MutationObserver((records, MutationObserver observer) {
-      listener(observer);
+  Future<List<MutationRecord>> onMutation(Node node) {
+    var completer = new Completer();
+    new MutationObserver((mutations, observer) {
       observer.disconnect();
+      completer.complete(mutations);
     })..observe(node, childList: true, subtree: true);
+    return completer.future;
   }
 
   void copyInstanceAttributes() {
@@ -304,14 +334,14 @@
 
     // get original value
     final self = reflect(this);
-    final defaultValue = self.getField(property.simpleName).reflectee;
+    final currentValue = self.getField(property.simpleName).reflectee;
 
     // deserialize Boolean or Number values from attribute
-    final newValue = deserializeValue(value, defaultValue,
-        _inferPropertyType(defaultValue, property));
+    final newValue = deserializeValue(value, currentValue,
+        _inferPropertyType(currentValue, property));
 
     // only act if the value has changed
-    if (!identical(newValue, defaultValue)) {
+    if (!identical(newValue, currentValue)) {
       // install new value (has side-effects)
       self.setField(property.simpleName, newValue);
     }
@@ -327,13 +357,13 @@
   }
 
   /**
-   * Convert representation of [value] based on [type] and [defaultValue].
+   * Convert representation of [value] based on [type] and [currentValue].
    */
   // 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);
+  Object deserializeValue(String value, Object currentValue, TypeMirror type) =>
+      deserialize.deserializeValue(value, currentValue, type);
 
   String serializeValue(Object value) {
     if (value == null) return null;
@@ -346,23 +376,23 @@
     return null;
   }
 
-  void reflectPropertyToAttribute(String name) {
+  void reflectPropertyToAttribute(Symbol 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 propValue = self.getField(name).reflectee;
     final serializedValue = serializeValue(propValue);
     // boolean properties must reflect as boolean attributes
     if (serializedValue != null) {
-      attributes[name] = serializedValue;
+      attributes[MirrorSystem.getName(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 (propValue is bool) {
-      attributes.remove(name);
+      attributes.remove(MirrorSystem.getName(name));
     }
   }
 
@@ -380,18 +410,19 @@
    * template, for example to use a different data-binding syntax.
    */
   DocumentFragment instanceTemplate(Element template) =>
-      templateBind(template).createInstance(this, _polymerSyntax);
+      templateBind(template).createInstance(this, syntax);
 
-  NodeBinding createBinding(String name, model, String path) =>
-      nodeBindFallback(this).createBinding(name, model, path);
-
-  NodeBinding bind(String name, model, String path) {
+  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) {
+    if (property == null) {
+      // Cannot call super.bind because template_binding is its own package
+      return nodeBindFallback(this).bind(name, model, path);
+    } else {
+      // clean out the closets
       unbind(name);
       // use n-way Polymer binding
       var observer = bindProperty(property.simpleName, model, path);
@@ -400,11 +431,8 @@
       // does not update due to not changing.
       // Dart note: we include this patch:
       // https://github.com/Polymer/polymer/pull/319
-      reflectPropertyToAttribute(MirrorSystem.getName(property.simpleName));
+      reflectPropertyToAttribute(property.simpleName);
       return bindings[name] = observer;
-    } else {
-      // Cannot call super.bind because template_binding is its own package
-      return nodeBindFallback(this).bind(name, model, path);
     }
   }
 
@@ -415,7 +443,7 @@
   void asyncUnbindAll() {
     if (_unbound == true) return;
     _unbindLog.fine('[$localName] asyncUnbindAll');
-    _unbindAllJob = job(_unbindAllJob, unbindAll, const Duration(seconds: 0));
+    _unbindAllJob = _runJob(_unbindAllJob, unbindAll, Duration.ZERO);
   }
 
   void unbindAll() {
@@ -424,8 +452,11 @@
     unbindAllProperties();
     nodeBindFallback(this).unbindAll();
 
-    _unbindNodeTree(shadowRoot);
-    // TODO(sjmiles): must also unbind inherited shadow roots
+    var root = shadowRoot;
+    while (root != null) {
+      _unbindNodeTree(root);
+      root = root.olderShadowRoot;
+    }
     _unbound = true;
   }
 
@@ -466,80 +497,118 @@
 
   /** 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
+    // TODO(jmesserly): we don't have CompoundPathObserver, so this
+    // implementation is a little bit different. We also don't expose the
+    // "generateCompoundPathObserver" method.
     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);
-        }
-      });
+      for (var name in observe.keys) {
+        observeArrayValue(name, reflect(this).getField(name), null);
+      }
     }
-    // add observers for published properties
-    if (publish != null) {
-      publish.forEach((name, value) {
-        if (observe == null || !observe.containsKey(name)) {
-          observeAttributeProperty(name);
-        }
-      });
+    if (observe != null || publish != null) {
+      // Instead of using CompoundPathObserver, set up a binding using normal
+      // change records.
+      _propertyObserver = changes.listen(notifyPropertyChanges);
     }
   }
 
-  void _observe(String name, void callback(newValue, oldValue)) {
-    _observeLog.fine('[$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);
-    }));
-  }
+  /** Responds to property changes on this element. */
+  // Dart note: this takes a list of changes rather than trying to deal with
+  // what CompoundPathObserver would give us. Simpler and probably faster too.
+  void notifyPropertyChanges(Iterable<ChangeRecord> changes) {
+    final observe = _declaration._observe;
+    final publish = _declaration._publish;
 
-  void _registerObserver(String name, StreamSubscription sub) {
-    if (_elementObservers == null) {
-      _elementObservers = new Map<String, StreamSubscription>();
+    // Summarize old and new values, so we only handle each change once.
+    final valuePairs = new Map<Symbol, _PropertyValue>();
+    for (var c in changes) {
+      if (c is! PropertyChangeRecord) continue;
+
+      valuePairs.putIfAbsent(c.name, () => new _PropertyValue(c.oldValue))
+          .newValue = c.newValue;
     }
-    _elementObservers[name] = sub;
-  }
 
-  void observeAttributeProperty(String name) {
-    _observe(name, (value, old) => reflectPropertyToAttribute(name));
-  }
+    valuePairs.forEach((name, pair) {
+      if (publish != null && publish.containsKey(name)) {
+        reflectPropertyToAttribute(name);
+      }
+      if (observe == null) return;
 
-  void observeProperty(String name, Symbol method) {
-    _observe(name, (value, old) => _invoke(method, [old]));
-  }
-
-  void observeBoth(String name, Symbol methodName) {
-    _observe(name, (value, old) {
-      reflectPropertyToAttribute(name);
-      _invoke(methodName, [old]);
+      var method = observe[name];
+      if (method != null) {
+        // observes the value if it is an array
+        observeArrayValue(name, pair.newValue, pair.oldValue);
+        // TODO(jmesserly): the JS code tries to avoid calling the same method
+        // twice, but I don't see how that is possible.
+        // Dart note: JS also passes "arguments", so we pass all change records.
+        invokeMethod(method, [pair.oldValue, pair.newValue, changes]);
+      }
     });
   }
 
-  void unbindProperty(String name) {
-    if (_elementObservers == null) return;
-    var sub = _elementObservers.remove(name);
-    if (sub != null) sub.cancel();
+  void observeArrayValue(Symbol name, Object value, Object old) {
+    final observe = _declaration._observe;
+    if (observe == null) return;
+
+    // we only care if there are registered side-effects
+    var callbackName = observe[name];
+    if (callbackName == null) return;
+
+    // if we are observing the previous value, stop
+    if (old is ObservableList) {
+      if (_observeLog.isLoggable(Level.FINE)) {
+        _observeLog.fine('[$localName] observeArrayValue: unregister observer '
+            '$name');
+      }
+
+      unregisterObserver('${MirrorSystem.getName(name)}__array');
+    }
+    // if the new value is an array, being observing it
+    if (value is ObservableList) {
+      if (_observeLog.isLoggable(Level.FINE)) {
+        _observeLog.fine('[$localName] observeArrayValue: register observer '
+            '$name');
+      }
+      var sub = (value as ObservableList).changes.listen((changes) {
+        invokeMethod(callbackName, [old]);
+      });
+      registerObserver('${MirrorSystem.getName(name)}__array', sub);
+    }
   }
 
+  void unbindProperty(String name) => unregisterObserver(name);
+
   void unbindAllProperties() {
-    if (_elementObservers == null) return;
-    for (var sub in _elementObservers.values) sub.cancel();
-    _elementObservers.clear();
+    if (_propertyObserver != null) {
+      _propertyObserver.cancel();
+      _propertyObserver = null;
+    }
+    unregisterObservers();
+  }
+
+  /** Bookkeeping observers for memory management. */
+  void registerObserver(String name, StreamSubscription sub) {
+    if (_observers == null) {
+      _observers = new Map<String, StreamSubscription>();
+    }
+    _observers[name] = sub;
+  }
+
+  bool unregisterObserver(String name) {
+    var sub = _observers.remove(name);
+    if (sub == null) return false;
+    sub.cancel();
+    return true;
+  }
+
+  void unregisterObservers() {
+    if (_observers == null) return;
+    for (var sub in _observers.values) sub.cancel();
+    _observers.clear();
+    _observers = null;
   }
 
   /**
@@ -548,14 +617,14 @@
    *
    *     var myProperty;
    *
-   *     created() {
-   *       super.created();
+   *     ready() {
+   *       super.ready();
    *       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) =>
+  NodeBinding bindProperty(Symbol name, Object model, [String path]) =>
       // apply Polymer two-way reference binding
       _bindProperties(this, name, model, path);
 
@@ -597,19 +666,6 @@
     addNodeListeners(this, events.keys, hostEventListener);
   }
 
-  /** Attach event listeners inside a shadow [root]. */
-  void addInstanceListeners(Node root, Element template) {
-    var templateDelegates = _declaration._templateDelegates;
-    if (templateDelegates == null) return;
-    var events = templateDelegates[template];
-    if (events == null) return;
-
-    if (_eventsLog.isLoggable(Level.FINE)) {
-      _eventsLog.fine('[$localName] addInstanceListeners: $events');
-    }
-    addNodeListeners(root, events, instanceEventListener);
-  }
-
   void addNodeListeners(Node node, Iterable<String> events,
       void listener(Event e)) {
 
@@ -638,7 +694,7 @@
       var detail = event is CustomEvent ?
           (event as CustomEvent).detail : null;
       // TODO(jmesserly): cache the symbols?
-      dispatchMethod(new Symbol(h), [event, detail, this]);
+      dispatchMethod(this, h, [event, detail, this]);
     }
 
     if (log) {
@@ -649,103 +705,71 @@
   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) {
+  /**
+   * Calls [methodOrCallback] with [args] if it is a closure, otherwise, treat
+   * it as a method name in [object], and invoke it.
+   */
+  void dispatchMethod(object, callbackOrMethod, List args) {
     bool log = _eventsLog.isLoggable(Level.FINE);
-    if (log) _eventsLog.fine('>>> [$localName]: dispatch $methodName');
+    if (log) _eventsLog.fine('>>> [$localName]: dispatch $callbackOrMethod');
 
-    _invoke(methodName, args);
-
-    if (log) _eventsLog.info('<<< [$localName]: dispatch $methodName');
-  }
-
-  InstanceMirror _invoke(Symbol methodName, List args) {
-    // TODO(sigmund): consider making callbacks list all arguments
-    // explicitly. Unless VM mirrors are optimized first, this will be expensive
-    // once custom elements extend directly from Element (see issue 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;
-    }
-    return self.invoke(methodName, args);
-  }
-
-  void instanceEventListener(Event event) {
-    _listenLocal(this, 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(Polymer 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.FINE);
-    if (log) _eventsLog.fine('>>> [$localName]: listenLocal [${event.type}]');
-
-    final eventOn = '$_EVENT_PREFIX${_eventNameFromType(event.type)}';
-    if (event.path == null) {
-      _listenLocalNoEventPath(host, event, eventOn);
+    if (callbackOrMethod is Function) {
+      Function.apply(callbackOrMethod, args);
+    } else if (callbackOrMethod is String) {
+      _invokeMethod(object, new Symbol(callbackOrMethod), args);
     } else {
-      _listenLocalEventPath(host, event, eventOn);
+      _eventsLog.warning('invalid callback');
     }
 
-    if (log) _eventsLog.fine('<<< [$localName]: listenLocal [${event.type}]');
+    if (log) _eventsLog.info('<<< [$localName]: dispatch $callbackOrMethod');
   }
 
-  static void _listenLocalEventPath(Polymer 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;
-      }
+  /**
+   * Bind events via attributes of the form `on-eventName`. This method can be
+   * use to hooks into the model syntax and adds event listeners as needed. By
+   * default, binding paths are always method names on the root model, the
+   * custom element in which the node exists. Adding a '@' in the path directs
+   * the event binding to use the model path as the event listener.  In both
+   * cases, the actual listener is attached to a generic method which evaluates
+   * the bound path at event execution time.
+   */
+  // from src/instance/event.js#prepareBinding
+  // Dart note: template_binding doesn't have the notion of prepareBinding, so
+  // we implement this by wrapping/overriding getBinding instead.
+  // TODO(sorvell): we're patching the syntax while evaluating
+  // event bindings. we'll move this to a better spot when that's done
+  static getBindingWithEvents(
+      model, String path, name, node, originalGetBinding) {
+    // if lhs an event prefix,
+    if (name is! String || !_hasEventPrefix(name)) {
+      return originalGetBinding(model, path, name, node);
     }
-  }
 
-  // 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(Polymer host, Event event,
-      String eventOn) {
-
+    // provide an event-binding callback.
+    // return (model, name, node) {
     if (_eventsLog.isLoggable(Level.FINE)) {
-      _eventsLog.fine('event.path() not supported for ${event.type}');
+      _eventsLog.fine('event: [${node.localName}].$name => '
+          '[${model.localName}].$path())');
     }
-
-    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;
+    var eventName = _removeEventPrefix(name);
+    // TODO(sigmund): polymer.js dropped event translations. reconcile?
+    var translated = _eventTranslations[eventName];
+    eventName = translated != null ? translated : eventName;
+    return node.on[eventName].listen((event) {
+      var ctrlr = _findController(node);
+      if (ctrlr is! Polymer) return;
+      var obj = ctrlr;
+      var method = path;
+      if (path[0] == '@') {
+        obj = model;
+        // Dart note: using getBinding gets us the result of evaluating the
+        // original path (without the @) as a normal expression.
+        method = originalGetBinding(model, path.substring(1), name, node).value;
       }
-      target = target.parent;
-    }
+      var detail = event is CustomEvent ?
+          (event as CustomEvent).detail : null;
+      ctrlr.dispatchMethod(obj, method, [event, detail, node]);
+    });
   }
 
   // TODO(jmesserly): this won't find the correct host unless the ShadowRoot
@@ -757,41 +781,25 @@
     return _shadowHost[node];
   }
 
-  static bool _handleEvent(Polymer ctrlr, Node node, Event event,
-      String eventOn) {
+  /** Call [methodName] method on this object with [args]. */
+  invokeMethod(Symbol methodName, List args) =>
+      _invokeMethod(this, methodName, args);
 
-    // 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.FINE)) {
-        _eventsLog.fine('[${ctrlr.localName}] found handler name [$name]');
-      }
-      var detail = event is CustomEvent ?
-          (event as CustomEvent).detail : null;
-
-      if (node != null) {
-        // TODO(jmesserly): cache symbols?
-        ctrlr.dispatchMethod(new Symbol(name), [event, detail, node]);
-      }
+  /** Call [methodName] method on [receiver] with [args]. */
+  static _invokeMethod(receiver, Symbol methodName, List args) {
+    // TODO(sigmund): consider making callbacks list all arguments
+    // explicitly. Unless VM mirrors are optimized first, this will be expensive
+    // once custom elements extend directly from Element (see issue 11108).
+    var receiverMirror = reflect(receiver);
+    var method = receiverMirror.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;
     }
-
-    // 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;
+    return receiverMirror.invoke(methodName, args).reflectee;
   }
 
   /**
@@ -808,7 +816,7 @@
   Timer asyncTimer(void method(), Duration timeout) {
     // when polyfilling Object.observe, ensure changes
     // propagate before executing the async method
-    platform.flush();
+    scheduleMicrotask(Observable.dirtyCheck);
     return new Timer(timeout, method);
   }
 
@@ -824,7 +832,7 @@
   int async(RequestAnimationFrameCallback method) {
     // when polyfilling Object.observe, ensure changes
     // propagate before executing the async method
-    platform.flush();
+    scheduleMicrotask(Observable.dirtyCheck);
     return window.requestAnimationFrame(method);
   }
 
@@ -864,6 +872,104 @@
       anew.classes.add(className);
     }
   }
+
+  /**
+   * Installs external stylesheets and <style> elements with the attribute
+   * polymer-scope='controller' into the scope of element. This is intended
+   * to be a called during custom element construction. Note, this incurs a
+   * per instance cost and should be used sparingly.
+   *
+   * The need for this type of styling should go away when the shadowDOM spec
+   * addresses these issues:
+   *
+   * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21391
+   * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21390
+   * https://www.w3.org/Bugs/Public/show_bug.cgi?id=21389
+   *
+   * @param element The custom element instance into whose controller (parent)
+   * scope styles will be installed.
+   * @param elementElement The <element> containing controller styles.
+   */
+  // TODO(sorvell): remove when spec issues are addressed
+  void installControllerStyles() {
+    var scope = findStyleController();
+    if (scope != null && scopeHasElementStyle(scope, _STYLE_CONTROLLER_SCOPE)) {
+      // allow inherited controller styles
+      var decl = _declaration;
+      var cssText = new StringBuffer();
+      while (decl != null) {
+        cssText.write(decl.cssTextForScope(_STYLE_CONTROLLER_SCOPE));
+        decl = decl.superDeclaration;
+      }
+      if (cssText.length > 0) {
+        var style = this.element.cssTextToScopeStyle(cssText.toString(),
+              _STYLE_CONTROLLER_SCOPE);
+        // TODO(sorvell): for now these styles are not shimmed
+        // but we may need to shim them
+        Polymer.applyStyleToScope(style, scope);
+      }
+    }
+  }
+
+  Node findStyleController() {
+    if (js.context != null && js.context['ShadowDOMPolyfill'] != null) {
+      return document.querySelector('head'); // get wrapped <head>.
+    } else {
+      // find the shadow root that contains this element
+      var n = this;
+      while (n.parentNode) {
+        n = n.parentNode;
+      }
+      return identical(n, document) ? document.head : n;
+    }
+  }
+
+  bool scopeHasElementStyle(scope, descriptor) {
+    var rule = '$_STYLE_SCOPE_ATTRIBUTE=$localName-$descriptor';
+    return scope.querySelector('style[$rule]') != null;
+  }
+
+  static 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);
+  }
+
+  /**
+   * Prevents flash of unstyled content
+   * This is the list of selectors for veiled elements
+   */
+  static List<Element> veiledElements = ['body'];
+
+  /** Apply unveil class. */
+  static void unveilElements() {
+    window.requestAnimationFrame((_) {
+      var nodes = document.querySelectorAll('.$_VEILED_CLASS');
+      for (var node in nodes) {
+        (node.classes)..add(_UNVEIL_CLASS)..remove(_VEILED_CLASS);
+      }
+      // NOTE: depends on transition end event to remove 'unveil' class.
+      if (nodes.isNotEmpty) {
+        window.onTransitionEnd.first.then((_) {
+          for (var node in nodes) {
+            node.classes.remove(_UNVEIL_CLASS);
+          }
+        });
+      }
+    });
+  }
 }
 
 // Dart note: Polymer addresses n-way bindings by metaprogramming: redefine
@@ -892,7 +998,7 @@
     super.close();
   }
 
-  void boundValueChanged(newValue) {
+  void valueChanged(newValue) {
     _lastValue = newValue;
     _target.setField(_property, newValue);
   }
@@ -961,3 +1067,15 @@
     polymerCreated();
   }
 }
+
+class _PropertyValue {
+  Object oldValue, newValue;
+  _PropertyValue(this.oldValue);
+}
+
+class _PolymerExpressionsWithEventDelegate extends PolymerExpressions {
+  getBinding(model, String path, name, node) {
+    return Polymer.getBindingWithEvents(
+        model, path, name, node, super.getBinding);
+  }
+}
diff --git a/pkg/polymer/lib/job.dart b/pkg/polymer/lib/src/job.dart
similarity index 73%
rename from pkg/polymer/lib/job.dart
rename to pkg/polymer/lib/src/job.dart
index e8a4fa6..5ba818f 100644
--- a/pkg/polymer/lib/job.dart
+++ b/pkg/polymer/lib/src/job.dart
@@ -2,9 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library polymer.job;
-
-import 'dart:async' show Timer;
+part of polymer;
 
 /**
  * Invoke [callback] in [wait], unless the job is re-registered,
@@ -15,21 +13,19 @@
  * 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) {
+_Job _runJob(_Job job, void callback(), Duration wait) {
   if (job != null) {
     job.stop();
   } else {
-    job = new Job();
+    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.)
-// Remove this type in favor of Timer?
-class Job {
+// Public in Polymer.js but private as not sure it's the correct API for Dart.
+// Switch to Timer when 14414 is addressed.
+class _Job {
   Function _callback;
   Timer _timer;
 
diff --git a/pkg/polymer/lib/src/loader.dart b/pkg/polymer/lib/src/loader.dart
index 9681a93..c999660 100644
--- a/pkg/polymer/lib/src/loader.dart
+++ b/pkg/polymer/lib/src/loader.dart
@@ -48,11 +48,14 @@
  */
 // TODO(jmesserly): change the Polymer build step to call this directly.
 void _initPolymerOptimized() {
-  preventFlashOfUnstyledContent();
-
   document.register(PolymerDeclaration._TAG, PolymerDeclaration);
 
   _loadLibraries();
+
+  // Run this after user code so they can add to Polymer.veiledElements
+  _preventFlashOfUnstyledContent();
+
+  customElementsReady.then((_) => Polymer._ready.complete());
 }
 
 /**
@@ -89,8 +92,6 @@
       new Completer().completeError(e, s);
     }
   }
-
-  customElementsReady.then((_) => Polymer._ready.complete());
 }
 
 /**
@@ -106,27 +107,23 @@
   if (scripts == null) scripts = <String>[];
   if (doc == null) {
     print('warning: $baseUri not found.');
-    return;
+    return scripts;
   }
   if (seen.contains(doc)) return scripts;
   seen.add(doc);
 
-  var inlinedScriptCount = 0;
+  bool scriptSeen = false;
   for (var node in doc.queryAll('script,link[rel="import"]')) {
     if (node is LinkElement) {
       _discoverScripts(node.import, node.href, seen, scripts);
     } else if (node is ScriptElement && node.type == 'application/dart') {
-      var url = node.src;
-      if (url != '') {
-        // TODO(sigmund): consider either normalizing package: urls or add a
-        // warning to let users know about cannonicalization issues.
-        scripts.add(url);
+      if (!scriptSeen) {
+        var url = node.src;
+        scripts.add(url == '' ? baseUri : url);
+        scriptSeen = true;
       } else {
-        // We generate a unique identifier for inlined scripts which we later
-        // translate to the unique identifiers used by Dartium. Dartium uses
-        // line/column number information which we can't compute here.
-        scripts.add('$baseUri:$inlinedScriptCount');
-        inlinedScriptCount++;
+        print('warning: more than one Dart script tag in $baseUri. Dartium '
+            'currently only allows a single Dart script tag per document.');
       }
     }
   }
@@ -143,41 +140,6 @@
 final String _packageRoot =
     '${path.dirname(Uri.parse(window.location.href).path)}/packages/';
 
-/** Regex that matches urls used to represent inlined scripts. */
-final RegExp _inlineScriptRegExp = new RegExp('\(.*\.html.*\):\([0-9]\+\)');
-
-/**
- * Map URLs fabricated by polymer to URLs fabricated by Dartium to represent
- * inlined scripts. Polymer uses baseUri:script#, Dartium uses baseUri:line#
- */
-// TODO(sigmund): figure out if we can generate the same URL and expose it.
-final Map<Uri, List<Uri>> _inlinedScriptMapping = () {
-  var map = {};
-  for (var uri in _libs.keys) {
-    var uriString = uri.toString();
-    var match = _inlineScriptRegExp.firstMatch(uriString);
-    if (match == null) continue;
-    var baseUri = Uri.parse(match.group(1));
-    if (map[baseUri] == null) map[baseUri] = [];
-    map[baseUri].add(uri);
-  }
-  return map;
-}();
-
-/** Returns a new Uri that replaces [path] in [uri]. */
-Uri _replacePath(Uri uri, String path) {
-  return new Uri(scheme: uri.scheme, host: uri.host, port: uri.port,
-      path: path, query: uri.query, fragment: uri.fragment);
-}
-
-/** Returns the Uri in [href] without query parameters or fragments. */
-String _baseUri(String href) {
-  var uri = Uri.parse(window.location.href);
-  var trimUri = new Uri(scheme: uri.scheme, host: uri.host,
-      port: uri.port, path: uri.path);
-  return trimUri.toString();
-}
-
 /**
  * Reads the library at [uriString] (which can be an absolute URI or a relative
  * URI from the root library), and:
@@ -190,25 +152,16 @@
  */
 void _loadLibrary(String uriString) {
   var uri = _rootUri.resolve(uriString);
-  var lib;
-  var match = _inlineScriptRegExp.firstMatch(uriString);
-  if (match != null) {
-    var baseUri = Uri.parse(match.group(1));
-    var list = _inlinedScriptMapping[baseUri];
-    var pos = int.parse(match.group(2), onError: (_) => -1);
-    if (list != null && pos >= 0 && pos < list.length && list[pos] != null) {
-      lib = _libs[list[pos]];
-    }
-  } else if (uri.path.startsWith(_packageRoot)) {
+  var lib = _libs[uri];
+  if (uri.path.startsWith(_packageRoot) && uri.path.endsWith('.dart')) {
     var packageUri =
         Uri.parse('package:${uri.path.substring(_packageRoot.length)}');
-    lib = _libs[packageUri];
-    if (lib == null) {
-      lib = _libs[uri];
+    var canonicalLib = _libs[packageUri];
+    if (canonicalLib != null) {
+      lib = canonicalLib;
     }
-  } else {
-    lib = _libs[uri];
   }
+
   if (lib == null) {
     print('warning: $uri library not found');
     return;
diff --git a/pkg/polymer/pubspec.yaml b/pkg/polymer/pubspec.yaml
index 34380cf..6aa271e 100644
--- a/pkg/polymer/pubspec.yaml
+++ b/pkg/polymer/pubspec.yaml
@@ -6,7 +6,7 @@
   browsers.
 homepage: https://www.dartlang.org/polymer-dart/
 dependencies:
-  analyzer_experimental: any
+  analyzer: any
   args: any
   barback: any
   browser: any
diff --git a/pkg/polymer/test/attr_mustache_test.dart b/pkg/polymer/test/attr_mustache_test.dart
index 6e61f92..8f2cae1 100644
--- a/pkg/polymer/test/attr_mustache_test.dart
+++ b/pkg/polymer/test/attr_mustache_test.dart
@@ -17,7 +17,7 @@
   Future get foundSrc => _found.future;
 
   // force an mdv binding
-  bind(name, model, path) =>
+  bind(name, model, [path]) =>
       nodeBindFallback(this).bind(name, model, path);
 
   inserted() {
diff --git a/pkg/polymer/test/bind_mdv_test.dart b/pkg/polymer/test/bind_mdv_test.dart
index 6706bde..3323b0c 100644
--- a/pkg/polymer/test/bind_mdv_test.dart
+++ b/pkg/polymer/test/bind_mdv_test.dart
@@ -9,8 +9,6 @@
 import 'package:custom_element/polyfill.dart';
 import 'package:template_binding/template_binding.dart';
 import 'package:observe/observe.dart';
-import 'package:observe/src/microtask.dart' show runMicrotask;
-import 'package:polymer/platform.dart' as Platform;
 import 'package:unittest/html_config.dart';
 import 'package:unittest/unittest.dart';
 
@@ -67,9 +65,9 @@
     // TODO(sorvell): fix this when observe-js lets us explicitly listen for
     // a change on input.value
     Observable.dirtyCheck();
-    Platform.endOfMicrotask(expectAsync0(() {
+    return new Future.microtask(() {
       expect(a.value, 'hello');
-    }));
+    });
   });
 }
 
@@ -90,6 +88,6 @@
     observer.disconnect();
     completer.complete();
   })..observe(node, attributes: true);
-  Platform.flush();
+  scheduleMicrotask(Observable.dirtyCheck);
   return completer.future;
-}
\ No newline at end of file
+}
diff --git a/pkg/polymer/test/bind_test.dart b/pkg/polymer/test/bind_test.dart
index 2e726cc..e3f25ca 100644
--- a/pkg/polymer/test/bind_test.dart
+++ b/pkg/polymer/test/bind_test.dart
@@ -9,17 +9,24 @@
 import 'package:unittest/html_config.dart';
 import 'package:unittest/matcher.dart';
 
+@CustomTag('x-bar')
+class XBar extends PolymerElement {
+  XBar.created() : super.created();
+
+  get testValue => true;
+}
+
 @CustomTag('x-foo')
 class XFoo extends PolymerElement {
   @observable var foo = 'foo!';
-  final _ready = new Completer();
-  Future onTestDone;
+  final _testDone = new Completer();
+  Future get onTestDone => _testDone.future;
 
-  XFoo.created() : super.created() {
-    onTestDone = _ready.future.then(_runTest);
-  }
+  XFoo.created() : super.created();
 
   _runTest(_) {
+    expect($['bindId'].text.trim(), 'bar!');
+
     expect(foo, $['foo'].attributes['foo']);
     expect($['bool'].attributes['foo'], '');
     expect($['bool'].attributes, isNot(contains('foo?')));
@@ -29,9 +36,12 @@
     expect($['barBool'].attributes['foo'], '');
     expect($['barBool'].attributes, isNot(contains('foo?')));
     expect($['barContent'].innerHtml, foo);
+    _testDone.complete();
   }
 
-  ready() => _ready.complete();
+  ready() {
+    onMutation($['bindId']).then(_runTest);
+  }
 }
 
 main() {
diff --git a/pkg/polymer/test/bind_test.html b/pkg/polymer/test/bind_test.html
index 3b3970c..65aa6aa 100644
--- a/pkg/polymer/test/bind_test.html
+++ b/pkg/polymer/test/bind_test.html
@@ -13,7 +13,7 @@
   <body>
     <x-foo></x-foo>
 
-    <polymer-element name="x-bar" noscript>
+    <polymer-element name="x-bar">
       <template>
         x-bar
       </template>
@@ -27,6 +27,9 @@
         <x-bar id="bar" foo="{{foo}}" ></x-bar>
         <x-bar id="barBool" foo?="{{foo}}"></x-bar>
         <x-bar id="barContent">{{foo}}</x-bar>
+        <div id="bindId">
+          <template if="{{$['bar'].testValue}}">bar!</template>
+        </div>
       </template>
     </polymer-element>
 
diff --git a/pkg/polymer/test/build/linter_test.dart b/pkg/polymer/test/build/linter_test.dart
index 1e216e1..6cd294a 100644
--- a/pkg/polymer/test/build/linter_test.dart
+++ b/pkg/polymer/test/build/linter_test.dart
@@ -20,10 +20,10 @@
       'a|lib/test.html.messages': ''
     });
 
-  group('must use init.dart, dart.js, not boot.js', () {
+  group('must have Dart code to invoke initPolymer, dart.js, not boot.js', () {
     _testLinter('nothing to report', {
         'a|web/test.html': '<!DOCTYPE html><html>'
-            '<script type="application/dart" src="packages/polymer/init.dart">'
+            '<script type="application/dart" src="foo.dart">'
             '</script>'
             '<script src="packages/browser/dart.js"></script>'
             '</html>',
@@ -31,7 +31,7 @@
         'a|web/test.html.messages': '',
       });
 
-    _testLinter('missing init.dart and dart.js', {
+    _testLinter('missing Dart code and dart.js', {
         'a|web/test.html': '<!DOCTYPE html><html></html>',
       }, {
         'a|web/test.html.messages': 'error: $USE_INIT_DART\n'
@@ -41,7 +41,7 @@
     _testLinter('using deprecated boot.js', {
         'a|web/test.html': '<!DOCTYPE html><html>\n'
             '<script src="packages/polymer/boot.js"></script>'
-            '<script type="application/dart" src="packages/polymer/init.dart">'
+            '<script type="application/dart" src="foo.dart">'
             '</script>'
             '<script src="packages/browser/dart.js"></script>'
             '</html>',
diff --git a/pkg/polymer/test/custom_event_test.html b/pkg/polymer/test/custom_event_test.html
index 749bd26..7fa99b6 100644
--- a/pkg/polymer/test/custom_event_test.html
+++ b/pkg/polymer/test/custom_event_test.html
@@ -18,7 +18,7 @@
 
   <polymer-element name="test-custom-event">
     <template>
-      <foo-bar on-foo="fooHandler" on-barbaz="barBazHandler"></foo-bar>
+      <foo-bar on-foo="{{fooHandler}}" on-barbaz="{{barBazHandler}}"></foo-bar>
     </template>
   </polymer-element>
 
diff --git a/pkg/polymer/test/event_handlers_test.dart b/pkg/polymer/test/event_handlers_test.dart
new file mode 100644
index 0000000..779ccb6
--- /dev/null
+++ b/pkg/polymer/test/event_handlers_test.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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.test.event_handlers_test;
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/polymer.dart';
+import 'package:template_binding/template_binding.dart';
+
+@CustomTag('x-test')
+class XTest extends PolymerElement {
+  int _testCount = 0;
+  String _lastEvent;
+  String _lastMessage;
+  List list1 = [];
+  List list2 = [];
+  final _ready = new Completer();
+  Future _onTestDone;
+
+  XTest.created() : super.created() {
+    _onTestDone = _ready.future.then(_runTest);
+  }
+
+  ready() {
+    super.ready();
+    for (var i = 0; i < 10; i++) {
+      var model = new MiniModel(this, i);
+      list1.add(model);
+      list2.add(model);
+    }
+    _ready.complete();
+  }
+
+  hostTapAction(event, detail, node) => _logEvent(event);
+
+  divTapAction(event, detail, node) => _logEvent(event);
+
+  focusAction(event, detail, node) => _logEvent(event);
+
+  blurAction(event, detail, node) => _logEvent(event);
+
+  scrollAction(event, detail, node) => _logEvent(event);
+
+  itemTapAction(event, detail, node) {
+    var model = nodeBind(event.target).templateInstance.model;
+    _logEvent(event, "x-test callback ${model['this']}");
+  }
+
+  _logEvent(event, [message]) {
+    _testCount++;
+    _lastEvent = event.type;
+    _lastMessage = message;
+  }
+
+  _runTest(_) {
+    fire('tap', toNode: $['div']);
+    expect(_testCount, 2, reason: 'event heard at div and host');
+    expect(_lastEvent, 'tap', reason: 'tap handled');
+    fire('focus', toNode: $['input'], canBubble: false);
+    expect(_testCount, 3, reason: 'event heard by input');
+    expect(_lastEvent, 'focus', reason: 'focus handled');
+    fire('blur', toNode: $['input'], canBubble: false);
+    expect(_testCount, 4, reason: 'event heard by input');
+    expect(_lastEvent, 'blur', reason: 'blur handled');
+    fire('scroll', toNode: $['list'], canBubble: false);
+    expect(_testCount, 5, reason: 'event heard by list');
+    expect(_lastEvent, 'scroll', reason: 'scroll handled');
+    return onMutation($['list']).then((_) {
+      var l1 = $['list'].querySelectorAll('.list1')[4];
+      fire('tap', toNode: l1, canBubble: false);
+      expect(_testCount, 6, reason: 'event heard by list1 item');
+      expect(_lastEvent, 'tap', reason: 'tap handled');
+      expect(_lastMessage, 'x-test callback <mini-model 4>');
+
+      var l2 = $['list'].querySelectorAll('.list2')[3];
+      fire('tap', toNode: l2, canBubble: false);
+      expect(_testCount, 7, reason: 'event heard by list2 item');
+      expect(_lastEvent, 'tap', reason: 'tap handled by model');
+      expect(_lastMessage, 'mini-model callback <mini-model 3>');
+    });
+  }
+}
+
+class MiniModel extends Observable {
+  XTest _element;
+  @observable final int index;
+  @reflectable Function itemTapAction;
+  _itemTapAction(e, d, n) {
+    _element._logEvent(e, 'mini-model callback $this');
+    e.stopPropagation();
+  }
+  MiniModel(this._element, this.index) {
+    // TODO(sigmund): remove this and reflect directly on the method. This is
+    // needed to work around bug 13002
+    itemTapAction = _itemTapAction;
+  }
+  String toString() => "<mini-model $index>";
+}
+
+main() {
+  initPolymer();
+}
+
+@initMethod _init() {
+  useHtmlConfiguration();
+
+  setUp(() => Polymer.onReady);
+  test('events handled', () => (query('x-test') as XTest)._onTestDone);
+}
+
diff --git a/pkg/polymer/test/event_handlers_test.html b/pkg/polymer/test/event_handlers_test.html
new file mode 100644
index 0000000..0669974
--- /dev/null
+++ b/pkg/polymer/test/event_handlers_test.html
@@ -0,0 +1,59 @@
+<!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>
+  <!--polymer-test: this comment is needed for test_suite.dart-->
+  <!-- Test ported from:
+  https://github.com/Polymer/polymer/blob/b720085/test/html/event-handlers.html
+  -->
+  <head>
+    <title>event handlers</title>
+    <script src="packages/unittest/test_controller.js"></script>
+  </head>
+  <body>
+
+  <x-test>
+    <div>...light...</div>
+  </x-test>
+ 
+  <polymer-element name="x-test" on-tap="{{hostTapAction}}">
+    <template>
+      <style>
+        @host {
+          * {
+            display: block;
+          }
+        }
+        .gradient {
+          background: -webkit-gradient(linear, left top, left bottom,
+            color-stop(0%,#b4e391), color-stop(50%,#61c419),
+            color-stop(100%,#b4e391));
+        }
+      </style>
+
+      <div id="div" on-tap="{{divTapAction}}">Tap me!
+        <content></content>
+      </div>
+      <input id="input" on-focus="{{focusAction}}"
+                        on-blur="{{blurAction}}">focusy</input>
+      <div id="list"
+           style="height: 200px; overflow: auto; border: 1px solid black;"
+           on-scroll="{{scrollAction}}">
+        <div class="gradient">
+          <template repeat="{{list1}}">
+            <div class="list1" on-tap="{{itemTapAction}}">a {{index}}</div>
+          </template>
+          <template repeat="{{item in list2}}">
+            <div class="list2"
+                on-tap="{{@item.itemTapAction}}">b {{item.index}}</div>
+          </template>
+        </div>
+      </div>
+    </template>
+    <script type="application/dart" src="event_handlers_test.dart"></script>
+  </polymer-element>
+  </body>
+</html>
diff --git a/pkg/polymer/test/event_path_declarative_test.dart b/pkg/polymer/test/event_path_declarative_test.dart
new file mode 100644
index 0000000..a96779a
--- /dev/null
+++ b/pkg/polymer/test/event_path_declarative_test.dart
@@ -0,0 +1,120 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This is ported from event-path-declarative-test.dart in polymer/test/html/.
+// While the original test was intended to test event.path support, we changed
+// the test structure just to check that the event was handled in the expected
+// order.
+library polymer.test.event_path_declarative_test;
+
+import 'dart:async';
+import 'dart:collection';
+import 'dart:html';
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/polymer.dart';
+import 'package:template_binding/template_binding.dart';
+
+var _observedEvents = [];
+var _testFired;
+
+main() => initPolymer();
+
+@reflectable
+class XZug extends PolymerElement {
+
+  XZug.created() : super.created();
+
+  ready() {
+    shadowRoot.on['test-event'].listen((e) {
+      _testFired.complete(null);
+    });
+  }
+
+
+  contentTestEventHandler(e, detail, sender) {
+    _observedEvents.add(sender);
+  }
+
+  divTestEventHandler(e, detail, sender) {
+    _observedEvents.add(sender);
+  }
+
+  testEventHandler(e, detail, sender) {
+    _observedEvents.add(sender);
+  }
+}
+
+@reflectable
+class XFoo extends PolymerElement {
+  XFoo.created() : super.created();
+
+  contentTestEventHandler(e, detail, sender) {
+    _observedEvents.add(sender);
+  }
+
+  divTestEventHandler(e, detail, sender) {
+    _observedEvents.add(sender);
+  }
+
+  testEventHandler(e, detail, sender) {
+    _observedEvents.add(sender);
+  }
+}
+
+@reflectable
+class XBar extends PolymerElement {
+  XBar.created() : super.created();
+
+  contentTestEventHandler(e, detail, sender) {
+    _observedEvents.add(sender);
+  }
+
+  divTestEventHandler(e, detail, sender) {
+    _observedEvents.add(sender);
+  }
+
+  testEventHandler(e, detail, sender) {
+    _observedEvents.add(sender);
+  }
+}
+
+@initMethod _init() {
+  useHtmlConfiguration();
+  // TODO(sigmund): switch back to use @CustomTag. We seem to be running into a
+  // problem where using @CustomTag doesn't guarantee that we register the tags
+  // in the following order (the query from mirrors is non deterministic).
+  // We shouldn't care about registration order though. See dartbug.com/14459
+  Polymer.register('x-zug', XZug);
+  Polymer.register('x-foo', XFoo);
+  Polymer.register('x-bar', XBar);
+
+  _testFired = new Completer();
+
+  setUp(() => Polymer.onReady);
+  test('event paths', () {
+    var target = document.querySelector('#target');
+    target.dispatchEvent(new CustomEvent('test-event', canBubble: true));
+    return _testFired.future.then((_) {
+      var xBar = querySelector('x-bar');
+      var xBarDiv = xBar.shadowRoot.querySelector('#xBarDiv');
+      var xBarContent = xBar.shadowRoot.querySelector('#xBarContent');
+      var xFoo = xBar.shadowRoot.querySelector('x-foo');
+      var xFooDiv = xFoo.shadowRoot.querySelector('#xFooDiv');
+      var xFooContent = xFoo.shadowRoot.querySelector('#xFooContent');
+      var xZug = xFoo.shadowRoot.querySelector('x-zug');
+      var xZugDiv = xZug.shadowRoot.querySelector('#xZugDiv');
+      var xZugContent = xZug.shadowRoot.querySelector('#xZugContent');
+
+      var expectedPath = [ xBarContent, xBarDiv, xFooContent,
+          xZugContent, xZugDiv, xZug, xFooDiv, xFoo, xBar];
+      debugName(e) => '${e.localName}#${e.id}';
+      expect(_observedEvents, expectedPath, reason:
+        '<br>\nexpected: ${expectedPath.map(debugName).join(',')}'
+        '<br>\nactual: ${_observedEvents.map(debugName).join(',')}'
+        );
+    });
+  });
+}
diff --git a/pkg/polymer/test/event_path_declarative_test.html b/pkg/polymer/test/event_path_declarative_test.html
new file mode 100644
index 0000000..fefcbd2
--- /dev/null
+++ b/pkg/polymer/test/event_path_declarative_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>
+  <!--polymer-test: this comment is needed for test_suite.dart-->
+  <head><title>event path declarative test</title>
+    <script src="packages/unittest/test_controller.js"></script>
+    <!--
+    Test ported from:
+    https://github.com/Polymer/polymer/blob/7936ff8/test/html/event-path-declarative.html
+    -->
+  </head>
+  <body>
+    <x-bar><div id="target">Test</div></x-bar>
+    <polymer-element name="x-zug" on-test-event="{{testEventHandler}}">
+      <template>
+        x-zug:
+        <div id="xZugDiv" on-test-event="{{divTestEventHandler}}">
+          <content id="xZugContent" on-test-event="{{contentTestEventHandler}}">
+          </content>
+        </div>
+      </template>
+    </polymer-element>
+
+
+    <polymer-element name="x-foo" on-test-event="{{testEventHandler}}">
+      <template>
+        <style>
+          @host {
+              display: block;
+              border: 1px solid green;
+              padding: 10px;
+            }
+        </style>
+        x-foo:
+        <div id="xFooDiv" on-test-event="{{divTestEventHandler}}">
+          <x-zug><content id="xFooContent"
+                          on-test-event="{{contentTestEventHandler}}"></content>
+          </x-zug>
+        </div>
+      </template>
+    </polymer-element>
+
+
+    <polymer-element name="x-bar" on-test-event="{{testEventHandler}}">
+      <template>
+        <style>
+          @host {
+            display: block;
+            border: 1px solid red;
+            padding: 10px;
+          }
+
+          .clicky {
+            border: 1px solid black;
+          }
+
+        </style>
+        x-bar:
+        <x-foo>
+          <div class="clicky" id="xBarDiv"
+               on-test-event="{{divTestEventHandler}}">
+          <content id="xBarContent" on-test-event="{{contentTestEventHandler}}">
+          </content>
+          </div>
+        </x-foo>
+      </template>
+    </polymer-element>
+
+  <script type="application/dart" src="event_path_declarative_test.dart"></script>
+  </body>
+</html>
diff --git a/pkg/polymer/test/events_test.html b/pkg/polymer/test/events_test.html
index 4fce9d5..5ff6eab 100644
--- a/pkg/polymer/test/events_test.html
+++ b/pkg/polymer/test/events_test.html
@@ -19,7 +19,7 @@
   </head>
   <body>
 
-  <polymer-element name="test-a" on-click="clickHandler">
+  <polymer-element name="test-a" on-click="{{clickHandler}}">
     <template></template>
   </polymer-element>
 
@@ -27,7 +27,7 @@
     <template>
       <div>
         <span id="b-1">1</span>
-        <span id="b-2" on-click="clickHandler">2</span>
+        <span id="b-2" on-click="{{clickHandler}}">2</span>
       </div>
     </template>
   </polymer-element>
diff --git a/pkg/polymer/test/noscript_test.dart b/pkg/polymer/test/noscript_test.dart
new file mode 100644
index 0000000..d638713
--- /dev/null
+++ b/pkg/polymer/test/noscript_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/polymer.dart';
+import 'package:template_binding/template_binding.dart';
+
+main() {
+  initPolymer();
+  useHtmlConfiguration();
+  templateBind(querySelector("#a")).model = "foo";
+
+  setUp(() => Polymer.onReady);
+
+  test('template found with multiple noscript declarations', () {
+    expect(querySelector('x-a') is PolymerElement, isTrue);
+    expect(querySelector('x-a').shadowRoot.nodes.first.text, 'a');
+
+    expect(querySelector('x-c') is PolymerElement, isTrue);
+    expect(querySelector('x-c').shadowRoot.nodes.first.text, 'c');
+
+    expect(querySelector('x-b') is PolymerElement, isTrue);
+    expect(querySelector('x-b').shadowRoot.nodes.first.text, 'b');
+
+    expect(querySelector('x-d') is PolymerElement, isTrue);
+    expect(querySelector('x-d').shadowRoot.nodes.first.text, 'd');
+  });
+}
diff --git a/pkg/polymer/test/noscript_test.html b/pkg/polymer/test/noscript_test.html
new file mode 100644
index 0000000..dbb84af
--- /dev/null
+++ b/pkg/polymer/test/noscript_test.html
@@ -0,0 +1,28 @@
+<!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>
+  <!--polymer-test: this comment is needed for test_suite.dart-->
+    <title>register test</title>
+    <script src="packages/unittest/test_controller.js"></script>
+  </head>
+  <body>
+  <polymer-element name="x-a" noscript><template>a</template></polymer-element>
+  <polymer-element name="x-b" noscript><template>b</template></polymer-element>
+  <polymer-element name="x-c" noscript><template>c</template></polymer-element>
+  <polymer-element name="x-d" noscript><template>d</template></polymer-element>
+
+  <x-a></x-a>
+  <template id="a" bind>
+    <x-b></x-b>
+    <x-c></x-c>
+  </template>
+  <x-d></x-d>
+
+  <script type="application/dart" src="noscript_test.dart"></script>
+  </body>
+</html>
diff --git a/pkg/polymer/test/prop_attr_bind_reflection_test.dart b/pkg/polymer/test/prop_attr_bind_reflection_test.dart
index bf02da2..554bbfb 100644
--- a/pkg/polymer/test/prop_attr_bind_reflection_test.dart
+++ b/pkg/polymer/test/prop_attr_bind_reflection_test.dart
@@ -2,7 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async' show Completer;
 import 'dart:html';
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
diff --git a/pkg/polymer/test/prop_attr_reflection_test.dart b/pkg/polymer/test/prop_attr_reflection_test.dart
index e429114..37562da 100644
--- a/pkg/polymer/test/prop_attr_reflection_test.dart
+++ b/pkg/polymer/test/prop_attr_reflection_test.dart
@@ -6,7 +6,6 @@
 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 {
@@ -37,7 +36,7 @@
     observer.disconnect();
     completer.complete();
   })..observe(node, attributes: true);
-  Platform.flush();
+  scheduleMicrotask(Observable.dirtyCheck);
   return completer.future;
 }
 
diff --git a/pkg/polymer/test/publish_attributes_test.dart b/pkg/polymer/test/publish_attributes_test.dart
index bd0e071..c6ea12a 100644
--- a/pkg/polymer/test/publish_attributes_test.dart
+++ b/pkg/polymer/test/publish_attributes_test.dart
@@ -51,14 +51,9 @@
     published(tag) =>
         query('polymer-element[name=$tag]').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']);
+    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/template_distribute_dynamic_test.dart b/pkg/polymer/test/template_distribute_dynamic_test.dart
index 130264a..86c469e 100644
--- a/pkg/polymer/test/template_distribute_dynamic_test.dart
+++ b/pkg/polymer/test/template_distribute_dynamic_test.dart
@@ -5,7 +5,6 @@
 import 'dart:async';
 import 'dart:html';
 import 'package:polymer/polymer.dart';
-import 'package:polymer/platform.dart' as Platform;
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
 
@@ -30,9 +29,7 @@
       {'name': 'foo'},
       {'name': 'bar'}
     ];
-
-    Platform.flush();
-    Platform.endOfMicrotask(expectAsync0(() {
+    return new Future(() {
       // tickle SD polyfill
       offsetHeight;
       var children = this.$['echo'].children;
@@ -51,7 +48,7 @@
           'shadowDOMPolyfill distributes expected number of actual children.');
       }
       */
-    }));
+    });
   }
 }
 
diff --git a/pkg/polymer/test/unbind_test.dart b/pkg/polymer/test/unbind_test.dart
index e41e038..c6d2d6a 100644
--- a/pkg/polymer/test/unbind_test.dart
+++ b/pkg/polymer/test/unbind_test.dart
@@ -4,14 +4,13 @@
 
 library polymer.test.unbind_test;
 
-import 'dart:async' show Future;
+import 'dart:async' show Future, scheduleMicrotask;
 import 'dart:html';
 
 @MirrorsUsed(targets: const [Polymer], override: 'polymer.test.unbind_test')
 import 'dart:mirrors' show reflect, reflectClass, MirrorSystem, MirrorsUsed;
 
 import 'package:polymer/polymer.dart';
-import 'package:polymer/platform.dart' as Platform;
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
 
@@ -72,7 +71,7 @@
 unbindTests() {
   var xTest = document.query('x-test');
   xTest.foo = 'bar';
-  Platform.flush();
+  scheduleMicrotask(Observable.dirtyCheck);
 
   return delay(null).then((_) {
     expect(_unbound(xTest), null, reason:
@@ -88,7 +87,7 @@
     expect(_unbound(node), null, reason:
         'element is bound when not inserted');
     node.foo = 'bar';
-    Platform.flush();
+    scheduleMicrotask(Observable.dirtyCheck);
     return node;
   }).then(delay).then((node) {
     expect(node.fooWasChanged, true, reason: 'node is actually bound');
diff --git a/pkg/scheduled_test/test/descriptor/async_test.dart b/pkg/scheduled_test/test/descriptor/async_test.dart
index 15763bb..48fa883 100644
--- a/pkg/scheduled_test/test/descriptor/async_test.dart
+++ b/pkg/scheduled_test/test/descriptor/async_test.dart
@@ -10,7 +10,9 @@
 import '../metatest.dart';
 import 'utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass("async().create() forwards to file().create", () {
diff --git a/pkg/scheduled_test/test/descriptor/directory_test.dart b/pkg/scheduled_test/test/descriptor/directory_test.dart
index 82c6d8d..dfc1f3b 100644
--- a/pkg/scheduled_test/test/descriptor/directory_test.dart
+++ b/pkg/scheduled_test/test/descriptor/directory_test.dart
@@ -12,7 +12,9 @@
 import '../metatest.dart';
 import 'utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass("directory().create() creates a directory and its contents",
diff --git a/pkg/scheduled_test/test/descriptor/file_test.dart b/pkg/scheduled_test/test/descriptor/file_test.dart
index 0b2a90f..bf62f62 100644
--- a/pkg/scheduled_test/test/descriptor/file_test.dart
+++ b/pkg/scheduled_test/test/descriptor/file_test.dart
@@ -11,7 +11,9 @@
 import '../metatest.dart';
 import 'utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass('file().create() creates a file', () {
diff --git a/pkg/scheduled_test/test/descriptor/nothing_test.dart b/pkg/scheduled_test/test/descriptor/nothing_test.dart
index b3a74d1..8afe303 100644
--- a/pkg/scheduled_test/test/descriptor/nothing_test.dart
+++ b/pkg/scheduled_test/test/descriptor/nothing_test.dart
@@ -11,7 +11,9 @@
 import '../metatest.dart';
 import 'utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass("nothing().create() does nothing", () {
diff --git a/pkg/scheduled_test/test/descriptor/pattern_test.dart b/pkg/scheduled_test/test/descriptor/pattern_test.dart
index 4056425..826343d 100644
--- a/pkg/scheduled_test/test/descriptor/pattern_test.dart
+++ b/pkg/scheduled_test/test/descriptor/pattern_test.dart
@@ -10,7 +10,9 @@
 
 String sandbox;
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass("pattern().validate() succeeds if there's a file matching "
diff --git a/pkg/scheduled_test/test/metatest.dart b/pkg/scheduled_test/test/metatest.dart
index 9e94d07..e846773 100644
--- a/pkg/scheduled_test/test/metatest.dart
+++ b/pkg/scheduled_test/test/metatest.dart
@@ -107,40 +107,47 @@
 /// The cached [Future] for [_inChildIsolate].
 Future<bool> _inChildIsolateFuture;
 
+/// The initial message received by the isolate.
+var _initialMessage;
+
+void metaTestInit(message) {
+  _initialMessage = message;
+}
+
 /// Returns whether or not we're running in a child isolate that's supposed to
 /// run a test.
 Future<bool> get _inChildIsolate {
   if (_inChildIsolateFuture != null) return _inChildIsolateFuture;
 
-  var completer = new Completer();
-  port.receive((message, replyTo) {
-    _testToRun = message['testToRun'];
-    _executable = message['executable'];
-    _replyTo = replyTo;
-    port.close();
-    completer.complete(true);
-  });
-
-  // TODO(nweiz): don't use a timeout here once issue 8416 is fixed.
-  _inChildIsolateFuture = timeout(completer.future, 500, () {
-    port.close();
-    return false;
-  });
+  if (_initialMessage == null) {
+    _inChildIsolateFuture = new Future.value(false);
+  } else {
+    _testToRun = _initialMessage['testToRun'];
+    _executable = _initialMessage['executable'];
+    _replyTo = _initialMessage['replyTo'];
+    _inChildIsolateFuture = new Future.value(true);
+  }
   return _inChildIsolateFuture;
 }
 
 /// Runs the test described by [description] in its own isolate. Returns a map
 /// describing the results of that test run.
 Future<Map> _runInIsolate(String description) {
+  var replyPort = new ReceivePort();
   // TODO(nweiz): Don't use path here once issue 8440 is fixed.
-  var future = spawnUri(path.join(path.current, Platform.script)).call({
+  return Isolate.spawnUri(Uri.parse(path.join(path.current, Platform.script)),
+      [], {
     'testToRun': description,
-    'executable': Platform.executable
-  });
-  // TODO(nweiz): Remove this timeout once issue 8417 is fixed and we can
-  // capture top-level exceptions.
-  return timeout(future, 30 * 1000, () {
-    throw 'Timed out waiting for test to complete.';
+    'executable': Platform.executable,
+    'replyTo': replyPort.sendPort
+  }).then((_) {
+    var future = replyPort.first;
+
+    // TODO(nweiz): Remove this timeout once issue 8417 is fixed and we can
+    // capture top-level exceptions.
+    return timeout(future, 30 * 1000, () {
+      throw 'Timed out waiting for test to complete.';
+    });
   });
 }
 
diff --git a/pkg/scheduled_test/test/scheduled_future_matchers_test.dart b/pkg/scheduled_test/test/scheduled_future_matchers_test.dart
index e1e3699..10efdc1 100644
--- a/pkg/scheduled_test/test/scheduled_future_matchers_test.dart
+++ b/pkg/scheduled_test/test/scheduled_future_matchers_test.dart
@@ -9,7 +9,9 @@
 import 'metatest.dart';
 import 'utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass("expect(..., completes) with a completing future should pass",
diff --git a/pkg/scheduled_test/test/scheduled_process_test.dart b/pkg/scheduled_test/test/scheduled_process_test.dart
index f937ae8..2f9387f 100644
--- a/pkg/scheduled_test/test/scheduled_process_test.dart
+++ b/pkg/scheduled_test/test/scheduled_process_test.dart
@@ -15,7 +15,9 @@
 import 'metatest.dart';
 import 'utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass("a process must have kill() or shouldExit() called", () {
diff --git a/pkg/scheduled_test/test/scheduled_server_test.dart b/pkg/scheduled_test/test/scheduled_server_test.dart
index 4170874..77dd13c 100644
--- a/pkg/scheduled_test/test/scheduled_server_test.dart
+++ b/pkg/scheduled_test/test/scheduled_server_test.dart
@@ -15,7 +15,9 @@
 import 'metatest.dart';
 import 'utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass("a server with no handlers does nothing", () {
diff --git a/pkg/scheduled_test/test/scheduled_test/abort_test.dart b/pkg/scheduled_test/test/scheduled_test/abort_test.dart
index ef313a1..d41632f 100644
--- a/pkg/scheduled_test/test/scheduled_test/abort_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/abort_test.dart
@@ -9,7 +9,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass("aborting the schedule before it's started running should "
diff --git a/pkg/scheduled_test/test/scheduled_test/current_schedule_current_task_test.dart b/pkg/scheduled_test/test/scheduled_test/current_schedule_current_task_test.dart
index ab8a19e..e2999d1 100644
--- a/pkg/scheduled_test/test/scheduled_test/current_schedule_current_task_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/current_schedule_current_task_test.dart
@@ -9,7 +9,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass('currentSchedule.currentTask returns the current task while '
diff --git a/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart b/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart
index e372cc6..988ac79 100644
--- a/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart
@@ -10,7 +10,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass('currentSchedule.errors contains the error in the onComplete '
diff --git a/pkg/scheduled_test/test/scheduled_test/current_schedule_state_test.dart b/pkg/scheduled_test/test/scheduled_test/current_schedule_state_test.dart
index 15ddf29..1f84779 100644
--- a/pkg/scheduled_test/test/scheduled_test/current_schedule_state_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/current_schedule_state_test.dart
@@ -7,7 +7,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass('currentSchedule.state starts out as SET_UP', () {
diff --git a/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart b/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart
index f4f8924..7ad9685 100644
--- a/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart
@@ -10,7 +10,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass("nested schedule() runs its function immediately (but "
diff --git a/pkg/scheduled_test/test/scheduled_test/on_complete_test.dart b/pkg/scheduled_test/test/scheduled_test/on_complete_test.dart
index f9a02b9..dc1cdac 100644
--- a/pkg/scheduled_test/test/scheduled_test/on_complete_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/on_complete_test.dart
@@ -9,7 +9,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass('the onComplete queue is run if a test is successful', () {
diff --git a/pkg/scheduled_test/test/scheduled_test/on_exception_test.dart b/pkg/scheduled_test/test/scheduled_test/on_exception_test.dart
index 8a97038..b100c36 100644
--- a/pkg/scheduled_test/test/scheduled_test/on_exception_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/on_exception_test.dart
@@ -9,7 +9,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass('the onException queue is not run if a test is successful',
diff --git a/pkg/scheduled_test/test/scheduled_test/out_of_band_task_test.dart b/pkg/scheduled_test/test/scheduled_test/out_of_band_task_test.dart
index b3cc1b6..35d292d 100644
--- a/pkg/scheduled_test/test/scheduled_test/out_of_band_task_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/out_of_band_task_test.dart
@@ -10,7 +10,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass("out-of-band schedule() runs its function immediately (but "
diff --git a/pkg/scheduled_test/test/scheduled_test/set_up_test.dart b/pkg/scheduled_test/test/scheduled_test/set_up_test.dart
index 7d6c538..fa3d47e 100644
--- a/pkg/scheduled_test/test/scheduled_test/set_up_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/set_up_test.dart
@@ -7,7 +7,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass('setUp is run before each test', () {
diff --git a/pkg/scheduled_test/test/scheduled_test/signal_error_test.dart b/pkg/scheduled_test/test/scheduled_test/signal_error_test.dart
index 395157f..5d67443 100644
--- a/pkg/scheduled_test/test/scheduled_test/signal_error_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/signal_error_test.dart
@@ -10,7 +10,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsFail('an out-of-band error reported via signalError is '
diff --git a/pkg/scheduled_test/test/scheduled_test/simple_test.dart b/pkg/scheduled_test/test/scheduled_test/simple_test.dart
index 7cf83ec..3c6a9dd 100644
--- a/pkg/scheduled_test/test/scheduled_test/simple_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/simple_test.dart
@@ -9,7 +9,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass('a scheduled test with a correct synchronous expectation '
diff --git a/pkg/scheduled_test/test/scheduled_test/task_return_value_test.dart b/pkg/scheduled_test/test/scheduled_test/task_return_value_test.dart
index b935dd7..2abf508 100644
--- a/pkg/scheduled_test/test/scheduled_test/task_return_value_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/task_return_value_test.dart
@@ -10,7 +10,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass("an error thrown in a scheduled task should be piped to that "
diff --git a/pkg/scheduled_test/test/scheduled_test/timeout_test.dart b/pkg/scheduled_test/test/scheduled_test/timeout_test.dart
index a14063a..7151a48 100644
--- a/pkg/scheduled_test/test/scheduled_test/timeout_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/timeout_test.dart
@@ -10,7 +10,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsPass("a single task that takes too long will cause a timeout "
diff --git a/pkg/scheduled_test/test/scheduled_test/wrap_async_test.dart b/pkg/scheduled_test/test/scheduled_test/wrap_async_test.dart
index a83d66a..d28e22c 100644
--- a/pkg/scheduled_test/test/scheduled_test/wrap_async_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/wrap_async_test.dart
@@ -10,7 +10,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsFail('an out-of-band failure in wrapAsync is handled', () {
diff --git a/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart b/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart
index add75ee..84cb29c 100644
--- a/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart
@@ -10,7 +10,9 @@
 import '../metatest.dart';
 import '../utils.dart';
 
-void main() {
+void main(List<String> args, message) {
+  metaTestInit(message);
+
   setUpTimeout();
 
   expectTestsFail('an out-of-band failure in wrapFuture is handled', () {
diff --git a/pkg/serialization/test/serialization_test.dart b/pkg/serialization/test/serialization_test.dart
index 83232c9..4d5ebf4 100644
--- a/pkg/serialization/test/serialization_test.dart
+++ b/pkg/serialization/test/serialization_test.dart
@@ -549,8 +549,9 @@
       n3.parent = n1;
       var s = nodeSerializerReflective(n1);
       var output = s.write(n2);
-      var port = spawnFunction(echo);
-      return port.call(output).then(verify);
+      ReceivePort port = new ReceivePort();
+      var remote = Isolate.spawn(echo, [output, port.sendPort]);
+      port.first.then(verify);
   });
 }
 
@@ -808,8 +809,8 @@
  * Function used in an isolate to make sure that the output passes through
  * isolate serialization properly.
  */
-void echo() {
-  port.receive((msg, reply) {
-    reply.send(msg);
-  });
+void echo(initialMessage) {
+  var msg = initialMessage[0];
+  var reply = initialMessage[1];
+  reply.send(msg);
 }
diff --git a/pkg/template_binding/lib/src/element.dart b/pkg/template_binding/lib/src/element.dart
index ccb1a28..c3c4992 100644
--- a/pkg/template_binding/lib/src/element.dart
+++ b/pkg/template_binding/lib/src/element.dart
@@ -8,11 +8,20 @@
 class _ElementExtension extends NodeBindExtension {
   _ElementExtension(Element node) : super._(node);
 
-  // TODO(jmesserly): should path be optional, and default to empty path?
-  // It is used that way in at least one path in JS TemplateElement tests
-  // (see "BindImperative" test in original JS code).
-  NodeBinding createBinding(String name, model, String path) =>
-      new _AttributeBinding(_node, name, model, path);
+  NodeBinding bind(String name, model, [String path]) {
+    _self.unbind(name);
+
+    var binding;
+    if (_node is OptionElement && name == 'value') {
+      // Note: because <option> can be a semantic template, <option> will be
+      // a TemplateBindExtension sometimes. So we need to handle it here.
+      _node.attributes.remove(name);
+      binding = new _OptionValueBinding(_node, model, path);
+    } else {
+      binding = new _AttributeBinding(_node, name, model, path);
+    }
+    return bindings[name] = binding;
+  }
 }
 
 class _AttributeBinding extends NodeBinding {
@@ -32,7 +41,7 @@
 
   Element get node => super.node;
 
-  void boundValueChanged(value) {
+  void valueChanged(value) {
     if (conditional) {
       if (_toBoolean(value)) {
         node.attributes[property] = '';
@@ -46,3 +55,29 @@
     }
   }
 }
+
+class _OptionValueBinding extends _ValueBinding {
+  _OptionValueBinding(node, model, path) : super(node, model, path);
+
+  OptionElement get node => super.node;
+
+  void valueChanged(newValue) {
+    var oldValue = null;
+    var selectBinding = null;
+    var select = node.parent;
+    if (select is SelectElement) {
+      var valueBinding = nodeBind(select).bindings['value'];
+      if (valueBinding is _SelectBinding) {
+        selectBinding = valueBinding;
+        oldValue = select.value;
+      }
+    }
+
+    super.valueChanged(newValue);
+
+    if (selectBinding != null && !selectBinding.closed &&
+        select.value != oldValue) {
+      selectBinding.nodeValueChanged(null);
+    }
+  }
+}
diff --git a/pkg/template_binding/lib/src/input_bindings.dart b/pkg/template_binding/lib/src/input_bindings.dart
index e00b3a9..fc89dc5 100644
--- a/pkg/template_binding/lib/src/input_bindings.dart
+++ b/pkg/template_binding/lib/src/input_bindings.dart
@@ -11,7 +11,7 @@
     _eventSub = _getStreamForInputType(node).listen(nodeValueChanged);
   }
 
-  void boundValueChanged(newValue);
+  void valueChanged(newValue);
 
   void nodeValueChanged(e);
 
@@ -41,6 +41,7 @@
   }();
 
   static Stream<Event> _getStreamForInputType(element) {
+    if (element is OptionElement) return element.onInput;
     switch (element.type) {
       case 'checkbox':
         return _checkboxEventType.forTarget(element);
@@ -59,13 +60,14 @@
 
   get node => super.node;
 
-  void boundValueChanged(newValue) {
+  void valueChanged(newValue) {
     // Note: node can be an InputElement or TextAreaElement. Both have "value".
-    (node as dynamic).value = sanitizeBoundValue(newValue);
+    node.value = sanitizeBoundValue(newValue);
   }
 
   void nodeValueChanged(e) {
-    value = (node as dynamic).value;
+    value = node.value;
+    Observable.dirtyCheck();
   }
 }
 
@@ -74,7 +76,7 @@
 
   InputElement get node => super.node;
 
-  void boundValueChanged(newValue) {
+  void valueChanged(newValue) {
     node.checked = _toBoolean(newValue);
   }
 
@@ -93,6 +95,8 @@
         }
       }
     }
+
+    Observable.dirtyCheck();
   }
 
   // |element| is assumed to be an HTMLInputElement with |type| == 'radio'.
@@ -105,7 +109,6 @@
   //   http://www.whatwg.org/specs/web-apps/current-work/multipage/number-state.html#radio-button-group
   //
   static Iterable _getAssociatedRadioButtons(element) {
-    if (!_isNodeInDocument(element)) return [];
     if (element.form != null) {
       return element.form.nodes.where((el) {
         return el != element &&
@@ -114,41 +117,32 @@
             el.name == element.name;
       });
     } else {
-      var radios = element.ownerDocument.queryAll(
+      var treeScope = _getTreeScope(element);
+      if (treeScope == null) return const [];
+
+      var radios = treeScope.querySelectorAll(
           'input[type="radio"][name="${element.name}"]');
       return radios.where((el) => el != element && el.form == null);
     }
   }
-
-  // TODO(jmesserly): polyfill document.contains API instead of doing it here
-  static bool _isNodeInDocument(Node node) {
-    // On non-IE this works:
-    // return node.ownerDocument.contains(node);
-    var document = node.ownerDocument;
-    if (node == document || node.parentNode == document) return true;
-    return document.documentElement.contains(node);
-  }
 }
 
-class _SelectedIndexBinding extends _InputBinding {
-  _SelectedIndexBinding(node, model, path)
-      : super(node, 'selectedIndex', model, path);
+class _SelectBinding extends _InputBinding {
+  _SelectBinding(node, property, model, path)
+      : super(node, property, model, path);
 
   SelectElement get node => super.node;
 
-  void boundValueChanged(value) {
-    var newValue = _toInt(value);
-    if (newValue <= node.length) {
-      node.selectedIndex = newValue;
-      return;
-    }
+  void valueChanged(newValue) {
+    if (_tryUpdateValue(newValue)) return;
 
     // The binding may wish to bind to an <option> which has not yet been
     // produced by a child <template>. Furthermore, we may need to wait for
     // <optgroup> iterating and then for <option>.
     //
-    // Unlike the JavaScript MDV, we don't have a special "Object.observe" event
-    // loop to schedule on. (See the the "ensureScheduled" function:
+    // Unlike the JavaScript implemenation, we don't have a special
+    // "Object.observe" event loop to schedule on.
+    // (See the the "ensureScheduled" function:
     // https://github.com/Polymer/mdv/commit/9a51ad7ed74a292bf71662cea28acbd151ff65c8)
     //
     // Instead we use scheduleMicrotask. Each <template repeat> needs a delay of
@@ -159,20 +153,35 @@
     //   * once for OPTGROUP
     //   * once for OPTION.
     // The resulting 2 * 2 is our maxRetries.
+    // TODO(jmesserly): a much better approach would be to find the nested
+    // <template> and wait on some future that completes when it has expanded.
     var maxRetries = 4;
     delaySetSelectedIndex() {
-      if (newValue > node.length && --maxRetries >= 0) {
+      if (!_tryUpdateValue(newValue) && maxRetries-- > 0) {
         scheduleMicrotask(delaySetSelectedIndex);
-      } else {
-        node.selectedIndex = newValue;
       }
     }
 
     scheduleMicrotask(delaySetSelectedIndex);
   }
 
+  bool _tryUpdateValue(newValue) {
+    if (property == 'selectedIndex') {
+      var intValue = _toInt(newValue);
+      node.selectedIndex = intValue;
+      return node.selectedIndex == intValue;
+    } else if (property == 'value') {
+      node.value = sanitizeBoundValue(newValue);
+      return node.value == newValue;
+    }
+  }
+
   void nodeValueChanged(e) {
-    value = node.selectedIndex;
+    if (property == 'selectedIndex') {
+      value = node.selectedIndex;
+    } else if (property == 'value') {
+      value = node.value;
+    }
   }
 
   // TODO(jmesserly,sigmund): I wonder how many bindings typically convert from
@@ -180,7 +189,7 @@
   // have something like a int/num binding converter (either as a base class or
   // a wrapper).
   static int _toInt(value) {
-    if (value is String) return int.parse(value, onError: (_) => null);
-    return value is int ? value : null;
+    if (value is String) return int.parse(value, onError: (_) => 0);
+    return value is int ? value : 0;
   }
 }
diff --git a/pkg/template_binding/lib/src/input_element.dart b/pkg/template_binding/lib/src/input_element.dart
index 0a6d45a..a599f24 100644
--- a/pkg/template_binding/lib/src/input_element.dart
+++ b/pkg/template_binding/lib/src/input_element.dart
@@ -10,16 +10,15 @@
 
   InputElement get _node => super._node;
 
-  NodeBinding createBinding(String name, model, String path) {
-    if (name == 'value') {
-      // TODO(rafaelw): Maybe template should remove all binding instructions.
-      _node.attributes.remove(name);
-      return new _ValueBinding(_node, model, path);
+  NodeBinding bind(String name, model, [String path]) {
+    if (name != 'value' && name != 'checked') {
+      return super.bind(name, model, path);
     }
-    if (name == 'checked') {
-      _node.attributes.remove(name);
-      return new _CheckedBinding(_node, model, path);
-    }
-    return super.createBinding(name, model, path);
+
+    _self.unbind(name);
+    _node.attributes.remove(name);
+    return bindings[name] = name == 'value' ?
+        new _ValueBinding(_node, model, path) :
+        new _CheckedBinding(_node, model, path);
   }
 }
diff --git a/pkg/template_binding/lib/src/node.dart b/pkg/template_binding/lib/src/node.dart
index a1bc29c..791214b 100644
--- a/pkg/template_binding/lib/src/node.dart
+++ b/pkg/template_binding/lib/src/node.dart
@@ -12,34 +12,13 @@
   NodeBindExtension._(this._node);
 
   /**
-   * Creates a binding to the attribute [name] to the [path] of the [model].
-   *
-   * This can be overridden by custom elements to provide the binding used in
-   * [bind]. This will only create the binding; it will not add
-   * it to [bindings].
-   *
-   * You should not need to call this directly except from [bind].
-   */
-  NodeBinding createBinding(String name, model, String path) => null;
-
-  /**
    * Binds the attribute [name] to the [path] of the [model].
    * Path is a String of accessors such as `foo.bar.baz`.
    * Returns the `NodeBinding` instance.
    */
-  NodeBinding bind(String name, model, String path) {
-    var binding = bindings[name];
-    if (binding != null) binding.close();
-
-    // Note: dispatch through the node so it can override this.
-    binding = nodeBind(_node).createBinding(name, model, path);
-
-    bindings[name] = binding;
-    if (binding == null) {
-      window.console.error('Unhandled binding to Node: '
-          '$this $name $model $path');
-    }
-    return binding;
+  NodeBinding bind(String name, model, [String path]) {
+    window.console.error('Unhandled binding to Node: '
+        '$this $name $model $path');
   }
 
   /** Unbinds the attribute [name]. */
@@ -65,6 +44,13 @@
     return _bindings;
   }
 
+  /**
+   * Dispatch support so custom HtmlElement's can override these methods.
+   * A public method like [this.bind] should not call another public method such
+   * as [this.unbind]. Instead it should dispatch through [_self.unbind].
+   */
+  NodeBindExtension get _self => _node is NodeBindExtension ? _node : this;
+
   TemplateInstance _templateInstance;
 
   /** Gets the template instance that instantiated this node, if any. */
@@ -199,7 +185,7 @@
   get model => _model;
 
   /** True if this binding has been [closed]. */
-  bool get closed => _observer == null;
+  bool get closed => _node == null;
 
   /** The value at the [path] on [model]. */
   get value => _observer.value;
@@ -208,21 +194,27 @@
     _observer.value = newValue;
   }
 
-  NodeBinding(this._node, this.property, this._model, this.path) {
-    // Create the path observer
-    _observer = new PathObserver(model, path);
+  NodeBinding(this._node, this.property, this._model, [String path])
+      : path = path != null ? path : '' {
     _observePath();
   }
 
-  void _observePath() {
-    _pathSub = _observer.bindSync(boundValueChanged);
+  _observePath() {
+    // Fast path if we're observing PathObserver.value
+    if (model is PathObserver && path == 'value') {
+      _observer = model;
+    } else {
+      // Create the path observer
+      _observer = new PathObserver(model, path);
+    }
+    _pathSub = _observer.bindSync(valueChanged);
   }
 
   /** Called when [value] changes to update the [node]. */
-  // TODO(jmesserly): the impl in MDV uses mirrors to set the property,
-  // but that isn't used except for specific known fields like "textContent",
-  // so I'm overridding this in the subclasses instead.
-  void boundValueChanged(newValue);
+  // TODO(jmesserly): the impl in template_binding uses reflection to set the
+  // property, but that isn't used except for specific known fields like
+  // "textContent", so I'm overridding this in the subclasses instead.
+  void valueChanged(newValue);
 
   /** Called to sanitize the value before it is assigned into the property. */
   sanitizeBoundValue(value) => value == null ? '' : '$value';
diff --git a/pkg/template_binding/lib/src/select_element.dart b/pkg/template_binding/lib/src/select_element.dart
index e1cc143..432b049 100644
--- a/pkg/template_binding/lib/src/select_element.dart
+++ b/pkg/template_binding/lib/src/select_element.dart
@@ -10,12 +10,14 @@
 
   SelectElement get _node => super._node;
 
-  NodeBinding createBinding(String name, model, String path) {
-    if (name.toLowerCase() == 'selectedindex') {
-      // TODO(rafaelw): Maybe template should remove all binding instructions.
-      _node.attributes.remove(name);
-      return new _SelectedIndexBinding(_node, model, path);
+  NodeBinding bind(String name, model, [String path]) {
+    if (name == 'selectedindex') name = 'selectedIndex';
+    if (name != 'selectedIndex' && name != 'value') {
+      return super.bind(name, model, path);
     }
-    return super.createBinding(name, model, path);
+
+    _self.unbind(name);
+    _node.attributes.remove(name);
+    return bindings[name] = new _SelectBinding(_node, name, model, path);
   }
 }
diff --git a/pkg/template_binding/lib/src/template.dart b/pkg/template_binding/lib/src/template.dart
index ee344f4..be6a6fd 100644
--- a/pkg/template_binding/lib/src/template.dart
+++ b/pkg/template_binding/lib/src/template.dart
@@ -21,19 +21,18 @@
 
   Element get _node => super._node;
 
-  NodeBinding createBinding(String name, model, String path) {
+  NodeBinding bind(String name, model, [String path]) {
     switch (name) {
       case 'bind':
       case 'repeat':
       case 'if':
+        _self.unbind(name);
         if (_templateIterator == null) {
           _templateIterator = new _TemplateIterator(_node);
         }
-        // TODO(jmesserly): why do we do this here and nowhere else?
-        if (path == null) path = '';
-        return new _TemplateBinding(this, name, model, path);
+        return bindings[name] = new _TemplateBinding(this, name, model, path);
       default:
-        return super.createBinding(name, model, path);
+        return super.bind(name, model, path);
     }
   }
 
@@ -88,17 +87,8 @@
     Element result = null;
     var refId = _node.attributes['ref'];
     if (refId != null) {
-      var treeScope = _node;
-      while (treeScope.parentNode != null) {
-        treeScope = treeScope.parentNode;
-      }
-
-      // Note: JS code tests that getElementById is present. We can't do that
-      // easily, so instead check for the types known to implement it.
-      if (treeScope is Document ||
-          treeScope is ShadowRoot ||
-          treeScope is SvgSvgElement) {
-
+      var treeScope = _getTreeScope(_node);
+      if (treeScope != null) {
         result = treeScope.getElementById(refId);
       }
     }
@@ -309,12 +299,12 @@
   // https://github.com/Polymer/mdv/issues/127
   _TemplateBinding(ext, name, model, path)
       : _ext = ext, super(ext._node, name, model, path) {
-    _ext._templateIterator.inputs.bind(property, model, path);
+    _ext._templateIterator.inputs.bind(property, model, this.path);
   }
 
   // These are no-ops because we don't use the underlying PathObserver.
   void _observePath() {}
-  void boundValueChanged(newValue) {}
+  void valueChanged(newValue) {}
 
   void close() {
     if (closed) return;
@@ -323,3 +313,16 @@
     super.close();
   }
 }
+
+_getTreeScope(Node node) {
+  while (node.parentNode != null) {
+    node = node.parentNode;
+  }
+
+  // Note: JS code tests that getElementById is present. We can't do that
+  // easily, so instead check for the types known to implement it.
+  if (node is Document || node is ShadowRoot || node is SvgSvgElement) {
+    return node;
+  }
+  return null;
+}
diff --git a/pkg/template_binding/lib/src/text.dart b/pkg/template_binding/lib/src/text.dart
index 8b66752..ecb2581 100644
--- a/pkg/template_binding/lib/src/text.dart
+++ b/pkg/template_binding/lib/src/text.dart
@@ -8,16 +8,20 @@
 class _TextExtension extends NodeBindExtension {
   _TextExtension(Text node) : super._(node);
 
-  NodeBinding createBinding(String name, model, String path) {
-    if (name == 'text') return new _TextBinding(_node, model, path);
-    return super.createBinding(name, model, path);
+  NodeBinding bind(String name, model, [String path]) {
+    // Dart note: 'text' instead of 'textContent' to match the DOM property.
+    if (name != 'text') {
+      return super.bind(name, model, path);
+    }
+    unbind(name);
+    return bindings[name] = new _TextBinding(_node, model, path);
   }
 }
 
 class _TextBinding extends NodeBinding {
   _TextBinding(node, model, path) : super(node, 'text', model, path);
 
-  void boundValueChanged(newValue) {
+  void valueChanged(newValue) {
     node.text = sanitizeBoundValue(newValue);
   }
 }
diff --git a/pkg/template_binding/lib/src/text_area_element.dart b/pkg/template_binding/lib/src/text_area_element.dart
index 8eec85f..0d462d1 100644
--- a/pkg/template_binding/lib/src/text_area_element.dart
+++ b/pkg/template_binding/lib/src/text_area_element.dart
@@ -10,12 +10,11 @@
 
   TextAreaElement get _node => super._node;
 
-  NodeBinding createBinding(String name, model, String path) {
-    if (name == 'value') {
-      // TODO(rafaelw): Maybe template should remove all binding instructions.
-      _node.attributes.remove(name);
-      return new _ValueBinding(_node, model, path);
-    }
-    return super.createBinding(name, model, path);
+  NodeBinding bind(String name, model, [String path]) {
+    if (name != 'value') return super.bind(name, model, path);
+
+    _self.unbind(name);
+    _node.attributes.remove(name);
+    return bindings[name] = new _ValueBinding(_node, model, path);
   }
 }
diff --git a/pkg/template_binding/lib/template_binding.dart b/pkg/template_binding/lib/template_binding.dart
index 72976ac..c8bd3b6 100644
--- a/pkg/template_binding/lib/template_binding.dart
+++ b/pkg/template_binding/lib/template_binding.dart
@@ -104,6 +104,7 @@
   var extension = _expando[node];
   if (extension != null) return extension;
 
+  // TODO(jmesserly): switch on localName?
   if (node is InputElement) {
     extension = new _InputElementExtension(node);
   } else if (node is SelectElement) {
diff --git a/pkg/template_binding/test/custom_element_bindings_test.dart b/pkg/template_binding/test/custom_element_bindings_test.dart
index 1779361..c9556d5 100644
--- a/pkg/template_binding/test/custom_element_bindings_test.dart
+++ b/pkg/template_binding/test/custom_element_bindings_test.dart
@@ -165,18 +165,20 @@
 
   MyCustomElement.created() : super.created();
 
-  NodeBinding createBinding(String name, model, String path) {
+  NodeBinding bind(String name, model, [String path]) {
     switch (name) {
       case 'my-point':
       case 'scary-monster':
-        return new _MyCustomBinding(this, name, model, path);
+        attributes.remove(name);
+        unbind(name);
+        return bindings[name] = new _MyCustomBinding(this, name, model, path);
     }
-    return nodeBindFallback(this).createBinding(name, model, path);
+    return nodeBindFallback(this).bind(name, model, path);
   }
 
-  bind(name, model, path) => nodeBindFallback(this).bind(name, model, path);
   unbind(name) => nodeBindFallback(this).unbind(name);
   unbindAll() => nodeBindFallback(this).unbindAll();
+  get bindings => nodeBindFallback(this).bindings;
 }
 
 class _MyCustomBinding extends NodeBinding {
@@ -188,7 +190,7 @@
 
   MyCustomElement get node => super.node;
 
-  void boundValueChanged(newValue) {
+  void valueChanged(newValue) {
     if (property == 'my-point') node.myPoint = newValue;
     if (property == 'scary-monster') node.scaryMonster = newValue;
   }
diff --git a/pkg/template_binding/test/element_bindings_test.dart b/pkg/template_binding/test/element_bindings_test.dart
deleted file mode 100644
index 56c42c4..0000000
--- a/pkg/template_binding/test/element_bindings_test.dart
+++ /dev/null
@@ -1,397 +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.
-
-library template_binding.test.element_bindings_test;
-
-import 'dart:html';
-import 'package:observe/observe.dart';
-import 'package:template_binding/template_binding.dart';
-import 'package:unittest/html_config.dart';
-import 'package:unittest/unittest.dart';
-import 'utils.dart';
-
-// Note: this file ported from
-// https://github.com/toolkitchen/mdv/blob/master/tests/element_bindings.js
-
-main() {
-  useHtmlConfiguration();
-  group('Element Bindings', elementBindingTests);
-}
-
-observePath(obj, path) => new PathObserver(obj, path);
-
-elementBindingTests() {
-  setUp(() {
-    document.body.append(testDiv = new DivElement());
-  });
-
-  tearDown(() {
-    testDiv.remove();
-    testDiv = null;
-  });
-
-  observeTest('Text', () {
-    var template = new Element.html('<template bind>{{a}} and {{b}}');
-    testDiv.append(template);
-    var model = toObservable({'a': 1, 'b': 2});
-    templateBind(template).model = model;
-    performMicrotaskCheckpoint();
-    var text = testDiv.nodes[1];
-    expect(text.text, '1 and 2');
-
-    model['a'] = 3;
-    performMicrotaskCheckpoint();
-    expect(text.text, '3 and 2');
-  });
-
-  observeTest('SimpleBinding', () {
-    var el = new DivElement();
-    var model = toObservable({'a': '1'});
-    nodeBind(el).bind('foo', model, 'a');
-    performMicrotaskCheckpoint();
-    expect(el.attributes['foo'], '1');
-
-    model['a'] = '2';
-    performMicrotaskCheckpoint();
-    expect(el.attributes['foo'], '2');
-
-    model['a'] = 232.2;
-    performMicrotaskCheckpoint();
-    expect(el.attributes['foo'], '232.2');
-
-    model['a'] = 232;
-    performMicrotaskCheckpoint();
-    expect(el.attributes['foo'], '232');
-
-    model['a'] = null;
-    performMicrotaskCheckpoint();
-    expect(el.attributes['foo'], '');
-  });
-
-  observeTest('SimpleBindingWithDashes', () {
-    var el = new DivElement();
-    var model = toObservable({'a': '1'});
-    nodeBind(el).bind('foo-bar', model, 'a');
-    performMicrotaskCheckpoint();
-    expect(el.attributes['foo-bar'], '1');
-
-    model['a'] = '2';
-    performMicrotaskCheckpoint();
-    expect(el.attributes['foo-bar'], '2');
-  });
-
-  observeTest('SimpleBindingWithComment', () {
-    var el = new DivElement();
-    el.innerHtml = '<!-- Comment -->';
-    var model = toObservable({'a': '1'});
-    nodeBind(el).bind('foo-bar', model, 'a');
-    performMicrotaskCheckpoint();
-    expect(el.attributes['foo-bar'], '1');
-
-    model['a'] = '2';
-    performMicrotaskCheckpoint();
-    expect(el.attributes['foo-bar'], '2');
-  });
-
-  observeTest('PlaceHolderBindingText', () {
-    var model = toObservable({
-      'adj': 'cruel',
-      'noun': 'world'
-    });
-
-    var el = new DivElement();
-    el.text = 'dummy';
-    el.nodes.first.text = 'Hello {{ adj }} {{noun}}!';
-    var template = new Element.html('<template bind>');
-    templateBind(template).content.append(el);
-    testDiv.append(template);
-    templateBind(template).model = model;
-
-    performMicrotaskCheckpoint();
-    el = testDiv.nodes[1].nodes.first;
-    expect(el.text, 'Hello cruel world!');
-
-    model['adj'] = 'happy';
-    performMicrotaskCheckpoint();
-    expect(el.text, 'Hello happy world!');
-  });
-
-  observeTest('InputElementTextBinding', () {
-    var model = toObservable({'val': 'ping'});
-
-    var el = new InputElement();
-    nodeBind(el).bind('value', model, 'val');
-    performMicrotaskCheckpoint();
-    expect(el.value, 'ping');
-
-    el.value = 'pong';
-    dispatchEvent('input', el);
-    expect(model['val'], 'pong');
-
-    // Try a deep path.
-    model = toObservable({'a': {'b': {'c': 'ping'}}});
-
-    nodeBind(el).bind('value', model, 'a.b.c');
-    performMicrotaskCheckpoint();
-    expect(el.value, 'ping');
-
-    el.value = 'pong';
-    dispatchEvent('input', el);
-    expect(observePath(model, 'a.b.c').value, 'pong');
-
-    // Start with the model property being absent.
-    model['a']['b'].remove('c');
-    performMicrotaskCheckpoint();
-    expect(el.value, '');
-
-    el.value = 'pong';
-    dispatchEvent('input', el);
-    expect(observePath(model, 'a.b.c').value, 'pong');
-    performMicrotaskCheckpoint();
-
-    // Model property unreachable (and unsettable).
-    model['a'].remove('b');
-    performMicrotaskCheckpoint();
-    expect(el.value, '');
-
-    el.value = 'pong';
-    dispatchEvent('input', el);
-    expect(observePath(model, 'a.b.c').value, null);
-  });
-
-  observeTest('InputElementCheckbox', () {
-    var model = toObservable({'val': true});
-
-    var el = new InputElement();
-    testDiv.append(el);
-    el.type = 'checkbox';
-    nodeBind(el).bind('checked', model, 'val');
-    performMicrotaskCheckpoint();
-    expect(el.checked, true);
-
-    model['val'] = false;
-    performMicrotaskCheckpoint();
-    expect(el.checked, false);
-
-    el.click();
-    expect(model['val'], true);
-
-    el.click();
-    expect(model['val'], false);
-
-    el.onClick.listen((_) {
-      expect(model['val'], true);
-    });
-    el.onChange.listen((_) {
-      expect(model['val'], true);
-    });
-
-    el.dispatchEvent(new MouseEvent('click', view: window));
-  });
-
-  observeTest('InputElementCheckbox - binding updated on click', () {
-    var model = toObservable({'val': true});
-
-    var el = new InputElement();
-    testDiv.append(el);
-    el.type = 'checkbox';
-    nodeBind(el).bind('checked', model, 'val');
-    performMicrotaskCheckpoint();
-    expect(el.checked, true);
-
-    el.onClick.listen((_) {
-      expect(model['val'], false);
-    });
-
-    el.dispatchEvent(new MouseEvent('click', view: window));
-  });
-
-  observeTest('InputElementCheckbox - binding updated on change', () {
-    var model = toObservable({'val': true});
-
-    var el = new InputElement();
-    testDiv.append(el);
-    el.type = 'checkbox';
-    nodeBind(el).bind('checked', model, 'val');
-    performMicrotaskCheckpoint();
-    expect(el.checked, true);
-
-    el.onChange.listen((_) {
-      expect(model['val'], false);
-    });
-
-    el.dispatchEvent(new MouseEvent('click', view: window));
-   });
-
-  observeTest('InputElementRadio', () {
-    var model = toObservable({'val1': true, 'val2': false, 'val3': false,
-        'val4': true});
-    var RADIO_GROUP_NAME = 'observeTest';
-
-    var container = testDiv;
-
-    var el1 = new InputElement();
-    testDiv.append(el1);
-    el1.type = 'radio';
-    el1.name = RADIO_GROUP_NAME;
-    nodeBind(el1).bind('checked', model, 'val1');
-
-    var el2 = new InputElement();
-    testDiv.append(el2);
-    el2.type = 'radio';
-    el2.name = RADIO_GROUP_NAME;
-    nodeBind(el2).bind('checked', model, 'val2');
-
-    var el3 = new InputElement();
-    testDiv.append(el3);
-    el3.type = 'radio';
-    el3.name = RADIO_GROUP_NAME;
-    nodeBind(el3).bind('checked', model, 'val3');
-
-    var el4 = new InputElement();
-    testDiv.append(el4);
-    el4.type = 'radio';
-    el4.name = 'othergroup';
-    nodeBind(el4).bind('checked', model, 'val4');
-
-    performMicrotaskCheckpoint();
-    expect(el1.checked, true);
-    expect(el2.checked, false);
-    expect(el3.checked, false);
-    expect(el4.checked, true);
-
-    model['val1'] = false;
-    model['val2'] = true;
-    performMicrotaskCheckpoint();
-    expect(el1.checked, false);
-    expect(el2.checked, true);
-    expect(el3.checked, false);
-    expect(el4.checked, true);
-
-    el1.checked = true;
-    dispatchEvent('change', el1);
-    expect(model['val1'], true);
-    expect(model['val2'], false);
-    expect(model['val3'], false);
-    expect(model['val4'], true);
-
-    el3.checked = true;
-    dispatchEvent('change', el3);
-    expect(model['val1'], false);
-    expect(model['val2'], false);
-    expect(model['val3'], true);
-    expect(model['val4'], true);
-  });
-
-  observeTest('InputElementRadioMultipleForms', () {
-    var model = toObservable({'val1': true, 'val2': false, 'val3': false,
-        'val4': true});
-    var RADIO_GROUP_NAME = 'observeTest';
-
-    var form1 = new FormElement();
-    testDiv.append(form1);
-    var form2 = new FormElement();
-    testDiv.append(form2);
-
-    var el1 = new InputElement();
-    form1.append(el1);
-    el1.type = 'radio';
-    el1.name = RADIO_GROUP_NAME;
-    nodeBind(el1).bind('checked', model, 'val1');
-
-    var el2 = new InputElement();
-    form1.append(el2);
-    el2.type = 'radio';
-    el2.name = RADIO_GROUP_NAME;
-    nodeBind(el2).bind('checked', model, 'val2');
-
-    var el3 = new InputElement();
-    form2.append(el3);
-    el3.type = 'radio';
-    el3.name = RADIO_GROUP_NAME;
-    nodeBind(el3).bind('checked', model, 'val3');
-
-    var el4 = new InputElement();
-    form2.append(el4);
-    el4.type = 'radio';
-    el4.name = RADIO_GROUP_NAME;
-    nodeBind(el4).bind('checked', model, 'val4');
-
-    performMicrotaskCheckpoint();
-    expect(el1.checked, true);
-    expect(el2.checked, false);
-    expect(el3.checked, false);
-    expect(el4.checked, true);
-
-    el2.checked = true;
-    dispatchEvent('change', el2);
-    expect(model['val1'], false);
-    expect(model['val2'], true);
-
-    // Radio buttons in form2 should be unaffected
-    expect(model['val3'], false);
-    expect(model['val4'], true);
-
-    el3.checked = true;
-    dispatchEvent('change', el3);
-    expect(model['val3'], true);
-    expect(model['val4'], false);
-
-    // Radio buttons in form1 should be unaffected
-    expect(model['val1'], false);
-    expect(model['val2'], true);
-  });
-
-  observeTest('BindToChecked', () {
-    var div = new DivElement();
-    testDiv.append(div);
-    var child = new DivElement();
-    div.append(child);
-    var input = new InputElement();
-    child.append(input);
-    input.type = 'checkbox';
-
-    var model = toObservable({'a': {'b': false}});
-    nodeBind(input).bind('checked', model, 'a.b');
-
-    input.click();
-    expect(model['a']['b'], true);
-
-    input.click();
-    expect(model['a']['b'], false);
-  });
-
-  observeTest('Select selectedIndex', () {
-    var select = new SelectElement();
-    testDiv.append(select);
-    var option0 = select.append(new OptionElement());
-    var option1 = select.append(new OptionElement());
-    var option2 = select.append(new OptionElement());
-
-    var model = toObservable({'val': 2});
-
-    nodeBind(select).bind('selectedIndex', model, 'val');
-    performMicrotaskCheckpoint();
-    expect(select.selectedIndex, 2);
-
-    select.selectedIndex = 1;
-    dispatchEvent('change', select);
-    expect(model['val'], 1);
-  });
-
-  observeTest('MultipleReferences', () {
-    var el = new DivElement();
-    var template = new Element.html('<template bind>');
-    templateBind(template).content.append(el);
-    testDiv.append(template);
-
-    var model = toObservable({'foo': 'bar'});
-    el.attributes['foo'] = '{{foo}} {{foo}}';
-    templateBind(template).model = model;
-
-    performMicrotaskCheckpoint();
-    el = testDiv.nodes[1];
-    expect(el.attributes['foo'], 'bar bar');
-  });
-}
diff --git a/pkg/template_binding/test/node_bindings_test.dart b/pkg/template_binding/test/node_bindings_test.dart
index 04ef8d4..6391b38 100644
--- a/pkg/template_binding/test/node_bindings_test.dart
+++ b/pkg/template_binding/test/node_bindings_test.dart
@@ -5,8 +5,14 @@
 library template_binding.test.node_bindings_test;
 
 import 'dart:html';
-import 'package:observe/observe.dart' show toObservable;
-import 'package:template_binding/template_binding.dart';
+
+@MirrorsUsed(targets: const [NodeBinding], override:
+    'template_binding.test.node_bindings_test')
+import 'dart:mirrors';
+
+import 'package:observe/observe.dart' show toObservable, PathObserver;
+import 'package:template_binding/template_binding.dart'
+  show nodeBind, NodeBinding;
 import 'package:unittest/html_config.dart';
 import 'package:unittest/unittest.dart';
 import 'utils.dart';
@@ -16,10 +22,7 @@
 
 main() {
   useHtmlConfiguration();
-  group('Node Bindings', nodeBindingTests);
-}
 
-nodeBindingTests() {
   setUp(() {
     document.body.append(testDiv = new DivElement());
   });
@@ -29,7 +32,14 @@
     testDiv = null;
   });
 
-  observeTest('Text', () {
+
+  group('Text bindings', testBindings);
+  group('Element attribute bindings', elementBindings);
+  group('Form Element bindings', formBindings);
+}
+
+testBindings() {
+  observeTest('Basic', () {
     var text = new Text('hi');
     var model = toObservable({'a': 1});
     nodeBind(text).bind('text', model, 'a');
@@ -47,7 +57,94 @@
     // TODO(rafaelw): Throw on binding to unavailable property?
   });
 
-  observeTest('Element', () {
+  observeTest('No Path', () {
+    var text = new Text('hi');
+    var model = 1;
+    nodeBind(text).bind('text', model);
+    expect(text.text, '1');
+  });
+
+  observeTest('Path unreachable', () {
+    var text = testDiv.append(new Text('hi'));
+    var model = 1;
+    nodeBind(text).bind('text', model, 'a');
+    expect(text.text, '');
+  });
+
+  observeTest('Observer is Model', () {
+    _observer(x) => reflect(x).getField(
+        privateSymbol(NodeBinding, '_observer')).reflectee;
+
+    var text = new Text('');
+    var model = toObservable({'a': {'b': {'c': 1}}});
+    var observer = new PathObserver(model, 'a.b.c');
+    nodeBind(text).bind('text', observer, 'value');
+    expect(text.text, '1');
+
+    var binding = nodeBind(text).bindings['text'];
+    expect(binding, isNotNull);
+    expect(privateField(binding, '_observer'), observer,
+        reason: 'should reuse observer');
+
+    model['a']['b']['c'] = 2;
+    performMicrotaskCheckpoint();
+    expect(text.text, '2');
+    nodeBind(text).unbind('text');
+  });
+}
+
+elementBindings() {
+  observeTest('Basic', () {
+    var el = new DivElement();
+    var model = toObservable({'a': '1'});
+    nodeBind(el).bind('foo', model, 'a');
+    performMicrotaskCheckpoint();
+    expect(el.attributes['foo'], '1');
+
+    model['a'] = '2';
+    performMicrotaskCheckpoint();
+    expect(el.attributes['foo'], '2');
+
+    model['a'] = 232.2;
+    performMicrotaskCheckpoint();
+    expect(el.attributes['foo'], '232.2');
+
+    model['a'] = 232;
+    performMicrotaskCheckpoint();
+    expect(el.attributes['foo'], '232');
+
+    model['a'] = null;
+    performMicrotaskCheckpoint();
+    expect(el.attributes['foo'], '');
+  });
+
+  observeTest('No Path', () {
+    var el = testDiv.append(new DivElement());
+    var model = 1;
+    nodeBind(el).bind('foo', model);
+    expect(el.attributes['foo'], '1');
+  });
+
+  observeTest('Path unreachable', () {
+    var el = testDiv.append(new DivElement());
+    var model = toObservable({});
+    nodeBind(el).bind('foo', model, 'bar');
+    expect(el.attributes['foo'], '');
+  });
+
+  observeTest('Dashes', () {
+    var el = testDiv.append(new DivElement());
+    var model = toObservable({'a': '1'});
+    nodeBind(el).bind('foo-bar', model, 'a');
+    performMicrotaskCheckpoint();
+    expect(el.attributes['foo-bar'], '1');
+
+    model['a'] = '2';
+    performMicrotaskCheckpoint();
+    expect(el.attributes['foo-bar'], '2');
+  });
+
+  observeTest('Element.id, Element.hidden?', () {
     var element = new DivElement();
     var model = toObservable({'a': 1, 'b': 2});
     nodeBind(element).bind('hidden?', model, 'a');
@@ -74,6 +171,15 @@
     expect(element.id, 'x');
   });
 
+  observeTest('Element.id - path unreachable', () {
+    var element = testDiv.append(new DivElement());
+    var model = toObservable({});
+    nodeBind(element).bind('id', model, 'a');
+    expect(element.id, '');
+  });
+}
+
+formBindings() {
   inputTextAreaValueTest(String tagName) {
     var el = new Element.tag(tagName);
     testDiv.nodes.add(el);
@@ -102,8 +208,32 @@
     expect(el.value, '');
   }
 
-  observeTest('Input.value', () => inputTextAreaValueTest('input'));
-  observeTest('TextArea.value', () => inputTextAreaValueTest('textarea'));
+  inputTextAreaNoPath(String tagName) {
+    var el = testDiv.append(new Element.tag(tagName));
+    var model = 42;
+    nodeBind(el).bind('value', model);
+    expect(el.value, '42');
+  }
+
+  inputTextAreaPathUnreachable(String tagName) {
+    var el = testDiv.append(new Element.tag(tagName));
+    var model = toObservable({});
+    nodeBind(el).bind('value', model, 'a');
+    expect(el.value, '');
+  }
+
+  observeTest('Input.value',
+      () => inputTextAreaValueTest('input'));
+  observeTest('Input.value - no path',
+      () => inputTextAreaNoPath('input'));
+  observeTest('Input.value - path unreachable',
+      () => inputTextAreaPathUnreachable('input'));
+  observeTest('TextArea.value',
+      () => inputTextAreaValueTest('textarea'));
+  observeTest('TextArea.value - no path',
+      () => inputTextAreaNoPath('textarea'));
+  observeTest('TextArea.value - path unreachable',
+      () => inputTextAreaPathUnreachable('textarea'));
 
   observeTest('Radio Input', () {
     var input = new InputElement();
@@ -129,24 +259,412 @@
         reason: 'disconnected binding should not fire');
   });
 
-  observeTest('Checkbox Input', () {
-    var input = new InputElement();
-    testDiv.append(input);
+  observeTest('Input.value - user value rejected', () {
+    var model = toObservable({'val': 'ping'});
+
+    var el = new InputElement();
+    nodeBind(el).bind('value', model, 'val');
+    performMicrotaskCheckpoint();
+    expect(el.value, 'ping');
+
+    el.value = 'pong';
+    dispatchEvent('input', el);
+    expect(model['val'], 'pong');
+
+    // Try a deep path.
+    model = toObservable({'a': {'b': {'c': 'ping'}}});
+
+    nodeBind(el).bind('value', model, 'a.b.c');
+    performMicrotaskCheckpoint();
+    expect(el.value, 'ping');
+
+    el.value = 'pong';
+    dispatchEvent('input', el);
+    expect(new PathObserver(model, 'a.b.c').value, 'pong');
+
+    // Start with the model property being absent.
+    model['a']['b'].remove('c');
+    performMicrotaskCheckpoint();
+    expect(el.value, '');
+
+    el.value = 'pong';
+    dispatchEvent('input', el);
+    expect(new PathObserver(model, 'a.b.c').value, 'pong');
+    performMicrotaskCheckpoint();
+
+    // Model property unreachable (and unsettable).
+    model['a'].remove('b');
+    performMicrotaskCheckpoint();
+    expect(el.value, '');
+
+    el.value = 'pong';
+    dispatchEvent('input', el);
+    expect(new PathObserver(model, 'a.b.c').value, null);
+  });
+
+  observeTest('(Checkbox)Input.checked', () {
+    var el = testDiv.append(new InputElement());
+    el.type = 'checkbox';
+
+    var model = toObservable({'x': true});
+    nodeBind(el).bind('checked', model, 'x');
+    expect(el.checked, true);
+
+    model['x'] = false;
+    expect(el.checked, true, reason: 'changes delivered async');
+    performMicrotaskCheckpoint();
+    expect(el.checked, false);
+
+    el.click();
+    expect(model['x'], true);
+    performMicrotaskCheckpoint();
+
+    el.click();
+    expect(model['x'], false);
+  });
+
+  observeTest('(Checkbox)Input.checked - path unreachable', () {
+    var input = testDiv.append(new InputElement());
     input.type = 'checkbox';
+    var model = toObservable({});
+    nodeBind(input).bind('checked', model, 'x');
+    expect(input.checked, false);
+  });
+
+  observeTest('(Checkbox)Input.checked 2', () {
+    var model = toObservable({'val': true});
+
+    var el = testDiv.append(new InputElement());
+    el.type = 'checkbox';
+    nodeBind(el).bind('checked', model, 'val');
+    performMicrotaskCheckpoint();
+    expect(el.checked, true);
+
+    model['val'] = false;
+    performMicrotaskCheckpoint();
+    expect(el.checked, false);
+
+    el.click();
+    expect(model['val'], true);
+
+    el.click();
+    expect(model['val'], false);
+
+    el.onClick.listen((_) {
+      expect(model['val'], true);
+    });
+    el.onChange.listen((_) {
+      expect(model['val'], true);
+    });
+
+    el.dispatchEvent(new MouseEvent('click', view: window));
+  });
+
+  observeTest('(Checkbox)Input.checked - binding updated on click', () {
+    var model = toObservable({'val': true});
+
+    var el = new InputElement();
+    testDiv.append(el);
+    el.type = 'checkbox';
+    nodeBind(el).bind('checked', model, 'val');
+    performMicrotaskCheckpoint();
+    expect(el.checked, true);
+
+    el.onClick.listen((_) {
+      expect(model['val'], false);
+    });
+
+    el.dispatchEvent(new MouseEvent('click', view: window));
+  });
+
+  observeTest('(Checkbox)Input.checked - binding updated on change', () {
+    var model = toObservable({'val': true});
+
+    var el = new InputElement();
+    testDiv.append(el);
+    el.type = 'checkbox';
+    nodeBind(el).bind('checked', model, 'val');
+    performMicrotaskCheckpoint();
+    expect(el.checked, true);
+
+    el.onChange.listen((_) {
+      expect(model['val'], false);
+    });
+
+    el.dispatchEvent(new MouseEvent('click', view: window));
+  });
+
+  observeTest('(Radio)Input.checked', () {
+    var input = testDiv.append(new InputElement());
+    input.type = 'radio';
     var model = toObservable({'x': true});
     nodeBind(input).bind('checked', model, 'x');
     expect(input.checked, true);
 
     model['x'] = false;
-    expect(input.checked, true, reason: 'changes delivered async');
+    expect(input.checked, true);
     performMicrotaskCheckpoint();
     expect(input.checked, false);
 
-    input.click();
+    input.checked = true;
+    dispatchEvent('change', input);
     expect(model['x'], true);
-    performMicrotaskCheckpoint();
 
-    input.click();
-    expect(model['x'], false);
+    nodeBind(input).unbind('checked');
+
+    input.checked = false;
+    dispatchEvent('change', input);
+    expect(model['x'], true);
   });
+
+  radioInputChecked2(host) {
+    var model = toObservable({'val1': true, 'val2': false, 'val3': false,
+        'val4': true});
+    var RADIO_GROUP_NAME = 'test';
+
+    var container = host.append(new DivElement());
+
+    var el1 = container.append(new InputElement());
+    el1.type = 'radio';
+    el1.name = RADIO_GROUP_NAME;
+    nodeBind(el1).bind('checked', model, 'val1');
+
+    var el2 = container.append(new InputElement());
+    el2.type = 'radio';
+    el2.name = RADIO_GROUP_NAME;
+    nodeBind(el2).bind('checked', model, 'val2');
+
+    var el3 = container.append(new InputElement());
+    el3.type = 'radio';
+    el3.name = RADIO_GROUP_NAME;
+    nodeBind(el3).bind('checked', model, 'val3');
+
+    var el4 = container.append(new InputElement());
+    el4.type = 'radio';
+    el4.name = 'othergroup';
+    nodeBind(el4).bind('checked', model, 'val4');
+
+    performMicrotaskCheckpoint();
+    expect(el1.checked, true);
+    expect(el2.checked, false);
+    expect(el3.checked, false);
+    expect(el4.checked, true);
+
+    model['val1'] = false;
+    model['val2'] = true;
+    performMicrotaskCheckpoint();
+    expect(el1.checked, false);
+    expect(el2.checked, true);
+    expect(el3.checked, false);
+    expect(el4.checked, true);
+
+    el1.checked = true;
+    dispatchEvent('change', el1);
+    expect(model['val1'], true);
+    expect(model['val2'], false);
+    expect(model['val3'], false);
+    expect(model['val4'], true);
+
+    el3.checked = true;
+    dispatchEvent('change', el3);
+    expect(model['val1'], false);
+    expect(model['val2'], false);
+    expect(model['val3'], true);
+    expect(model['val4'], true);
+  }
+
+  observeTest('(Radio)Input.checked 2', () {
+    radioInputChecked2(testDiv);
+  });
+
+  observeTest('(Radio)Input.checked 2 - ShadowRoot', () {
+    if (!ShadowRoot.supported) return;
+
+    var div = new DivElement();
+    var shadowRoot = div.createShadowRoot();
+    radioInputChecked2(shadowRoot);
+    unbindAll(shadowRoot);
+  });
+
+  radioInputCheckedMultipleForms(host) {
+    var model = toObservable({'val1': true, 'val2': false, 'val3': false,
+        'val4': true});
+    var RADIO_GROUP_NAME = 'observeTest';
+
+    var container = testDiv.append(new DivElement());
+    var form1 = new FormElement();
+    container.append(form1);
+    var form2 = new FormElement();
+    container.append(form2);
+
+    var el1 = new InputElement();
+    form1.append(el1);
+    el1.type = 'radio';
+    el1.name = RADIO_GROUP_NAME;
+    nodeBind(el1).bind('checked', model, 'val1');
+
+    var el2 = new InputElement();
+    form1.append(el2);
+    el2.type = 'radio';
+    el2.name = RADIO_GROUP_NAME;
+    nodeBind(el2).bind('checked', model, 'val2');
+
+    var el3 = new InputElement();
+    form2.append(el3);
+    el3.type = 'radio';
+    el3.name = RADIO_GROUP_NAME;
+    nodeBind(el3).bind('checked', model, 'val3');
+
+    var el4 = new InputElement();
+    form2.append(el4);
+    el4.type = 'radio';
+    el4.name = RADIO_GROUP_NAME;
+    nodeBind(el4).bind('checked', model, 'val4');
+
+    performMicrotaskCheckpoint();
+    expect(el1.checked, true);
+    expect(el2.checked, false);
+    expect(el3.checked, false);
+    expect(el4.checked, true);
+
+    el2.checked = true;
+    dispatchEvent('change', el2);
+    expect(model['val1'], false);
+    expect(model['val2'], true);
+
+    // Radio buttons in form2 should be unaffected
+    expect(model['val3'], false);
+    expect(model['val4'], true);
+
+    el3.checked = true;
+    dispatchEvent('change', el3);
+    expect(model['val3'], true);
+    expect(model['val4'], false);
+
+    // Radio buttons in form1 should be unaffected
+    expect(model['val1'], false);
+    expect(model['val2'], true);
+  }
+
+  observeTest('(Radio)Input.checked - multiple forms', () {
+    radioInputCheckedMultipleForms(testDiv);
+  });
+
+  observeTest('(Radio)Input.checked 2 - ShadowRoot', () {
+    if (!ShadowRoot.supported) return;
+
+    var shadowRoot = new DivElement().createShadowRoot();
+    radioInputChecked2(shadowRoot);
+    unbindAll(shadowRoot);
+  });
+
+  observeTest('Select.selectedIndex', () {
+    var select = new SelectElement();
+    testDiv.append(select);
+    var option0 = select.append(new OptionElement());
+    var option1 = select.append(new OptionElement());
+    var option2 = select.append(new OptionElement());
+
+    var model = toObservable({'val': 2});
+
+    nodeBind(select).bind('selectedIndex', model, 'val');
+    performMicrotaskCheckpoint();
+    expect(select.selectedIndex, 2);
+
+    select.selectedIndex = 1;
+    dispatchEvent('change', select);
+    expect(model['val'], 1);
+  });
+
+  observeTest('Select.selectedIndex - path NaN', () {
+    var select = new SelectElement();
+    testDiv.append(select);
+    var option0 = select.append(new OptionElement());
+    var option1 = select.append(new OptionElement());
+    option1.selected = true;
+    var option2 = select.append(new OptionElement());
+
+    var model = toObservable({'val': 'foo'});
+
+    nodeBind(select).bind('selectedIndex', model, 'val');
+    performMicrotaskCheckpoint();
+    expect(select.selectedIndex, 0);
+  });
+
+  observeTest('Select.selectedIndex - path unreachable', () {
+    var select = new SelectElement();
+    testDiv.append(select);
+    var option0 = select.append(new OptionElement());
+    var option1 = select.append(new OptionElement());
+    option1.selected = true;
+    var option2 = select.append(new OptionElement());
+
+    var model = toObservable({});
+
+    nodeBind(select).bind('selectedIndex', model, 'val');
+    performMicrotaskCheckpoint();
+    expect(select.selectedIndex, 0);
+  });
+
+  observeTest('Option.value', () {
+    var option = testDiv.append(new OptionElement());
+    var model = toObservable({'x': 42});
+    nodeBind(option).bind('value', model, 'x');
+    expect(option.value, '42');
+
+    model['x'] = 'Hi';
+    expect(option.value, '42');
+    performMicrotaskCheckpoint();
+    expect(option.value, 'Hi');
+  });
+
+  observeTest('Select.value', () {
+    var select = testDiv.append(new SelectElement());
+    testDiv.append(select);
+    var option0 = select.append(new OptionElement());
+    var option1 = select.append(new OptionElement());
+    var option2 = select.append(new OptionElement());
+
+    var model = toObservable({
+      'opt0': 'a',
+      'opt1': 'b',
+      'opt2': 'c',
+      'selected': 'b'
+    });
+
+    nodeBind(option0).bind('value', model, 'opt0');
+    nodeBind(option1).bind('value', model, 'opt1');
+    nodeBind(option2).bind('value', model, 'opt2');
+
+    nodeBind(select).bind('value', model, 'selected');
+    performMicrotaskCheckpoint();
+    expect(select.value, 'b');
+
+    select.value = 'c';
+    dispatchEvent('change', select);
+    expect(model['selected'], 'c');
+
+    model['opt2'] = 'X';
+    performMicrotaskCheckpoint();
+    expect(select.value, 'X');
+    expect(model['selected'], 'X');
+
+    model['selected'] = 'a';
+    performMicrotaskCheckpoint();
+    expect(select.value, 'a');
+  });
+}
+
+privateField(x, name) => reflect(x).getField(
+    privateSymbol(reflect(x).type, name)).reflectee;
+
+// TODO(jmesserly): fix this when it's easier to get a private symbol.
+privateSymbol(TypeMirror type, String name) {
+  while (type != null) {
+    var symbol = type.variables.keys.firstWhere(
+        (s) => MirrorSystem.getName(s) == name, orElse: () => null);
+    if (symbol != null) return symbol;
+    type = type.superclass;
+  }
+  return null;
 }
diff --git a/pkg/template_binding/test/template_element_test.dart b/pkg/template_binding/test/template_element_test.dart
index 005c137..a878090 100644
--- a/pkg/template_binding/test/template_element_test.dart
+++ b/pkg/template_binding/test/template_element_test.dart
@@ -155,20 +155,20 @@
     var model = toObservable({'b': 'B'});
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 2);
     expect(div.nodes.last.text, 'aBc');
 
     model['b'] = 'b';
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.last.text, 'abc');
 
     model['b'] = null;
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.last.text, 'ac');
 
     model = null;
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     // setting model isn't observable.
     expect(div.nodes.last.text, 'ac');
   });
@@ -179,20 +179,20 @@
     var model = toObservable({ 'data': {'b': 'B'} });
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 2);
     expect(div.nodes.last.text, 'aBc');
 
     model['data']['b'] = 'b';
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.last.text, 'abc');
 
     model['data'] = toObservable({'b': 'X'});
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.last.text, 'aXc');
 
     model['data'] = null;
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.last.text, 'ac');
   });
 
@@ -202,25 +202,25 @@
     var model = toObservable({'b': 'B', 'd': 1});
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 2);
     expect(div.nodes.last.text, 'aBc');
 
     model['b'] = 'b';
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.last.text, 'abc');
 
     // TODO(jmesserly): MDV set this to empty string and relies on JS conversion
     // rules. Is that intended?
     // See https://github.com/toolkitchen/mdv/issues/59
     model['d'] = null;
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 1);
 
     model['d'] = 'here';
     model['b'] = 'd';
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 2);
     expect(div.nodes.last.text, 'adc');
   });
@@ -232,12 +232,12 @@
     var model = toObservable({'b': {'value': 'B'}});
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 2);
     expect(div.nodes.last.text, 'aBc');
 
     model['b'] = toObservable({'value': 'b'});
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.last.text, 'abc');
   });
 
@@ -249,16 +249,16 @@
     var model = toObservable({'b': 'B'});
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 2);
     expect(div.nodes.last.attributes['foo'], 'aBc');
 
     model['b'] = 'b';
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.last.attributes['foo'], 'abc');
 
     model['b'] = 'X';
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.last.attributes['foo'], 'aXc');
   });
 
@@ -270,13 +270,13 @@
     var model = toObservable({'b': 'b'});
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 2);
     expect(div.nodes.last.attributes['foo'], '');
     expect(div.nodes.last.attributes, isNot(contains('foo?')));
 
     model['b'] = null;
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.last.attributes, isNot(contains('foo')));
   });
 
@@ -287,19 +287,19 @@
     var model = toObservable([0, 1, 2]);
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 4);
 
     model.length = 1;
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 2);
 
     model.addAll(toObservable([3, 4]));
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 4);
 
     model.removeRange(1, 2);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 3);
   });
 
@@ -315,7 +315,7 @@
     ]);
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 6);
     var template = div.firstChild;
 
@@ -323,19 +323,19 @@
     checkExpandos(template.nextNode);
 
     model.sort((a, b) => a['val'] - b['val']);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     checkExpandos(template.nextNode);
 
     model = toObservable(model.reversed);
     recursivelySetTemplateModel(div, model);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     checkExpandos(template.nextNode);
 
     for (var item in model) {
       item['val'] += 1;
     }
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes[1].text, "11");
     expect(div.nodes[2].text, "9");
     expect(div.nodes[3].text, "6");
@@ -350,7 +350,7 @@
     var model = toObservable({ 'foo': { 'bar': 5 }});
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 2);
     var template = div.firstChild;
 
@@ -359,7 +359,7 @@
 
     model = toObservable({'foo': model['foo']});
     recursivelySetTemplateModel(div, model);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     checkExpandos(template.nextNode);
   });
 
@@ -370,19 +370,19 @@
     var model = toObservable([0, 1, 2]);
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 4);
 
     model.length = 1;
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 2);
 
     model.addAll(toObservable([3, 4]));
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 4);
 
     model.removeRange(1, 2);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 3);
   });
 
@@ -392,7 +392,7 @@
     var model = toObservable([{'v': 0}, {'v': 1}, {'v': 2}, {'v': 3},
         {'v': 4}]);
     recursivelySetTemplateModel(div, model);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
 
     var nodes = div.nodes.skip(1).toList();
     var vs = model.toList();
@@ -402,14 +402,14 @@
     }
 
     model.length = 3;
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     for (var i = 0; i < 5; i++) {
       expect(nodes[i].text, '$i');
     }
 
     vs[3]['v'] = 33;
     vs[4]['v'] = 44;
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     for (var i = 0; i < 5; i++) {
       expect(nodes[i].text, '$i');
     }
@@ -421,7 +421,7 @@
     var model = toObservable([1, 2, 3, 4, 5]);
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
 
     // Note: the node at index 0 is the <template>.
     var nodes = div.nodes.toList();
@@ -430,7 +430,7 @@
     model.removeAt(0);
     model.removeLast();
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 4, reason: 'list has 3 items');
     expect(identical(div.nodes[1], nodes[2]), true, reason: '2 not removed');
     expect(identical(div.nodes[2], nodes[3]), true, reason: '3 not removed');
@@ -440,7 +440,7 @@
     model[2] = 6;
     model.add(7);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
 
     expect(div.nodes.length, 6, reason: 'list has 5 items');
     expect(nodes.contains(div.nodes[1]), false, reason: '5 is a new node');
@@ -453,7 +453,7 @@
 
     model.insert(2, 8);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
 
     expect(div.nodes.length, 7, reason: 'list has 6 items');
     expect(identical(div.nodes[1], nodes[1]), true);
@@ -476,21 +476,21 @@
     ]);
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 4);
     expect(div.nodes[1].text, '0');
     expect(div.nodes[2].text, '1');
     expect(div.nodes[3].text, '2');
 
     model[1]['value'] = 'One';
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 4);
     expect(div.nodes[1].text, '0');
     expect(div.nodes[2].text, 'One');
     expect(div.nodes[3].text, '2');
 
     model.replaceRange(0, 1, toObservable([{'value': 'Zero'}]));
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 4);
     expect(div.nodes[1].text, 'Zero');
     expect(div.nodes[2].text, 'One');
@@ -505,19 +505,19 @@
     var model = toObservable({'x': 'hi'});
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 2);
     expect(div.nodes.last.value, 'hi');
 
     model['x'] = 'bye';
     expect(div.nodes.last.value, 'hi');
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.last.value, 'bye');
 
     div.nodes.last.value = 'hello';
     dispatchEvent('input', div.nodes.last);
     expect(model['x'], 'hello');
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.last.value, 'hello');
   });
 
@@ -537,7 +537,7 @@
     });
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
 
     var t1 = document.getElementById('t1');
     var instance = t1.nextElementSibling;
@@ -570,7 +570,7 @@
     var model = toObservable({'name': 'Leela'});
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes[1].text, 'Hi Leela');
   });
 
@@ -584,7 +584,7 @@
     var model = toObservable({'name': 'Leela'});
     nodeBind(t).bind('bind', model, '');
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes[1].text, 'Hi Leela');
   });
 
@@ -594,7 +594,7 @@
     var model = toObservable({'name': 'Leela'});
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes[1].text, 'Hi Leela');
   });
 
@@ -614,7 +614,7 @@
     var model = toObservable({'name': 'Fry'});
     recursivelySetTemplateModel(div, model);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(t2.nextNode.text, 'Hi Fry');
   });
 
@@ -631,13 +631,13 @@
     recursivelySetTemplateModel(div, model);
 
     var t = div.nodes.first;
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
 
     expect(div.nodes.length, 2);
     expect(t.nextNode.text, 'Hi Leela');
 
     nodeBind(t).bind('bind', model, 'XZ');
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
 
     expect(div.nodes.length, 2);
     expect(t.nextNode.text, 'Hi Zoidberg');
@@ -667,40 +667,40 @@
     });
 
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal']);
 
     m['contacts'].add(toObservable({'name': 'Alex'}));
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal', 'Hi Alex']);
 
     m['contacts'].replaceRange(0, 2,
         toObservable([{'name': 'Rafael'}, {'name': 'Erik'}]));
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Rafael', 'Hi Erik', 'Hi Neal', 'Hi Alex']);
 
     m['contacts'].removeRange(1, 3);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Rafael', 'Hi Alex']);
 
     m['contacts'].insertAll(1,
         toObservable([{'name': 'Erik'}, {'name': 'Dimitri'}]));
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Rafael', 'Hi Erik', 'Hi Dimitri', 'Hi Alex']);
 
     m['contacts'].replaceRange(0, 1,
         toObservable([{'name': 'Tab'}, {'name': 'Neal'}]));
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Tab', 'Hi Neal', 'Hi Erik', 'Hi Dimitri',
         'Hi Alex']);
 
     m['contacts'] = toObservable([{'name': 'Alex'}]);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Alex']);
 
     m['contacts'].length = 0;
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, []);
   });
 
@@ -718,7 +718,7 @@
     });
     recursivelySetTemplateModel(div, m);
 
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     var t = div.nodes.first;
 
     assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal']);
@@ -736,34 +736,34 @@
     ]);
     recursivelySetTemplateModel(div, m);
 
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal']);
 
     m.add(toObservable({'name': 'Alex'}));
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal', 'Hi Alex']);
 
     m.replaceRange(0, 2, toObservable([{'name': 'Rafael'}, {'name': 'Erik'}]));
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Rafael', 'Hi Erik', 'Hi Neal', 'Hi Alex']);
 
     m.removeRange(1, 3);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Rafael', 'Hi Alex']);
 
     m.insertAll(1, toObservable([{'name': 'Erik'}, {'name': 'Dimitri'}]));
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Rafael', 'Hi Erik', 'Hi Dimitri', 'Hi Alex']);
 
     m.replaceRange(0, 1, toObservable([{'name': 'Tab'}, {'name': 'Neal'}]));
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Tab', 'Hi Neal', 'Hi Erik', 'Hi Dimitri',
         'Hi Alex']);
 
     m.length = 0;
     m.add(toObservable({'name': 'Alex'}));
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Alex']);
   });
 
@@ -781,7 +781,7 @@
     m = toObservable({});
     recursivelySetTemplateModel(div, m);
 
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 1);
   });
 
@@ -796,7 +796,7 @@
       {'name': 'Neal'}
     ]);
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     assertNodesAre(div, ['Hi Raf', 'Hi Arv', 'Hi Neal']);
     var node1 = div.nodes[1];
@@ -804,7 +804,7 @@
     var node3 = div.nodes[3];
 
     m.replaceRange(1, 2, toObservable([{'name': 'Erik'}]));
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Raf', 'Hi Erik', 'Hi Neal']);
     expect(div.nodes[1], node1,
         reason: 'model[0] did not change so the node should not have changed');
@@ -815,7 +815,7 @@
 
     node2 = div.nodes[2];
     m.insert(0, toObservable({'name': 'Alex'}));
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     assertNodesAre(div, ['Hi Alex', 'Hi Raf', 'Hi Erik', 'Hi Neal']);
   });
 
@@ -825,7 +825,7 @@
 
     var model = toObservable({'foo': 'bar'});
     recursivelySetTemplateModel(div, model);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
 
     expect(div.nodes[1].nodes[0].nodes[0].text, 'bar');
   });
@@ -840,7 +840,7 @@
       'a': true
     });
     nodeBind(t).bind('bind', m, '');
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     var instanceInput = t.nextNode;
     expect(instanceInput.checked, true);
@@ -863,7 +863,7 @@
     });
 
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     var i = start;
     expect(div.nodes[i++].text, '1');
@@ -871,11 +871,11 @@
     expect(div.nodes[i++].text, '2');
 
     m['a']['b'] = 11;
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     expect(div.nodes[start].text, '11');
 
     m['a']['c'] = toObservable({'d': 22});
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     expect(div.nodes[start + 2].text, '22');
   }
 
@@ -915,7 +915,7 @@
     });
 
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     var i = start;
     expect(div.nodes[i++].text, '1');
@@ -930,7 +930,7 @@
       'c': {'d': 33}
     });
 
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     expect(div.nodes[start + 3].text, '3');
     expect(div.nodes[start + 5].text, '33');
   }
@@ -973,7 +973,7 @@
     });
 
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     var i = start;
     expect(div.nodes[i++].text, '1');
@@ -991,7 +991,7 @@
     });
 
     i = start + 4;
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     expect(div.nodes[start + 4].text, '3');
     expect(div.nodes[start + 6].text, '31');
     expect(div.nodes[start + 7].text, '32');
@@ -1051,7 +1051,7 @@
     ]);
 
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     var i = 1;
     expect(div.nodes[i++].text, 'Item 1');
@@ -1067,7 +1067,7 @@
     m[0] = toObservable({'name': 'Item 1 changed'});
 
     i = 1;
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     expect(div.nodes[i++].text, 'Item 1 changed');
     expect(div.nodes[i++].tagName, 'TEMPLATE');
     expect(div.nodes[i++].text, 'Item 2');
@@ -1091,7 +1091,7 @@
     });
 
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     var select = div.nodes[0].nextNode;
     expect(select.nodes.length, 2);
@@ -1132,7 +1132,7 @@
     ]);
 
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     var tbody = div.nodes[0].nodes[0];
 
@@ -1169,7 +1169,7 @@
     ]);
 
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     var i = 1;
     var tbody = div.nodes[0].nodes[0];
@@ -1217,9 +1217,9 @@
 
     recursivelySetTemplateModel(div, m);
 
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     m.removeAt(0);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
   });
 
   observeTest('DeepNested', () {
@@ -1240,7 +1240,7 @@
       }
     });
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     expect(div.nodes[1].tagName, 'P');
     expect(div.nodes[1].nodes.first.tagName, 'TEMPLATE');
@@ -1252,7 +1252,7 @@
     var model = 42;
 
     recursivelySetTemplateModel(div, model);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes[1].text, '42');
     expect(div.nodes[0].text, '');
   });
@@ -1262,7 +1262,7 @@
     var model = toObservable([]);
 
     recursivelySetTemplateModel(div, model);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 1);
     expect(div.nodes[0].text, '');
   });
@@ -1281,7 +1281,7 @@
       'b': 2
     });
     recursivelySetTemplateModel(div, model);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
 
     expect(div.nodes[0].text, '');
     expect(div.nodes[1].text, '1');
@@ -1295,17 +1295,17 @@
 
     var model = toObservable({'a': 42});
     recursivelySetTemplateModel(div, model);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes[1].text, '42');
 
     model = null;
     recursivelySetTemplateModel(div, model);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 1);
 
     model = toObservable({'a': 42});
     recursivelySetTemplateModel(div, model);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(div.nodes[1].text, '42');
   });
 
@@ -1328,19 +1328,19 @@
       }
     });
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     expect(div.nodes.length, 5);
     expect(div.nodes[1].text, 'Name: Hermes');
     expect(div.nodes[3].text, 'Wife: LaBarbara');
 
     m['child'] = toObservable({'name': 'Dwight'});
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 6);
     expect(div.nodes[5].text, 'Child: Dwight');
 
     m.remove('wife');
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 5);
     expect(div.nodes[4].text, 'Child: Dwight');
   });
@@ -1359,19 +1359,19 @@
       }
     });
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     expect(div.nodes.length, 5);
     expect(div.nodes[1].text, 'Name: Fry');
     expect(div.nodes[3].text, 'Name: Bender');
 
     m['friend']['friend'] = toObservable({'name': 'Leela'});
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 7);
     expect(div.nodes[5].text, 'Name: Leela');
 
     m['friend'] = toObservable({'name': 'Leela'});
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 5);
     expect(div.nodes[3].text, 'Name: Leela');
   });
@@ -1448,7 +1448,7 @@
       ]
     });
     recursivelySetTemplateModel(div, m);
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
 
     expect(div.nodes.length, 2);
     expect(div.nodes[1].text, '3');
@@ -1456,7 +1456,7 @@
     nodeBind(template)
         ..unbind('bind')
         ..bind('repeat', m, 'a');
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 4);
     expect(div.nodes[1].text, '0');
     expect(div.nodes[2].text, '1');
@@ -1465,7 +1465,7 @@
     nodeBind(template).unbind('repeat');
     nodeBind(template).bind('bind', m, 'a.1.b');
 
-    deliverChanges(m);
+    performMicrotaskCheckpoint();
     expect(div.nodes.length, 2);
     expect(div.nodes[1].text, '4');
   });
@@ -1479,7 +1479,7 @@
         '</template>');
     var model = toObservable([]);
     recursivelySetTemplateModel(div, model);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
 
     expect(div.nodes.length, 3);
 
@@ -1487,7 +1487,7 @@
     document.getElementById('b').id = 'a';
 
     model..add(1)..add(2);
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
 
     expect(div.nodes.length, 7);
     expect(div.nodes[4].text, 'b:1');
@@ -1543,7 +1543,7 @@
           '<template bind="{{}}">Hi {{ name }}</template>');
       var model = toObservable({'name': 'Leela'});
       recursivelySetTemplateModel(root, model);
-      deliverChanges(model);
+      performMicrotaskCheckpoint();
       expect(root.nodes[1].text, 'Hi Leela');
     }
   });
@@ -1594,19 +1594,19 @@
 
     recursivelySetTemplateModel(div, model, syntax);
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(syntax.count, 1);
 
     var inner = model['outer']['inner'];
     model['outer'] = null;
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(syntax.count, 1);
 
     model['outer'] = toObservable({'inner': {'age': 2}});
     syntax.expectedAge = 2;
 
-    deliverChanges(model);
+    performMicrotaskCheckpoint();
     expect(syntax.count, 2);
   });
 
@@ -1695,47 +1695,3 @@
     count++;
   }
 }
-
-/**
- * Verifies that the model is Observable, then calls
- * [performMicrotaskCheckpoint].
- */
-void deliverChanges(model) {
-  expectObservable(model);
-  performMicrotaskCheckpoint();
-}
-
-void expectObservable(model) {
-  if (model is! Observable) {
-    // This is here to eagerly catch a bug in the test; it means the test
-    // forgot a toObservable somewhere.
-    expect(identical(toObservable(model), model), true,
-        reason: 'model type "${model.runtimeType}" should be observable');
-    return;
-  }
-  if (model is ObservableList) {
-    for (var item in model) {
-      expectObservable(item);
-    }
-  } else if (model is ObservableMap) {
-    model.forEach((k, v) {
-      expectObservable(k);
-      expectObservable(v);
-    });
-  }
-}
-
-_deepToSymbol(value) {
-  if (value is Map) {
-    var result = new LinkedHashMap();
-    value.forEach((k, v) {
-      k = k is String ? new Symbol(k) : _deepToSymbol(k);
-      result[k] = _deepToSymbol(v);
-    });
-    return result;
-  }
-  if (value is Iterable) {
-    return value.map(_deepToSymbol).toList();
-  }
-  return value;
-}
diff --git a/pkg/template_binding/test/utils.dart b/pkg/template_binding/test/utils.dart
index 4aee4b9..92d63e4 100644
--- a/pkg/template_binding/test/utils.dart
+++ b/pkg/template_binding/test/utils.dart
@@ -94,3 +94,10 @@
 class NullTreeSanitizer implements NodeTreeSanitizer {
   void sanitizeTree(Node node) {}
 }
+
+unbindAll(node) {
+  nodeBind(node).unbindAll();
+  for (var child = node.firstChild; child != null; child = child.nextNode) {
+    unbindAll(child);
+  }
+}
diff --git a/pkg/unittest/lib/unittest.dart b/pkg/unittest/lib/unittest.dart
index f9643fb..c13aa9d 100644
--- a/pkg/unittest/lib/unittest.dart
+++ b/pkg/unittest/lib/unittest.dart
@@ -305,15 +305,6 @@
 const ERROR = 'error';
 
 /**
- * A map that can be used to communicate state between a test driver
- * or main() function and the tests, particularly when these two
- * are otherwise independent. For example, a test driver that starts
- * an HTTP server and then runs tests that access that server could use
- * this as a way of communicating the server port to the tests.
- */
-Map testState = {};
-
-/**
  * Creates a new test case with the given description and body. The
  * description will include the descriptions of any surrounding group()
  * calls.
diff --git a/pkg/unittest/test/unittest_test_utils.dart b/pkg/unittest/test/unittest_test_utils.dart
index 7d9a922..92555dd 100644
--- a/pkg/unittest/test/unittest_test_utils.dart
+++ b/pkg/unittest/test/unittest_test_utils.dart
@@ -78,18 +78,16 @@
   s.write('l$index D ');
 };
 
-runTestInIsolate() {
-  port.receive((_, sendport) {
-    var testConfig = new TestConfiguration(sendport);
-    unittestConfiguration = testConfig;
-    testFunction(testConfig);
-  });
+runTestInIsolate(sendport) {
+  var testConfig = new TestConfiguration(sendport);
+  unittestConfiguration = testConfig;
+  testFunction(testConfig);
 }
 
 main() {
-  spawnFunction(runTestInIsolate)
-      .call('')
-      .then((String msg) {
-        expect(msg.trim(), equals(expected));
-      });
+  var replyPort = new ReceivePort();
+  Isolate.spawn(runTestInIsolate, replyPort.sendPort);
+  replyPort.first.then((String msg) {
+    expect(msg.trim(), equals(expected));
+  });
 }
diff --git a/pkg/watcher/lib/src/utils.dart b/pkg/watcher/lib/src/utils.dart
index 319835ec..3d00c08 100644
--- a/pkg/watcher/lib/src/utils.dart
+++ b/pkg/watcher/lib/src/utils.dart
@@ -6,9 +6,10 @@
 
 import 'dart:io';
 
-/// Returns `true` if [error] is a [DirectoryException] for a missing directory.
+/// Returns `true` if [error] is a [FileSystemException] for a missing
+/// directory.
 bool isDirectoryNotFoundException(error) {
-  if (error is! DirectoryException) return false;
+  if (error is! FileSystemException) return false;
 
   // See dartbug.com/12461 and tests/standalone/io/directory_error_test.dart.
   var notFoundCode = Platform.operatingSystem == "windows" ? 3 : 2;
diff --git a/pkg/yaml/README.md b/pkg/yaml/README.md
index ad7678f..47a5419 100644
--- a/pkg/yaml/README.md
+++ b/pkg/yaml/README.md
@@ -10,13 +10,13 @@
     }
 
 This library currently doesn't support dumping to YAML. You should use
-`stringify` from `dart:json` instead:
+`JSON.encode` from `dart:convert` instead:
 
-    import 'dart:json' as json;
+    import 'dart:convert';
     import 'package:yaml/yaml.dart';
     main() {
       var doc = loadYaml("YAML: YAML Ain't Markup Language");
-      print(json.stringify(doc));
+      print(JSON.encode(doc));
     }
 
 The source code for this package is at <http://code.google.com/p/dart>.
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index 91702ab..047cd84 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -310,3 +310,27 @@
   _logResolution('# Path: $uri -> $uri');
   return uri.toString();
 }
+
+
+class _PlatformHook {
+  // TODO(whesse):  Replace uses of Platform with uses of internal _Platform
+  //   class, to prepare for removal of (deprecated) Platform class.
+  //   Also merge _Platform and _PlatformHook class into _Platform class
+  //   at that time, since _PlatformHook is the only user of _Platform.
+  int get numberOfProcessors => Platform.numberOfProcessors;
+  String get pathSeparator => Platform.pathSeparator;
+  String get operatingSystem => Platform.operatingSystem;
+  String get localHostname => Platform.localHostname;
+  String get version => Platform.version;
+  Map<String, String> get environment => Platform.environment;
+  Uri get script => new Uri.file(Platform.script);
+  String get executable => Platform.executable;
+  List<String>  get executableArguments => Platform.executableArguments;
+  String get packageRoot => Platform.packageRoot;
+}
+
+
+_getPlatform() => new _PlatformHook();
+
+
+
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 657a457..a3a2f69 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -29,6 +29,7 @@
 const char* DartUtils::kIOLibURL = "dart:io";
 const char* DartUtils::kIOLibPatchURL = "dart:io-patch";
 const char* DartUtils::kUriLibURL = "dart:uri";
+const char* DartUtils::kPlatformLibURL = "dart:platform";
 const char* DartUtils::kHttpScheme = "http:";
 
 const char* DartUtils::kIdFieldName = "_id";
@@ -711,17 +712,29 @@
 
   // Set up package root if specified.
   if (package_root != NULL) {
-    result = NewString(package_root);
-    if (!Dart_IsError(result)) {
-      const int kNumArgs = 1;
-      Dart_Handle dart_args[kNumArgs];
-      dart_args[0] = result;
-      return Dart_Invoke(builtin_lib,
+    Dart_Handle package_root_string = NewString(package_root);
+    if (Dart_IsError(package_root_string)) {
+      return package_root_string;
+    }
+    const int kNumArgs = 1;
+    Dart_Handle dart_args[kNumArgs];
+    dart_args[0] = package_root_string;
+    result = Dart_Invoke(builtin_lib,
                          NewString("_setPackageRoot"),
                          kNumArgs,
                          dart_args);
+    if (Dart_IsError(result)) {
+      return result;
     }
   }
+
+  // Setup the platform library's _platform object.
+  internal_lib = Dart_LookupLibrary(NewString(kPlatformLibURL));
+  DART_CHECK_VALID(internal_lib);
+  Dart_Handle platform =
+      Dart_Invoke(builtin_lib, NewString("_getPlatform"), 0, NULL);
+  result = Dart_SetField(internal_lib, NewString("_platform"), platform);
+  DART_CHECK_VALID(result);
   return result;
 }
 
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 6540454..ca8fa06 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -204,6 +204,7 @@
   static const char* kIOLibURL;
   static const char* kIOLibPatchURL;
   static const char* kUriLibURL;
+  static const char* kPlatformLibURL;
   static const char* kHttpScheme;
 
   static const char* kIdFieldName;
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index 10c53b9..058d638 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -374,7 +374,7 @@
   args[1] = DartUtils::NewString(dir_name);
   args[2] = dart_os_error;
   Dart_ThrowException(Dart_New(
-      DartUtils::GetDartType(DartUtils::kIOLibURL, "DirectoryException"),
+      DartUtils::GetDartType(DartUtils::kIOLibURL, "FileSystemException"),
       Dart_Null(),
       3,
       args));
diff --git a/runtime/bin/eventhandler_patch.dart b/runtime/bin/eventhandler_patch.dart
index 2038a57..a5d8244 100644
--- a/runtime/bin/eventhandler_patch.dart
+++ b/runtime/bin/eventhandler_patch.dart
@@ -6,7 +6,7 @@
 
 patch class _EventHandler {
   /* patch */ static void _sendData(Object sender,
-                                    ReceivePort receivePort,
+                                    RawReceivePort receivePort,
                                     int data)
       native "EventHandler_SendData";
 }
diff --git a/runtime/bin/file_patch.dart b/runtime/bin/file_patch.dart
index 93367f4..96a5d16 100644
--- a/runtime/bin/file_patch.dart
+++ b/runtime/bin/file_patch.dart
@@ -57,11 +57,12 @@
 
   _FileSystemWatcherImpl(this._path, this._events, this._recursive) {
     if (!isSupported) {
-      throw new FileException(
+      throw new FileSystemException(
           "File system watching is not supported on this system",
           _path);
     }
-    _controller = new StreamController(onListen: _listen, onCancel: _cancel);
+    _controller = new StreamController.broadcast(onListen: _listen,
+                                                 onCancel: _cancel);
   }
 
   void _listen() {
@@ -69,13 +70,14 @@
     try {
       socketId = _watchPath(_path, _events, identical(true, _recursive));
     } catch (e) {
-      throw new FileException(
+      throw new FileSystemException(
           "Failed to watch path",
           _path,
           e);
     }
     var socket = new _RawSocket(new _NativeSocket.watch(socketId));
     _subscription = socket.expand((event) {
+      bool stop = false;
       var events = [];
       var pair = {};
       if (event == RawSocketEvent.READ) {
@@ -87,18 +89,22 @@
           }
           return path;
         }
+        void add(event) {
+          if ((event.type & _events) == 0) return;
+          events.add(event);
+        }
         while (socket.available() > 0) {
           for (var event in _readEvents()) {
             if (event == null) continue;
             var path = getPath(event);
             if ((event[0] & FileSystemEvent.CREATE) != 0) {
-              events.add(new FileSystemCreateEvent._(path));
+              add(new FileSystemCreateEvent._(path));
             }
             if ((event[0] & FileSystemEvent.MODIFY) != 0) {
-              events.add(new FileSystemModifyEvent._(path, true));
+              add(new FileSystemModifyEvent._(path, true));
             }
             if ((event[0] & FileSystemEvent._MODIFY_ATTRIBUTES) != 0) {
-              events.add(new FileSystemModifyEvent._(path, false));
+              add(new FileSystemModifyEvent._(path, false));
             }
             if ((event[0] & FileSystemEvent.MOVE) != 0) {
               int link = event[1];
@@ -111,11 +117,15 @@
                   pair[link] = event;
                 }
               } else {
-                events.add(new FileSystemMoveEvent._(path, null));
+                add(new FileSystemMoveEvent._(path, null));
               }
             }
             if ((event[0] & FileSystemEvent.DELETE) != 0) {
-              events.add(new FileSystemDeleteEvent._(path));
+              add(new FileSystemDeleteEvent._(path));
+            }
+            if ((event[0] & FileSystemEvent._DELETE_SELF) != 0) {
+              add(new FileSystemDeleteEvent._(path));
+              stop = true;
             }
           }
         }
@@ -127,17 +137,19 @@
       } else {
         assert(false);
       }
+      if (stop) socket.close();
       return events;
     })
-    .where((event) => (event.type & _events) != 0)
     .listen(_controller.add, onDone: _cancel);
   }
 
   void _cancel() {
-    _unwatchPath();
     if (_subscription != null) {
+      _unwatchPath();
       _subscription.cancel();
+      _subscription = null;
     }
+    _controller.close();
   }
 
   Stream<FileSystemEvent> get stream => _controller.stream;
diff --git a/runtime/bin/file_system_watcher.h b/runtime/bin/file_system_watcher.h
index ea56c11..9434674 100644
--- a/runtime/bin/file_system_watcher.h
+++ b/runtime/bin/file_system_watcher.h
@@ -24,7 +24,8 @@
     kModifyContent = 1 << 1,
     kDelete = 1 << 2,
     kMove = 1 << 3,
-    kModefyAttribute = 1 << 4
+    kModefyAttribute = 1 << 4,
+    kDeleteSelf = 1 << 5
   };
 
   struct Event {
diff --git a/runtime/bin/file_system_watcher_linux.cc b/runtime/bin/file_system_watcher_linux.cc
index c629718..da5dee1 100644
--- a/runtime/bin/file_system_watcher_linux.cc
+++ b/runtime/bin/file_system_watcher_linux.cc
@@ -24,7 +24,7 @@
                                       bool recursive) {
   int fd = TEMP_FAILURE_RETRY(inotify_init1(IN_NONBLOCK | IN_CLOEXEC));
   if (fd < 0) return -1;
-  int list_events = 0;
+  int list_events = IN_DELETE_SELF;
   if (events & kCreate) list_events |= IN_CREATE;
   if (events & kModifyContent) list_events |= IN_MODIFY | IN_ATTRIB;
   if (events & kDelete) list_events |= IN_DELETE;
@@ -56,7 +56,7 @@
   if (bytes < 0) {
     return DartUtils::NewDartOSError();
   }
-  const intptr_t kMaxCount = kBufferSize / kEventSize + 1;
+  const intptr_t kMaxCount = bytes / kEventSize;
   Dart_Handle events = Dart_NewList(kMaxCount);
   intptr_t offset = 0;
   intptr_t i = 0;
@@ -70,6 +70,7 @@
     if (e->mask & IN_CREATE) mask |= kCreate;
     if (e->mask & IN_MOVE) mask |= kMove;
     if (e->mask & IN_DELETE) mask |= kDelete;
+    if (e->mask & IN_DELETE_SELF) mask |= kDeleteSelf;
     Dart_ListSetAt(event, 0, Dart_NewInteger(mask));
     Dart_ListSetAt(event, 1, Dart_NewInteger(e->cookie));
     if (e->len > 0) {
diff --git a/runtime/bin/file_system_watcher_macos.cc b/runtime/bin/file_system_watcher_macos.cc
index de0be2e..4aed2e3 100644
--- a/runtime/bin/file_system_watcher_macos.cc
+++ b/runtime/bin/file_system_watcher_macos.cc
@@ -136,7 +136,9 @@
     if (watcher == NULL) {
       watcher_monitor->Enter();
       watcher = new FSEventsWatcher();
-      watcher_monitor->Wait(Monitor::kNoTimeout);
+      while (watcher->run_loop_ == NULL) {
+        watcher_monitor->Wait(Monitor::kNoTimeout);
+      }
       watcher_monitor->Exit();
     }
     watcher->users_++;
@@ -199,7 +201,9 @@
     Node* node = reinterpret_cast<Node*>(client);
     for (size_t i = 0; i < num_events; i++) {
       char *path = reinterpret_cast<char**>(event_paths)[i];
-      path += node->base_path_length() + 1;
+      path += node->base_path_length();
+      // If path is longer the base, skip next character ('/').
+      if (path[0] != '\0') path += 1;
       if (!node->recursive() && strstr(path, "/") != NULL) continue;
       FSEvent event;
       event.data.flags = event_flags[i];
@@ -259,6 +263,7 @@
     if (bytes < 0) {
       return DartUtils::NewDartOSError();
     }
+    size_t path_len = strlen(e.data.path);
     Dart_Handle event = Dart_NewList(3);
     int flags = e.data.flags;
     int mask = 0;
@@ -266,11 +271,18 @@
     if (flags & kFSEventStreamEventFlagItemRenamed) mask |= kMove;
     if (flags & kFSEventStreamEventFlagItemXattrMod) mask |= kModefyAttribute;
     if (flags & kFSEventStreamEventFlagItemCreated) mask |= kCreate;
-    if (flags & kFSEventStreamEventFlagItemRemoved) mask |= kDelete;
+    if (flags & kFSEventStreamEventFlagItemRemoved) {
+      if (path_len == 0) {
+        // The removed path is the path being watched.
+        mask |= kDeleteSelf;
+      } else {
+        mask |= kDelete;
+      }
+    }
     Dart_ListSetAt(event, 0, Dart_NewInteger(mask));
     Dart_ListSetAt(event, 1, Dart_NewInteger(1));
     Dart_ListSetAt(event, 2, Dart_NewStringFromUTF8(
-        reinterpret_cast<uint8_t*>(e.data.path), strlen(e.data.path)));
+        reinterpret_cast<uint8_t*>(e.data.path), path_len));
     Dart_ListSetAt(events, i, event);
   }
   return events;
diff --git a/runtime/bin/io_service_patch.dart b/runtime/bin/io_service_patch.dart
index c6a7035..85f5124 100644
--- a/runtime/bin/io_service_patch.dart
+++ b/runtime/bin/io_service_patch.dart
@@ -6,7 +6,7 @@
   // Lazy initialize service ports, 32 per isolate.
   static const int _SERVICE_PORT_COUNT = 32;
   static List<SendPort> _servicePort = new List(_SERVICE_PORT_COUNT);
-  static ReceivePort _receivePort;
+  static RawReceivePort _receivePort;
   static SendPort _replyToPort;
   static Map<int, Completer> _messageMap = {};
   static int _id = 0;
@@ -29,9 +29,9 @@
       _servicePort[index] = _newServicePort();
     }
     if (_receivePort == null) {
-      _receivePort = new ReceivePort();
-      _replyToPort = _receivePort.toSendPort();
-      _receivePort.receive((data, _) {
+      _receivePort = new RawReceivePort();
+      _replyToPort = _receivePort.sendPort;
+      _receivePort.handler = (data) {
         assert(data is List && data.length == 2);
         _messageMap.remove(data[0]).complete(data[1]);
         if (_messageMap.length == 0) {
@@ -39,7 +39,7 @@
           _receivePort.close();
           _receivePort = null;
         }
-      });
+      };
     }
   }
 
diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h
index df76864..8a977be 100644
--- a/runtime/bin/isolate_data.h
+++ b/runtime/bin/isolate_data.h
@@ -20,14 +20,13 @@
 // when the isolate shuts down.
 class IsolateData {
  public:
-  IsolateData()
-      : object_array_class(NULL),
-        growable_object_array_class(NULL), immutable_array_class(NULL) {
+  explicit IsolateData(const char* url) : script_url(strdup(url)) {
+  }
+  ~IsolateData() {
+    free(script_url);
   }
 
-  Dart_PersistentHandle object_array_class;
-  Dart_PersistentHandle growable_object_array_class;
-  Dart_PersistentHandle immutable_array_class;
+  char* script_url;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(IsolateData);
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 76c0062..b6e8ee9 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -460,7 +460,11 @@
   result = DartUtils::PrepareForScriptLoading(package_root, builtin_lib);
   CHECK_RESULT(result);
 
-  Dart_Handle library = DartUtils::LoadScript(script_uri, builtin_lib);
+  IsolateData* isolate_data = reinterpret_cast<IsolateData*>(data);
+  ASSERT(isolate_data != NULL);
+  ASSERT(isolate_data->script_url != NULL);
+  Dart_Handle library = DartUtils::LoadScript(isolate_data->script_url,
+                                              builtin_lib);
   CHECK_RESULT(library);
   if (!Dart_IsLibrary(library)) {
     char errbuf[256];
@@ -514,9 +518,22 @@
                                           const char* main,
                                           void* data, char** error) {
   bool is_compile_error = false;
+  if (script_uri == NULL) {
+    if (data == NULL) {
+      *error = strdup("Invalid 'callback_data' - Unable to spawn new isolate");
+      return NULL;
+    }
+    IsolateData* parent_isolate_data = reinterpret_cast<IsolateData*>(data);
+    script_uri = parent_isolate_data->script_url;
+    if (script_uri == NULL) {
+      *error = strdup("Invalid 'callback_data' - Unable to spawn new isolate");
+      return NULL;
+    }
+  }
+  IsolateData* isolate_data = new IsolateData(script_uri);
   return CreateIsolateAndSetupHelper(script_uri,
                                      main,
-                                     new IsolateData(),
+                                     isolate_data,
                                      error,
                                      &is_compile_error);
 }
@@ -781,9 +798,10 @@
   char* error = NULL;
   bool is_compile_error = false;
   char* isolate_name = BuildIsolateName(script_name, "main");
+  IsolateData* isolate_data = new IsolateData(script_name);
   Dart_Isolate isolate = CreateIsolateAndSetupHelper(script_name,
                                                      "main",
-                                                     new IsolateData(),
+                                                     isolate_data,
                                                      &error,
                                                      &is_compile_error);
   if (isolate == NULL) {
@@ -863,16 +881,32 @@
       }
     } else {
       // Lookup and invoke the top level main function.
-      Dart_Handle main_args[1];
+      // The top-level function may accept up to two arguments:
+      //   main(List<String> args, var message).
+      // However most commonly it either accepts one (the args list) or
+      // none.
+      // If the message is optional, main(args, [message]), it is invoked with
+      // one argument only.
+      Dart_Handle main_args[2];
       main_args[0] = CreateRuntimeOptions(&dart_options);
+      main_args[1] = Dart_Null();
+      // First try with 1 argument.
       result = Dart_Invoke(library, DartUtils::NewString("main"), 1, main_args);
       // TODO(iposva): Return a special error type for mismatched argument
       // counts from Dart_Invoke to avoid the string comparison.
       const char* expected_error = "Dart_Invoke: wrong argument count for "
-          "function 'main': 1 passed, 0 expected.";
+          "function 'main': ";
+      intptr_t length = strlen(expected_error);
       if (Dart_IsError(result) &&
-          strcmp(expected_error, Dart_GetError(result)) == 0) {
-        result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
+          strncmp(expected_error, Dart_GetError(result), length) == 0) {
+        // Try with two arguments.
+        result =
+            Dart_Invoke(library, DartUtils::NewString("main"), 2, main_args);
+        if (Dart_IsError(result) &&
+            strncmp(expected_error, Dart_GetError(result), length) == 0) {
+          // Finally try with 0 arguments.
+          result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
+        }
       }
       if (Dart_IsError(result)) {
         return DartErrorExit(result);
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index a0de4fd..458da76 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -206,7 +206,7 @@
   // Handlers and receive port for socket events from the event handler.
   int eventMask = 0;
   List eventHandlers;
-  ReceivePort eventPort;
+  RawReceivePort eventPort;
 
   // Indicates if native interrupts can be activated.
   bool canActivateEvents = true;
@@ -588,8 +588,7 @@
 
   void connectToEventHandler() {
     if (eventPort == null) {
-      eventPort = new ReceivePort();
-      eventPort.receive ((var message, _) => multiplex(message));
+      eventPort = new RawReceivePort(multiplex);
     }
   }
 
diff --git a/runtime/bin/stdio_patch.dart b/runtime/bin/stdio_patch.dart
index 482e8d7..eb9aa68 100644
--- a/runtime/bin/stdio_patch.dart
+++ b/runtime/bin/stdio_patch.dart
@@ -12,7 +12,7 @@
       case _STDIO_HANDLE_TYPE_FILE:
         return new Stdin._(new _FileStream.forStdin());
       default:
-        throw new FileException("Unsupported stdin type");
+        throw new FileSystemException("Unsupported stdin type");
     }
   }
 
@@ -26,14 +26,14 @@
       case _STDIO_HANDLE_TYPE_FILE:
         return new _StdSink(new IOSink(new _FileStreamConsumer.fromStdio(fd)));
       default:
-        throw new FileException("Unsupported stdin type");
+        throw new FileSystemException("Unsupported stdin type");
     }
   }
 
   static int _socketType(nativeSocket) {
     var result = _getSocketType(nativeSocket);
     if (result is OSError) {
-      throw new FileException("Error retreiving socket type", result);
+      throw new FileSystemException("Error retreiving socket type", result);
     }
     return result;
   }
diff --git a/runtime/bin/vmservice/running_isolate.dart b/runtime/bin/vmservice/running_isolate.dart
index 2d4af13..13b358a 100644
--- a/runtime/bin/vmservice/running_isolate.dart
+++ b/runtime/bin/vmservice/running_isolate.dart
@@ -12,16 +12,16 @@
 
   Future sendMessage(List request) {
     final completer = new Completer.sync();
-    final receivePort = new ReceivePort();
+    final receivePort = new RawReceivePort();
     sendServiceMessage(sendPort, receivePort, request);
-    receivePort.receive((value, ignoreReplyTo) {
+    receivePort.handler = (value) {
       receivePort.close();
       if (value is Exception) {
         completer.completeError(value);
       } else {
         completer.complete(value);
       }
-    });
+    };
     return completer.future;
   }
 
diff --git a/runtime/bin/vmservice/vmservice.dart b/runtime/bin/vmservice/vmservice.dart
index 681eff1..83c2168 100644
--- a/runtime/bin/vmservice/vmservice.dart
+++ b/runtime/bin/vmservice/vmservice.dart
@@ -31,14 +31,14 @@
     }
   }
 
-  void messageHandler(message, SendPort replyTo) {
+  void messageHandler(message) {
     if (message is List && message.length == 3) {
       controlMessageHandler(message[0], message[1], message[2]);
     }
   }
 
   VMService._internal() {
-    port.receive(messageHandler);
+    port.listen(messageHandler);
   }
 
   factory VMService() {
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index 320d3da..7da20cc 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -84,8 +84,10 @@
 bool VmService::_Start(intptr_t server_port) {
   ASSERT(isolate_ == NULL);
   char* error = NULL;
-  isolate_ = Dart_CreateIsolate("vmservice:", "main", snapshot_buffer,
-                                new IsolateData(),
+  const char* script_uri = "vmservice:";
+  IsolateData* isolate_data = new IsolateData(script_uri);
+  isolate_ = Dart_CreateIsolate(script_uri, "main", snapshot_buffer,
+                                isolate_data,
                                 &error);
   if (isolate_ == NULL) {
     error_msg_ = error;
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 5824572..3cc6fb5 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -613,16 +613,21 @@
  * caller of this function (the vm) will make sure that the buffer is
  * freed.
  *
- * \param script_uri The uri of the script to load.  This uri has been
- *   canonicalized by the library tag handler from the parent isolate.
+ * \param script_uri The uri of the script to load.
+ *   This uri is non NULL if the isolate is being created using the
+ *   spawnUri isolate API. This uri has been canonicalized by the
+ *   library tag handler from the parent isolate.
  *   The callback is responsible for loading this script by a call to
  *   Dart_LoadScript or Dart_LoadScriptFromSnapshot.
+ *   This uri will be NULL if the isolate is being created using the
+ *   spawnFunction isolate API.
+ *   The callback is responsible for loading the script used in the
+ *   parent isolate by a call to Dart_LoadScript or
+ *   Dart_LoadScriptFromSnapshot.
  * \param main The name of the main entry point this isolate will
  *   eventually run.  This is provided for advisory purposes only to
  *   improve debugging messages.  The main function is not invoked by
  *   this function.
- * \param unhandled_exc The name of the function to this isolate will
- *   call when an unhandled exception is encountered.
  * \param callback_data The callback data which was passed to the
  *   parent isolate when it was created by calling Dart_CreateIsolate().
  * \param error A structure into which the embedder can place a
diff --git a/runtime/include/dart_mirrors_api.h b/runtime/include/dart_mirrors_api.h
index 3a4c9ce..be50e49 100644
--- a/runtime/include/dart_mirrors_api.h
+++ b/runtime/include/dart_mirrors_api.h
@@ -122,6 +122,14 @@
 DART_EXPORT Dart_Handle Dart_LibraryName(Dart_Handle library);
 
 /**
+ * Returns in \library_id the library id of the given \library.
+ *
+ * \return A valid handle if no error occurs during the operation.
+ */
+DART_EXPORT Dart_Handle Dart_LibraryId(Dart_Handle library,
+                                       intptr_t* library_id);
+
+/**
  * Returns a list of the names of all classes and interfaces declared
  * in a library.
  *
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 9cfcddf..ab7f258 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -53,7 +53,7 @@
     Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
     ASSERT(!isolate_lib.IsNull());
     const String& class_name =
-        String::Handle(isolate_lib.PrivateName(Symbols::_ReceivePortImpl()));
+        String::Handle(isolate_lib.PrivateName(Symbols::_RawReceivePortImpl()));
     const String& function_name =
         String::Handle(isolate_lib.PrivateName(Symbols::_get_or_create()));
     func = Resolver::ResolveStatic(isolate_lib,
@@ -76,7 +76,7 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(ReceivePortImpl_factory, 1) {
+DEFINE_NATIVE_ENTRY(RawReceivePortImpl_factory, 1) {
   ASSERT(AbstractTypeArguments::CheckedHandle(
       arguments->NativeArgAt(0)).IsNull());
   intptr_t port_id =
@@ -89,7 +89,7 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(ReceivePortImpl_closeInternal, 1) {
+DEFINE_NATIVE_ENTRY(RawReceivePortImpl_closeInternal, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, id, arguments->NativeArgAt(0));
   PortMap::ClosePort(id.Value());
   return Object::null();
@@ -215,7 +215,7 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 2) {
+DEFINE_NATIVE_ENTRY(Isolate_spawnFunction, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
   bool throw_exception = false;
   Function& func = Function::Handle();
@@ -230,27 +230,7 @@
   }
   if (throw_exception) {
     const String& msg = String::Handle(String::New(
-        "spawnFunction expects to be passed a closure to a top-level static "
-        "function"));
-    Exceptions::ThrowArgumentError(msg);
-  }
-
-  GET_NATIVE_ARGUMENT(Instance, callback, arguments->NativeArgAt(1));
-  Function& callback_func = Function::Handle();
-  if (callback.IsClosure()) {
-    callback_func = Closure::function(callback);
-    const Class& cls = Class::Handle(callback_func.Owner());
-    if (!callback_func.IsClosureFunction() || !callback_func.is_static() ||
-        !cls.IsTopLevel()) {
-      throw_exception = true;
-    }
-  } else if (!callback.IsNull()) {
-    throw_exception = true;
-  }
-  if (throw_exception) {
-    const String& msg = String::Handle(String::New(
-        "spawnFunction expects to be passed either a unhandled exception "
-        "callback to a top-level static function, or null"));
+        "Isolate.spawn expects to be passed a top-level function"));
     Exceptions::ThrowArgumentError(msg);
   }
 
@@ -258,17 +238,13 @@
   Context& ctx = Context::Handle();
   ctx = Closure::context(closure);
   ASSERT(ctx.num_variables() == 0);
-  if (!callback.IsNull()) {
-    ctx = Closure::context(callback);
-    ASSERT(ctx.num_variables() == 0);
-  }
 #endif
 
-  return Spawn(arguments, new IsolateSpawnState(func, callback_func));
+  return Spawn(arguments, new IsolateSpawnState(func));
 }
 
 
-DEFINE_NATIVE_ENTRY(isolate_spawnUri, 1) {
+DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(0));
 
   // Canonicalize the uri with respect to the current isolate.
@@ -286,7 +262,7 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) {
+DEFINE_NATIVE_ENTRY(Isolate_mainPort, 0) {
   const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port()));
   if (port.IsError()) {
     Exceptions::PropagateError(Error::Cast(port));
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index a2713d1..2a08763 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -2,125 +2,109 @@
 // for 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 _CloseToken {
-  /// This token is sent from [IsolateSink]s to [IsolateStream]s to ask them to
-  /// close themselves.
-  const _CloseToken();
-}
-
-patch bool _isCloseToken(var object) {
-  // TODO(floitsch): can we compare against const _CloseToken()?
-  return object is _CloseToken;
-}
-
-patch class MessageBox {
-  /* patch */ MessageBox.oneShot() : this._oneShot(new ReceivePort());
-  MessageBox._oneShot(ReceivePort receivePort)
-      : stream = new IsolateStream._fromOriginalReceivePortOneShot(receivePort),
-        sink = new _IsolateSink._fromPort(receivePort.toSendPort());
-
-  /* patch */ MessageBox() : this._(new ReceivePort());
-  MessageBox._(ReceivePort receivePort)
-      : stream = new IsolateStream._fromOriginalReceivePort(receivePort),
-        sink = new _IsolateSink._fromPort(receivePort.toSendPort());
-}
-
-class _IsolateSink implements IsolateSink {
-  bool _isClosed = false;
-  final SendPort _port;
-  _IsolateSink._fromPort(this._port);
-
-  void add(dynamic message) {
-    _port.send(message);
-  }
-
-  void addError(Object errorEvent) {
-    throw new UnimplementedError("addError on isolate streams");
-  }
-
-  void close() {
-    if (_isClosed) return;
-    add(const _CloseToken());
-    _isClosed = true;
-  }
-
-  bool operator==(var other) {
-    return other is IsolateSink && _port == other._port;
-  }
-
-  int get hashCode => _port.hashCode + 499;
-}
-
-patch IsolateSink streamSpawnFunction(
-    void topLevelFunction(),
-    [bool unhandledExceptionCallback(IsolateUnhandledException e)]) {
-  SendPort sendPort = spawnFunction(topLevelFunction,
-                                    unhandledExceptionCallback);
-  return new _IsolateSink._fromPort(sendPort);
-}
-
 patch class ReceivePort {
-  /* patch */ factory ReceivePort() {
-    return new _ReceivePortImpl();
+  /* patch */ factory ReceivePort() = _ReceivePortImpl;
+
+  /* patch */ factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) =
+      _ReceivePortImpl.fromRawReceivePort;
+}
+
+patch class RawReceivePort {
+  /**
+   * Opens a long-lived port for receiving messages.
+   *
+   * A [RawReceivePort] is low level and does not work with [Zone]s. It
+   * can not be paused. The data-handler must be set before the first
+   * event is received.
+   */
+  /* patch */ factory RawReceivePort([void handler(event)]) {
+    _RawReceivePortImpl result = new _RawReceivePortImpl();
+    result.handler = handler;
+    return result;
   }
 }
 
-class _ReceivePortImpl implements ReceivePort {
-  factory _ReceivePortImpl() native "ReceivePortImpl_factory";
+class _ReceivePortImpl extends Stream implements ReceivePort {
+  _ReceivePortImpl() : this.fromRawReceivePort(new RawReceivePort());
 
-  receive(void onMessage(var message, SendPort replyTo)) {
-    _onMessage = onMessage;
+  _ReceivePortImpl.fromRawReceivePort(this._rawPort) {
+    _controller = new StreamController(onCancel: close, sync: true);
+    _rawPort.handler = _controller.add;
   }
 
+  SendPort get sendPort {
+    return _rawPort.sendPort;
+  }
+
+  StreamSubscription listen(void onData(var message),
+                            { Function onError,
+                              void onDone(),
+                              bool cancelOnError }) {
+    return _controller.stream.listen(onData,
+                                     onError: onError,
+                                     onDone: onDone,
+                                     cancelOnError: cancelOnError);
+  }
+
+  close() {
+    _rawPort.close();
+    _controller.close();
+  }
+
+  final RawReceivePort _rawPort;
+  StreamController _controller;
+}
+
+class _RawReceivePortImpl implements RawReceivePort {
+  factory _RawReceivePortImpl() native "RawReceivePortImpl_factory";
+
   close() {
     _portMap.remove(_id);
     _closeInternal(_id);
   }
 
-  SendPort toSendPort() {
+  SendPort get sendPort {
     return new _SendPortImpl(_id);
   }
 
   /**** Internal implementation details ****/
-  // Called from the VM to create a new ReceivePort instance.
-  static _ReceivePortImpl _get_or_create(int id) {
-    if (_portMap != null) {
-      _ReceivePortImpl port = _portMap[id];
-      if (port != null) {
-        return port;
-      }
+  // Called from the VM to create a new RawReceivePort instance.
+  static _RawReceivePortImpl _get_or_create(int id) {
+    _RawReceivePortImpl port = _portMap[id];
+    if (port != null) {
+      return port;
     }
-    return new _ReceivePortImpl._internal(id);
+    return new _RawReceivePortImpl._internal(id);
   }
 
-  _ReceivePortImpl._internal(int id) : _id = id {
-    if (_portMap == null) {
-      _portMap = new Map();
-    }
+  _RawReceivePortImpl._internal(int id) : _id = id {
     _portMap[id] = this;
   }
 
-  // Called from the VM to retrieve the ReceivePort for a message.
-  static _ReceivePortImpl _lookupReceivePort(int id) {
-    assert(_portMap != null);
+  // Called from the VM to retrieve the RawReceivePort for a message.
+  static _RawReceivePortImpl _lookupReceivePort(int id) {
     return _portMap[id];
   }
 
   // Called from the VM to dispatch to the handler.
-  static void _handleMessage(_ReceivePortImpl port, int replyId, var message) {
+  static void _handleMessage(
+      _RawReceivePortImpl port, int replyId, var message) {
     assert(port != null);
-    SendPort replyTo = (replyId == 0) ? null : new _SendPortImpl(replyId);
-    (port._onMessage)(message, replyTo);
+    port._handler(message);
   }
 
   // Call into the VM to close the VM maintained mappings.
-  static _closeInternal(int id) native "ReceivePortImpl_closeInternal";
+  static _closeInternal(int id) native "RawReceivePortImpl_closeInternal";
+
+  void set handler(Function newHandler) {
+    this._handler = newHandler;
+  }
 
   final int _id;
-  var _onMessage;
+  Function _handler;
 
-  // id to ReceivePort mapping.
-  static Map _portMap;
+  // id to RawReceivePort mapping.
+  static final Map _portMap = new HashMap();
 }
 
 
@@ -135,27 +119,19 @@
     _sendInternal(_id, replyId, message);
   }
 
-  Future call(var message) {
-    final completer = new Completer.sync();
-    final port = new _ReceivePortImpl();
-    send(message, port.toSendPort());
-    port.receive((value, ignoreReplyTo) {
-      port.close();
-      if (value is Exception) {
-        completer.completeError(value);
-      } else {
-        completer.complete(value);
-      }
-    });
-    return completer.future;
-  }
-
   bool operator==(var other) {
     return (other is _SendPortImpl) && _id == other._id;
   }
 
   int get hashCode {
-    return _id;
+    const int MASK = 0x3FFFFFFF;
+    int hash = _id;
+    hash = (hash + ((hash & (MASK >> 10)) << 10)) & MASK;
+    hash ^= (hash >> 6);
+    hash = (hash + ((hash & (MASK >> 3)) << 3)) & MASK;
+    hash ^= (hash >> 11);
+    hash = (hash + ((hash & (MASK >> 15)) << 15)) & MASK;
+    return hash;
   }
 
   /*--- private implementation ---*/
@@ -175,21 +151,102 @@
   final int _id;
 }
 
-_getPortInternal() native "isolate_getPortInternal";
+typedef _MainFunction();
+typedef _MainFunctionArgs(args);
+typedef _MainFunctionArgsMessage(args, message);
 
-ReceivePort _portInternal;
+/**
+ * Takes the real entry point as argument and invokes it with the initial
+ * message.
+ *
+ * The initial startup message is received through the control port.
+ */
+void _startIsolate(Function entryPoint, bool isSpawnUri) {
+  // This port keeps the isolate alive until the initial startup message has
+  // been received.
+  var keepAlivePort = new RawReceivePort();
 
-patch class _Isolate {
-  /* patch */ static ReceivePort get port {
-    if (_portInternal == null) {
-      _portInternal = _getPortInternal();
-    }
-    return _portInternal;
+  ignoreHandler(message) {
+    // Messages on the current Isolate's control port are dropped after the
+    // initial startup message has been received.
   }
 
-  /* patch */ static SendPort spawnFunction(void topLevelFunction(),
-      [bool unhandledExceptionCallback(IsolateUnhandledException e)])
-      native "isolate_spawnFunction";
+  isolateStartHandler(message) {
+    // We received the initial startup message. Ignore all further messages and
+    // close the port which kept this isolate alive.
+    Isolate._self.handler = ignoreHandler;
+    keepAlivePort.close();
 
-  /* patch */ static SendPort spawnUri(String uri) native "isolate_spawnUri";
+    SendPort replyTo = message[0];
+    // TODO(floitsch): don't send ok-message if we can't find the entry point.
+    replyTo.send("started");
+    if (isSpawnUri) {
+      assert(message.length == 3);
+      List<String> args = message[1];
+      var isolateMessage = message[2];
+      if (entryPoint is _MainFunctionArgsMessage) {
+        entryPoint(args, isolateMessage);
+      } else if (entryPoint is _MainFunctionArgs) {
+        entryPoint(args);
+      } else {
+        entryPoint();
+      }
+    } else {
+      assert(message.length == 2);
+      var entryMessage = message[1];
+      entryPoint(entryMessage);
+    }
+  }
+
+  Isolate._self.handler = isolateStartHandler;
+}
+
+patch class Isolate {
+  /* patch */ static Future<Isolate> spawn(
+      void entryPoint(message), var message) {
+    Completer completer = new Completer<Isolate>.sync();
+    try {
+      // The VM will invoke [_startIsolate] with entryPoint as argument.
+      SendPort controlPort = _spawnFunction(entryPoint);
+      RawReceivePort readyPort = new RawReceivePort();
+      controlPort.send([readyPort.sendPort, message]);
+      readyPort.handler = (readyMessage) {
+        assert(readyMessage == 'started');
+        readyPort.close();
+        completer.complete(new Isolate._fromControlPort(controlPort));
+      };
+    } catch(e, st) {
+      // TODO(floitsch): we want errors to go into the returned future.
+      rethrow;
+    };
+    return completer.future;
+  }
+
+  /* patch */ static Future<Isolate> spawnUri(
+      Uri uri, List<String> args, var message) {
+    Completer completer = new Completer<Isolate>.sync();
+    try {
+      // The VM will invoke [_startIsolate] and not `main`.
+      SendPort controlPort = _spawnUri(uri.toString());
+      RawReceivePort readyPort = new RawReceivePort();
+      controlPort.send([readyPort.sendPort, args, message]);
+      readyPort.handler = (readyMessage) {
+        assert(readyMessage == 'started');
+        readyPort.close();
+        completer.complete(new Isolate._fromControlPort(controlPort));
+      };
+    } catch(e, st) {
+      // TODO(floitsch): we want errors to go into the returned future.
+      rethrow;
+    };
+    return completer.future;
+  }
+
+  static final RawReceivePort _self = _mainPort;
+  static RawReceivePort get _mainPort native "Isolate_mainPort";
+
+  static SendPort _spawnFunction(Function topLevelFunction)
+      native "Isolate_spawnFunction";
+
+  static SendPort _spawnUri(String uri) native "Isolate_spawnUri";
 }
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 2522480..28ff352 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -352,7 +352,7 @@
   // We do not set the names of anonymous mixin applications because the mirrors
   // use a different naming convention than the VM (lib.S with lib.M and S&M
   // respectively).
-  if (!cls.IsMixinApplication() || cls.is_mixin_typedef()) {
+  if (!cls.IsAnonymousMixinApplication()) {
     args.SetAt(2, String::Handle(cls.Name()));
   }
   args.SetAt(3, is_generic);
@@ -1211,7 +1211,8 @@
       // We filter out function signature classes and dynamic.
       // TODO(12478): Should not need to filter out dynamic.
       if (!klass.IsCanonicalSignatureClass() &&
-          !klass.IsDynamicClass()) {
+          !klass.IsDynamicClass() &&
+          !klass.IsAnonymousMixinApplication()) {
         type = klass.DeclarationType();
         member_mirror = CreateClassMirror(klass,
                                           type,
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 1e79507..5bb24ac 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -574,14 +574,11 @@
   ClassMirror get mixin {
     if (_mixin == null) {
       if (_isMixinTypedef) {
-        Type mixinType = isOriginalDeclaration
-            ? _nativeMixin(_trueSuperclass._reflectedType)
-            : _nativeMixinInstantiated(_trueSuperclass._reflectedType, _instantiator);
+        Type mixinType = _nativeMixinInstantiated(_trueSuperclass._reflectedType,
+                                                  _instantiator);
         _mixin = reflectType(mixinType);
       } else {
-        Type mixinType = isOriginalDeclaration
-            ? _nativeMixin(_reflectedType)
-            : _nativeMixinInstantiated(_reflectedType, _instantiator);
+        Type mixinType = _nativeMixinInstantiated(_reflectedType, _instantiator);
         if (mixinType == null) {
           // The reflectee is not a mixin application.
           _mixin = this;
@@ -593,6 +590,17 @@
     return _mixin;
   }
 
+  Map<Symbol, DeclarationMirror> _declarations;
+  Map<Symbol, DeclarationMirror> get declarations {
+    if (_declarations != null) return _declarations;
+    var decls = new Map<Symbol, DeclarationMirror>();
+    decls.addAll(members);
+    decls.addAll(constructors);
+    typeVariables.forEach((tv) => decls[tv.simpleName] = tv);
+    return _declarations =
+        new _UnmodifiableMapView<Symbol, DeclarationMirror>(decls);
+  }
+
   Map<Symbol, Mirror> _members;
   Map<Symbol, Mirror> get members {
     if (_members == null) {
@@ -913,6 +921,7 @@
   }
 
   bool get isPrivate => false;
+  bool get isStatic => false;
 
   final bool isTopLevel = false;
 
@@ -1100,6 +1109,13 @@
 
   final Uri uri;
 
+  Map<Symbol, DeclarationMirror> _declarations;
+  Map<Symbol, DeclarationMirror> get declarations {
+    if (_declarations != null) return _declarations;
+    return _declarations =
+        new _UnmodifiableMapView<Symbol, DeclarationMirror>(members);
+  }
+
   Map<Symbol, Mirror> _members;
   Map<Symbol, Mirror> get members {
     if (_members == null) {
@@ -1265,7 +1281,7 @@
       if (!isConstructor) {
         _constructorName = _s('');
       } else {
-        var parts = _n(simpleName).split('.');
+        var parts = MirrorSystem.getName(simpleName).split('.');
         if (parts.length > 2) {
           throw new MirrorException(
               'Internal error in MethodMirror.constructorName: '
@@ -1415,9 +1431,14 @@
   final DeclarationMirror owner = null;
   final Symbol simpleName;
   final bool isTopLevel = true;
-  // Fixed length 0, therefore immutable.
   final List<InstanceMirror> metadata = emptyList;
 
+  List<TypeVariableMirror> get typeVariables => emptyList;
+  List<TypeMirror> get typeArguments => emptyList;
+
+  bool get isOriginalDeclaration => true;
+  TypeMirror get originalDeclaration => this;
+
   SourceLocation get location {
     throw new UnimplementedError('TypeMirror.location is not implemented');
   }
diff --git a/runtime/lib/platform_patch.dart b/runtime/lib/platform_patch.dart
new file mode 100644
index 0000000..80dfef9
--- /dev/null
+++ b/runtime/lib/platform_patch.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+patch int get numberOfProcessors => _platform.numberOfProcessors;
+
+patch String get pathSeparator => _platform.pathSeparator;
+
+patch String get operatingSystem => _platform.operatingSystem;
+
+patch String get localHostname => _platform.localHostname;
+
+patch String get version => _platform.version;
+
+patch Map<String, String> get environment => _platform.environment;
+
+patch String get executable => _platform.executable;
+
+patch Uri get script => _platform.script;
+
+patch List<String> get executableArguments => _platform.executableArguments;
+
+patch String get packageRoot => _platform.packageRoot;
+
+class _Platform {
+  int get numberOfProcessors;
+  String get pathSeparator;
+  String get operatingSystem;
+  String get localHostname;
+  String get version;
+  Map get environment;
+  Uri get script;
+  String get executable;
+  List<String>  get executableArguments;
+  String get packageRoot;
+}
+
+// A non-default _Platform, with real values, is stored here by the embedder.
+_Platform _platform = new _DefaultPlatform();
+
+class _DefaultPlatform implements _Platform {
+  int get numberOfProcessors {
+    return null;
+  }
+
+  String get pathSeparator {
+    return null;
+  }
+
+  String get operatingSystem {
+    return null;
+  }
+
+  String get localHostname {
+    return null;
+  }
+
+  String get version {
+    return null;
+  }
+
+  Map get environment {
+    return null;
+  }
+
+  Uri get script {
+    return null;
+  }
+
+  String get executable {
+    return null;
+  }
+
+  List<String>  get executableArguments {
+    return new List<String>(0);
+  }
+
+  String get packageRoot {
+    return null;
+  }
+}
diff --git a/runtime/lib/platform_sources.gypi b/runtime/lib/platform_sources.gypi
new file mode 100644
index 0000000..dd1b34f
--- /dev/null
+++ b/runtime/lib/platform_sources.gypi
@@ -0,0 +1,10 @@
+# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# This file contains all sources for the dart:platform library.
+{
+  'sources': [
+    'platform_patch.dart',
+  ],
+}
diff --git a/runtime/lib/regexp_patch.dart b/runtime/lib/regexp_patch.dart
index 909b801..e2b9fec 100644
--- a/runtime/lib/regexp_patch.dart
+++ b/runtime/lib/regexp_patch.dart
@@ -55,9 +55,6 @@
 
   Pattern get pattern => _regexp;
 
-  // TODO(12843): Remove when grace period is over.
-  String get str => input;
-
   final RegExp _regexp;
   final String input;
   final List<int> _match;
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index e717533..f19b305 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -89,9 +89,16 @@
       // TODO(5413632): Compare hash codes when both are present.
       return false;
     }
-    return this.compareTo(other) == 0;
+    final len = this.length;
+    for (int i = 0; i < len; i++) {
+      if (this.codeUnitAt(i) != other.codeUnitAt(i)) {
+        return false;
+      }
+    }
+    return true;
   }
 
+
   int compareTo(String other) {
     int thisLength = this.length;
     int otherLength = other.length;
@@ -523,6 +530,10 @@
     return _StringBase._isOneByteWhitespace(codePoint);
   }
 
+  bool operator ==(Object other) {
+    return super == other;
+  }
+
   String _substringUncheckedNative(int startIndex, int endIndex)
       native "OneByteString_substringUnchecked";
 
@@ -575,6 +586,10 @@
   bool _isWhitespace(int codePoint) {
     return _StringBase._isTwoByteWhitespace(codePoint);
   }
+
+  bool operator ==(Object other) {
+    return super == other;
+  }
 }
 
 
@@ -587,6 +602,10 @@
   bool _isWhitespace(int codePoint) {
     return _StringBase._isOneByteWhitespace(codePoint);
   }
+
+  bool operator ==(Object other) {
+    return super == other;
+  }
 }
 
 
@@ -599,6 +618,10 @@
   bool _isWhitespace(int codePoint) {
     return _StringBase._isTwoByteWhitespace(codePoint);
   }
+
+  bool operator ==(Object other) {
+    return super == other;
+  }
 }
 
 
@@ -626,9 +649,6 @@
     return result;
   }
 
-  // TODO(12843): Remove when grace period is over.
-  String get str => input;
-
   final int start;
   final String input;
   final String pattern;
diff --git a/runtime/tests/vm/dart/isolate_mirror_local_test.dart b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
index 4ffcaef..e5ca82e 100644
--- a/runtime/tests/vm/dart/isolate_mirror_local_test.dart
+++ b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
@@ -495,7 +495,7 @@
                                         'testCustomInstanceMirror']);
 
   // Test that an isolate can reflect on itself.
-  mirrorSystemOf(exit_port.toSendPort()).then(testMirrorSystem);
+  mirrorSystemOf(exit_port.sendPort).then(testMirrorSystem);
 
   testIntegerInstanceMirror(reflect(1001));
   testStringInstanceMirror(reflect('This\nis\na\nString'));
diff --git a/runtime/tests/vm/dart/isolate_mirror_remote_test.dart b/runtime/tests/vm/dart/isolate_mirror_remote_test.dart
index f3fff3a..7b36cfd 100644
--- a/runtime/tests/vm/dart/isolate_mirror_remote_test.dart
+++ b/runtime/tests/vm/dart/isolate_mirror_remote_test.dart
@@ -11,11 +11,9 @@
 import 'dart:isolate';
 import 'dart:mirrors';
 
-void isolateMain() {
-  port.receive(
-      (msg, replyPort) {
-        Expect.fail('Received unexpected message $msg in remote isolate.');
-      });
+void isolateMain(SendPort replyTo) {
+  var port = new ReceivePort();
+  replyTo.send(port.sendPort);
 }
 
 void testMirrorSystem(MirrorSystem mirror) {
@@ -23,11 +21,14 @@
 }
 
 void main() {
-  SendPort sp = spawnFunction(isolateMain);
-  try {
-    mirrorSystemOf(sp).then(testMirrorSystem);
-    Expect.fail('Should not reach here.  Remote isolates not implemented.');
-  } catch (exception) {
-    Expect.isTrue(exception is UnimplementedError);
-  }
+  var response = new ReceivePort();
+  Isolate.spawn(isolateMain, response.sendPort);
+  response.first.then((sp) {
+    try {
+      mirrorSystemOf(sp).then(testMirrorSystem);
+      Expect.fail('Should not reach here.  Remote isolates not implemented.');
+    } catch (exception) {
+      Expect.isTrue(exception is UnimplementedError);
+    }
+  });
 }
diff --git a/runtime/tests/vm/dart/isolate_unhandled_exception_test.dart b/runtime/tests/vm/dart/isolate_unhandled_exception_test.dart
deleted file mode 100644
index 798221e..0000000
--- a/runtime/tests/vm/dart/isolate_unhandled_exception_test.dart
+++ /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.
-
-library isolate_unhandled_exception_test;
-
-import "package:expect/expect.dart";
-import 'dart:async';
-import 'dart:isolate';
-
-// Tests that an isolate's keeps message handling working after
-// throwing an unhandled exception, if it was created with an
-// unhandled exception callback that returns true (continue handling).
-// This test verifies that a callback function specified in
-// Isolate.spawnFunction is called.
-
-// Note: this test will hang if an uncaught exception isn't handled,
-// either by an error in the callback or it returning false.
-
-void entry() {
-  port.receive((message, replyTo) {
-    if (message == 'throw exception') {
-      replyTo.call('throwing exception');
-      throw new UnsupportedError('ignore this exception');
-    }
-    replyTo.call('hello');
-    port.close();
-  });
-}
-
-bool exceptionCallback(IsolateUnhandledException e) {
-  return e.source.message == 'ignore this exception';
-}
-
-void main() {
-  var isolate_port = spawnFunction(entry, exceptionCallback);
-
-  // Send a message that will cause an ignorable exception to be thrown.
-  Future f = isolate_port.call('throw exception');
-  f.catchError((error) {
-    // Exception wasn't ignored as it was supposed to be.
-    Expect.fail("Error not expected");
-  });
-
-  // Verify that isolate can still handle messages.
-  isolate_port.call('hi').then((value) {
-    Expect.equals('hello', value);
-  }, onError: (error) {
-    Expect.fail("Error not expected");
-  });
-}
diff --git a/runtime/tests/vm/dart/isolate_unhandled_exception_test2.dart b/runtime/tests/vm/dart/isolate_unhandled_exception_test2.dart
deleted file mode 100644
index 7fe1c86..0000000
--- a/runtime/tests/vm/dart/isolate_unhandled_exception_test2.dart
+++ /dev/null
@@ -1,49 +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 isolate_unhandled_exception_test2;
-
-import 'dart:isolate';
-
-// Tests that an isolate's keeps message handling working after
-// throwing an unhandled exception, if there is a top level callback
-// method that returns whether to continue handling messages or not.
-// This test verifies that a default-named callback function is called
-// when no callback is specified in Isolate.spawnFunction.
-
-// Note: this test will hang if an uncaught exception isn't handled,
-// either by an error in the callback or it returning false.
-
-void entry() {
-  port.receive((message, replyTo) {
-    if (message == 'throw exception') {
-      replyTo.call('throwing exception');
-      throw new UnsupportedError('ignore this exception');
-    }
-    replyTo.call('hello');
-    port.close();
-  });
-}
-
-bool _unhandledExceptionCallback(IsolateUnhandledException e) {
-  return e.source.message == 'ignore this exception';
-}
-
-void main() {
-  var isolate_port = spawnFunction(entry);
-
-  // Send a message that will cause an ignorable exception to be thrown.
-  Future f = isolate_port.call('throw exception');
-  f.onComplete((future) {
-    // Exception wasn't ignored as it was supposed to be.
-    Expect.equals(null, future.exception);
-  });
-
-  // Verify that isolate can still handle messages.
-  isolate_port.call('hi').onComplete((future) {
-    Expect.equals(null, future.exception);
-    Expect.equals('hello', future.value);
-  });
-
-}
diff --git a/runtime/tests/vm/dart/isolate_unhandled_exception_uri_helper.dart b/runtime/tests/vm/dart/isolate_unhandled_exception_uri_helper.dart
deleted file mode 100644
index b8088a8..0000000
--- a/runtime/tests/vm/dart/isolate_unhandled_exception_uri_helper.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library isolate_unhandled_exception_uri_helper;
-
-import 'dart:isolate';
-
-// Isolate script that throws an uncaught exception, which is caught by an
-// uncaught exception handler.
-
-void main() {
-  port.receive((message, replyTo) {
-    if (message == 'throw exception') {
-      replyTo.call('throwing exception');
-      throw new UnsupportedError('ignore this exception');
-    }
-    replyTo.call('hello');
-    port.close();
-  });
-}
-
-bool _unhandledExceptionCallback(IsolateUnhandledException e) {
-  return e.source.message == 'ignore this exception';
-}
diff --git a/runtime/tests/vm/dart/isolate_unhandled_exception_uri_test.dart b/runtime/tests/vm/dart/isolate_unhandled_exception_uri_test.dart
deleted file mode 100644
index e3b9ebc..0000000
--- a/runtime/tests/vm/dart/isolate_unhandled_exception_uri_test.dart
+++ /dev/null
@@ -1,34 +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 isolate_unhandled_exception_uri_helper;
-
-import "package:expect/expect.dart";
-import 'dart:async';
-import 'dart:isolate';
-
-// Tests that isolate code in another script keeps message handling working
-// after throwing an unhandled exception, if it has a function called
-// unhandledExceptionCallback that returns true (continue handling).
-
-// Note: this test will hang if an uncaught exception isn't handled,
-// either by an error in the callback or it returning false.
-
-void main() {
-  var isolate_port = spawnUri('isolate_unhandled_exception_uri_helper.dart');
-
-  // Send a message that will cause an ignorable exception to be thrown.
-  Future f = isolate_port.call('throw exception');
-  f.catchError((error) {
-    Expect.fail("Error not expected");
-  });
-
-  // Verify that isolate can still handle messages.
-  isolate_port.call('hi').then((value) {
-    Expect.equals('hello', value);
-  }, onError: (error) {
-    Expect.fail("Error not expected");
-  });
-
-}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 1c349bf..be2665c 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -60,11 +60,9 @@
 
 [ $compiler == none && $runtime == drt ]
 dart/isolate_mirror_local_test: Skip
-dart/error_stacktrace_test: Skip
 
 [ $compiler == none && $runtime == dartium ]
 dart/isolate_mirror_local_test: Fail # Issue 13719: Please triage this failure.
-dart/error_stacktrace_test: Skip
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 dart/isolate_mirror_remote_test: Fail # Issue 13921
diff --git a/runtime/tools/gyp/runtime-configurations.gypi b/runtime/tools/gyp/runtime-configurations.gypi
index a648a53..d1fd833 100644
--- a/runtime/tools/gyp/runtime-configurations.gypi
+++ b/runtime/tools/gyp/runtime-configurations.gypi
@@ -99,6 +99,13 @@
         },
       },
 
+      'Dart_simmips_Base': {
+        'abstract': 1,
+        'xcode_settings': {
+          'ARCHS': [ 'i386' ],
+        },
+      },
+
       'Dart_Release': {
         'abstract': 1,
         'xcode_settings': {
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index cbc649d..1425d0b 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -2807,9 +2807,9 @@
     pushq(new_pc);
     pushq(PP);
     movq(PP, new_pp);
-  }
-  if (frame_size != 0) {
-    subq(RSP, Immediate(frame_size));
+    if (frame_size != 0) {
+      subq(RSP, Immediate(frame_size));
+    }
   }
 }
 
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index 4cb8158..0b100ce 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -431,12 +431,12 @@
       "import 'dart:core';\n"
       "import 'dart:collection';\n"
       "import 'dart:_collection-dev';\n"
+      "import 'dart:convert';\n"
       "import 'dart:math';\n"
       "import 'dart:isolate';\n"
       "import 'dart:mirrors';\n"
       "import 'dart:typed_data';\n"
       "import 'dart:utf';\n"
-      "import 'dart:json';\n"
       "import 'dart:builtin';\n"
       "import 'dart:io';\n"
       "\n";
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index cbbcee0..0ee04fc 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -54,10 +54,6 @@
                isolate,
                Bootstrap::isolate_source_paths_,
                Bootstrap::isolate_patch_paths_),
-  INIT_LIBRARY(ObjectStore::kJson,
-               json,
-               Bootstrap::json_source_paths_,
-               NULL),
   INIT_LIBRARY(ObjectStore::kMath,
                math,
                Bootstrap::math_source_paths_,
@@ -66,6 +62,10 @@
                mirrors,
                Bootstrap::mirrors_source_paths_,
                Bootstrap::mirrors_patch_paths_),
+  INIT_LIBRARY(ObjectStore::kPlatform,
+               platform,
+               Bootstrap::platform_source_paths_,
+               Bootstrap::platform_patch_paths_),
   INIT_LIBRARY(ObjectStore::kTypedData,
                typed_data,
                Bootstrap::typed_data_source_paths_,
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index 6ebc812..dd525d8 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -29,6 +29,7 @@
   static const char* json_source_paths_[];
   static const char* math_source_paths_[];
   static const char* mirrors_source_paths_[];
+  static const char* platform_source_paths_[];
   static const char* typed_data_source_paths_[];
   static const char* utf_source_paths_[];
 
@@ -41,6 +42,7 @@
   static const char* isolate_patch_paths_[];
   static const char* math_patch_paths_[];
   static const char* mirrors_patch_paths_[];
+  static const char* platform_patch_paths_[];
   static const char* typed_data_patch_paths_[];
 };
 
diff --git a/runtime/vm/bootstrap_natives.cc b/runtime/vm/bootstrap_natives.cc
index a072563..70c27e5 100644
--- a/runtime/vm/bootstrap_natives.cc
+++ b/runtime/vm/bootstrap_natives.cc
@@ -76,6 +76,10 @@
   ASSERT(!library.IsNull());
   library.set_native_entry_resolver(resolver);
 
+  library = Library::PlatformLibrary();
+  ASSERT(!library.IsNull());
+  library.set_native_entry_resolver(resolver);
+
   library = Library::TypedDataLibrary();
   ASSERT(!library.IsNull());
   library.set_native_entry_resolver(resolver);
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 7e1e097..8aed894 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -39,8 +39,8 @@
   V(Integer_equalToInteger, 2)                                                 \
   V(Integer_parse, 1)                                                          \
   V(Integer_leftShiftWithMask32, 3)                                            \
-  V(ReceivePortImpl_factory, 1)                                                \
-  V(ReceivePortImpl_closeInternal, 1)                                          \
+  V(RawReceivePortImpl_factory, 1)                                             \
+  V(RawReceivePortImpl_closeInternal, 1)                                       \
   V(SendPortImpl_sendInternal_, 3)                                             \
   V(Smi_shlFromInt, 2)                                                         \
   V(Smi_shrFromInt, 2)                                                         \
@@ -248,9 +248,9 @@
   V(Uint32x4_setFlagZ, 2)                                                      \
   V(Uint32x4_setFlagW, 2)                                                      \
   V(Uint32x4_select, 3)                                                        \
-  V(isolate_getPortInternal, 0)                                                \
-  V(isolate_spawnFunction, 2)                                                  \
-  V(isolate_spawnUri, 1)                                                       \
+  V(Isolate_mainPort, 0)                                                       \
+  V(Isolate_spawnFunction, 1)                                                  \
+  V(Isolate_spawnUri, 1)                                                       \
   V(Mirrors_isLocalPort, 1)                                                    \
   V(Mirrors_makeLocalClassMirror, 1)                                           \
   V(Mirrors_makeLocalTypeMirror, 1)                                            \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 12f2319..a141dc3 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1359,10 +1359,22 @@
 }
 
 
-// Copy the type parameters of the super and mixin classes to the
-// mixin application class. Change type arguments of super type and of
-// interfaces to refer to the respective type parameters of the mixin
-// application class.
+// Clone the type parameters of the super class and of the mixin class of this
+// mixin application class and use them as the type parameters of this mixin
+// application class. Set the type arguments of the super type, of the mixin
+// type (as well as of the interface type, which is identical to the mixin type)
+// to refer to the respective type parameters of the mixin application class.
+// In other words, decorate this mixin application class with type parameters
+// that forward to the super type and mixin type (and interface type).
+// Example:
+//   class S<T> { }
+//   class M<T> { }
+//   class C<E> extends S<E> with M<List<E>> { }
+// results in
+//   class S&M<T`, T> extends S<T`> implements M<T> { } // mixin == M<T>
+//   class C<E> extends S&M<E, List<E>> { }
+// CloneMixinAppTypeParameters decorates class S&M with type parameters T` and
+// T, and use them as type arguments in S<T`> and M<T>.
 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) {
   ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null());
   const AbstractType& super_type = AbstractType::Handle(
@@ -1385,6 +1397,7 @@
       mixin_app_class.token_pos()));
   ASSERT(!interface.IsFinalized());
   interfaces.SetAt(0, interface);
+  ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw());
   mixin_app_class.set_interfaces(interfaces);
 
   // If both the super type and the mixin type are non generic, the mixin
@@ -1410,7 +1423,7 @@
         param ^= super_type_params.TypeAt(i);
         param_name = param.name();
         param_bound = param.bound();
-        // TODO(hausner): handle type bounds.
+        // TODO(14453): handle type bounds.
         if (!param_bound.IsObjectType()) {
           const Script& script = Script::Handle(mixin_app_class.script());
           ReportError(Error::Handle(),  // No previous error.
@@ -1432,7 +1445,7 @@
         super_type_args.SetTypeAt(cloned_index, cloned_param);
         cloned_index++;
       }
-      // TODO(hausner): May need to handle BoundedType here.
+      // TODO(14453): May need to handle BoundedType here.
       ASSERT(super_type.IsType());
       Type::Cast(super_type).set_arguments(super_type_args);
       ASSERT(!super_type.IsFinalized());
@@ -1446,6 +1459,9 @@
     if (num_mixin_type_params > 0) {
       const TypeArguments& mixin_params =
           TypeArguments::Handle(mixin_class.type_parameters());
+      const TypeArguments& mixin_type_args = TypeArguments::Handle(
+          TypeArguments::New(num_mixin_type_params));
+      // TODO(regis): Can we share interface type and mixin_type?
       const TypeArguments& interface_type_args = TypeArguments::Handle(
           TypeArguments::New(num_mixin_type_params));
       for (intptr_t i = 0; i < num_mixin_type_params; i++) {
@@ -1453,7 +1469,7 @@
         param_name = param.name();
         param_bound = param.bound();
 
-        // TODO(hausner): handle type bounds.
+        // TODO(14453): handle type bounds.
         if (!param_bound.IsObjectType()) {
           const Script& script = Script::Handle(mixin_app_class.script());
           ReportError(Error::Handle(),  // No previous error.
@@ -1469,10 +1485,14 @@
                                           param.token_pos());
         cloned_type_params.SetTypeAt(cloned_index, cloned_param);
         interface_type_args.SetTypeAt(i, cloned_param);
+        mixin_type_args.SetTypeAt(i, cloned_param);
         cloned_index++;
       }
 
-      // Lastly, set the type arguments of the single interface type.
+      // Lastly, set the type arguments of the mixin type and of the single
+      // interface type.
+      ASSERT(!mixin_type.IsFinalized());
+      mixin_type.set_arguments(mixin_type_args);
       ASSERT(!interface.IsFinalized());
       interface.set_arguments(interface_type_args);
     }
@@ -1544,10 +1564,12 @@
 The offset of the first type parameter U of S&A must be at the finalized index
 of type parameter U of A.
 */
+// TODO(regis): The syntax does not use 'typedef' anymore. Rename to 'alias'?
 void ClassFinalizer::ApplyMixinTypedef(const Class& mixin_app_class) {
   // If this mixin typedef is aliasing another mixin typedef, another class
   // will be inserted via recursion. No need to check here.
   // The mixin type may or may not be finalized yet.
+  AbstractType& super_type = AbstractType::Handle(mixin_app_class.super_type());
   const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
   const Class& mixin_class = Class::Handle(mixin_type.type_class());
   ASSERT(mixin_class.is_mixin_typedef());
@@ -1560,27 +1582,42 @@
   String& inserted_class_name = String::Handle(mixin_app_class.Name());
   inserted_class_name = String::Concat(inserted_class_name,
                                        Symbols::Backtick());
-  inserted_class_name = Symbols::New(inserted_class_name);
-  const Script& script = Script::Handle(mixin_app_class.script());
   const Library& library = Library::Handle(mixin_app_class.library());
-  const Class& inserted_class = Class::Handle(Class::New(
-      inserted_class_name, script, mixin_app_class.token_pos()));
-  inserted_class.set_library(library);
-  inserted_class.set_is_synthesized_class();
+  Class& inserted_class = Class::Handle(
+      library.LookupLocalClass(inserted_class_name));
+  if (inserted_class.IsNull()) {
+    inserted_class_name = Symbols::New(inserted_class_name);
+    const Script& script = Script::Handle(mixin_app_class.script());
+    inserted_class = Class::New(
+        inserted_class_name, script, mixin_app_class.token_pos());
+    inserted_class.set_is_synthesized_class();
+    library.AddClass(inserted_class);
 
-  // The super type of the inserted class is identical to the super type of
-  // this mixin application class, except that it must refer to the type
-  // parameters of the inserted class rather than to those of the mixin
-  // application class.
-  // The type arguments of the super type will be set properly when calling
-  // CloneMixinAppTypeParameters on the inserted class, as long as the super
-  // type class is set properly.
-  AbstractType& super_type = AbstractType::Handle(mixin_app_class.super_type());
-  inserted_class.set_super_type(super_type);  // Super class only is used.
+    if (FLAG_trace_class_finalization) {
+      OS::Print("Creating mixin typedef application %s\n",
+                inserted_class.ToCString());
+    }
 
-  // The mixin type must also be set before calling CloneMixinAppTypeParameters.
-  // It refers to the type parameters of the mixin class typedef.
-  inserted_class.set_mixin(aliased_mixin_type);  // Mixin class only is used.
+    // The super type of the inserted class is identical to the super type of
+    // this mixin application class, except that it must refer to the type
+    // parameters of the inserted class rather than to those of the mixin
+    // application class.
+    // The type arguments of the super type will be set properly when calling
+    // CloneMixinAppTypeParameters on the inserted class, as long as the super
+    // type class is set properly.
+    inserted_class.set_super_type(super_type);  // Super class only is used.
+
+    // The mixin type and interface type must also be set before calling
+    // CloneMixinAppTypeParameters.
+    // After FinalizeTypesInClass, they will refer to the type parameters of
+    // the mixin class typedef.
+    const Type& generic_mixin_type = Type::Handle(
+        Type::New(Class::Handle(aliased_mixin_type.type_class()),
+                  Object::null_abstract_type_arguments(),
+                  aliased_mixin_type.token_pos()));
+    inserted_class.set_mixin(generic_mixin_type);
+    // The interface will be set in CloneMixinAppTypeParameters.
+  }
 
   // Finalize the types and call CloneMixinAppTypeParameters.
   FinalizeTypesInClass(inserted_class);
@@ -1589,9 +1626,10 @@
   // inserted class. The super type arguments are the concatenation of the
   // old super type arguments (propagating type arguments to the super class)
   // with new type arguments providing type arguments to the mixin.
-  // The appended type arguments are those of the aliased mixin type, except
+  // The appended type arguments are those of the super type of the mixin
+  // typedef that are forwarding to the aliased mixin type, except
   // that they must refer to the type parameters of the mixin application
-  // class rather than to those of the aliased mixin class.
+  // class rather than to those of the mixin typedef class.
   // This type parameter substitution is performed by an instantiation step.
   // It is important that the type parameters of the mixin application class
   // are not finalized yet, because new type parameters may have been added
@@ -1625,14 +1663,15 @@
   ASSERT(inserted_class.NumTypeParameters() ==
          (num_super_type_params + num_aliased_mixin_type_params));
   // The aliased_mixin_type may be raw.
-  const AbstractTypeArguments& aliased_mixin_type_args =
-      AbstractTypeArguments::Handle(aliased_mixin_type.arguments());
+  const AbstractTypeArguments& mixin_class_super_type_args =
+      AbstractTypeArguments::Handle(
+          AbstractType::Handle(mixin_class.super_type()).arguments());
   TypeArguments& new_mixin_type_args = TypeArguments::Handle();
   if ((num_aliased_mixin_type_params > 0) &&
-      !aliased_mixin_type_args.IsNull()) {
+      !mixin_class_super_type_args.IsNull()) {
     new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params);
     for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) {
-      type = aliased_mixin_type_args.TypeAt(offset + i);
+      type = mixin_class_super_type_args.TypeAt(offset + i);
       new_mixin_type_args.SetTypeAt(i, type);
     }
   }
@@ -1641,7 +1680,7 @@
     Error& bound_error = Error::Handle();
     new_mixin_type_args ^=
         new_mixin_type_args.InstantiateFrom(instantiator, &bound_error);
-    // TODO(regis): Handle bound error.
+    // TODO(14453): Handle bound error.
     ASSERT(bound_error.IsNull());
   }
   TypeArguments& new_super_type_args = TypeArguments::Handle();
@@ -1751,7 +1790,7 @@
   ASSERT(!mixin_type.IsBeingFinalized());
   mixin_type ^=
       FinalizeType(mixin_app_class, mixin_type, kCanonicalizeWellFormed);
-  // TODO(regis): Check for a malbounded mixin_type.
+  // TODO(14453): Check for a malbounded mixin_type.
   mixin_app_class.set_mixin(mixin_type);
 }
 
@@ -2224,33 +2263,83 @@
 }
 
 
-RawType* ClassFinalizer::ResolveMixinAppType(const Class& cls,
-                                             const MixinAppType& mixin_app) {
-  // Resolve super type and all mixin types.
+RawType* ClassFinalizer::ResolveMixinAppType(
+    const Class& cls,
+    const MixinAppType& mixin_app_type) {
+  // Lookup or create mixin application classes in the library of cls
+  // and resolve super type and mixin types.
+  const Library& library = Library::Handle(cls.library());
+  ASSERT(!library.IsNull());
+  const Script& script = Script::Handle(cls.script());
+  ASSERT(!script.IsNull());
   const GrowableObjectArray& type_args =
       GrowableObjectArray::Handle(GrowableObjectArray::New());
-  AbstractType& type = AbstractType::Handle(mixin_app.SuperType());
-  ResolveType(cls, type, kCanonicalizeWellFormed);
-  ASSERT(type.HasResolvedTypeClass());
-  // TODO(hausner): May need to handle BoundedType here.
-  ASSERT(type.IsType());
-  CollectTypeArguments(cls, Type::Cast(type), type_args);
+  AbstractType& mixin_super_type =
+      AbstractType::Handle(mixin_app_type.super_type());
+  ResolveType(cls, mixin_super_type, kCanonicalizeWellFormed);
+  ASSERT(mixin_super_type.HasResolvedTypeClass());
+  // TODO(14453): May need to handle BoundedType here.
+  ASSERT(mixin_super_type.IsType());
+  CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args);
+  AbstractType& mixin_type = AbstractType::Handle();
+  Type& generic_mixin_type = Type::Handle();
+  Class& mixin_type_class = Class::Handle();
   Class& mixin_app_class = Class::Handle();
-  const intptr_t depth = mixin_app.Depth();
+  String& mixin_app_class_name = String::Handle();
+  String& mixin_type_class_name = String::Handle();
+  const intptr_t depth = mixin_app_type.Depth();
   for (intptr_t i = 0; i < depth; i++) {
-    mixin_app_class = mixin_app.MixinAppAt(i);
-    type = mixin_app_class.mixin();
-    ASSERT(!type.IsNull());
-    ResolveType(cls, type, kCanonicalizeWellFormed);
-    ASSERT(type.HasResolvedTypeClass());
-    ASSERT(type.IsType());
-    CollectTypeArguments(cls, Type::Cast(type), type_args);
+    mixin_type = mixin_app_type.MixinTypeAt(i);
+    ASSERT(!mixin_type.IsNull());
+    ResolveType(cls, mixin_type, kCanonicalizeWellFormed);
+    ASSERT(mixin_type.HasResolvedTypeClass());
+    ASSERT(mixin_type.IsType());
+    CollectTypeArguments(cls, Type::Cast(mixin_type), type_args);
+
+    // The name of the mixin application class is a combination of
+    // the super class name and mixin class name.
+    mixin_app_class_name = mixin_super_type.ClassName();
+    mixin_app_class_name = String::Concat(mixin_app_class_name,
+                                          Symbols::Ampersand());
+    mixin_type_class_name = mixin_type.ClassName();
+    mixin_app_class_name = String::Concat(mixin_app_class_name,
+                                          mixin_type_class_name);
+    mixin_app_class = library.LookupLocalClass(mixin_app_class_name);
+    if (mixin_app_class.IsNull()) {
+      mixin_app_class_name = Symbols::New(mixin_app_class_name);
+      mixin_app_class = Class::New(mixin_app_class_name,
+                                   script,
+                                   mixin_type.token_pos());
+      mixin_app_class.set_super_type(mixin_super_type);
+      mixin_type_class = mixin_type.type_class();
+      generic_mixin_type = Type::New(mixin_type_class,
+                                     Object::null_abstract_type_arguments(),
+                                     mixin_type.token_pos());
+      mixin_app_class.set_mixin(generic_mixin_type);
+      mixin_app_class.set_is_synthesized_class();
+      library.AddClass(mixin_app_class);
+
+      // No need to add the new class to pending_classes, since it will be
+      // processed via the super_type chain of a pending class.
+
+      if (FLAG_trace_class_finalization) {
+        OS::Print("Creating mixin application %s\n",
+                  mixin_app_class.ToCString());
+      }
+    }
+    // This mixin application class becomes the type class of the super type of
+    // the next mixin application class. It is however too early to provide the
+    // correct super type arguments. We use the raw type for now.
+    mixin_super_type = Type::New(mixin_app_class,
+                                 Object::null_abstract_type_arguments(),
+                                 mixin_type.token_pos());
   }
+  AbstractType& type_arg = AbstractType::Handle();
   const TypeArguments& mixin_app_args =
     TypeArguments::Handle(TypeArguments::New(type_args.Length()));
   for (intptr_t i = 0; i < type_args.Length(); i++) {
-    type ^= type_args.At(i);
-    mixin_app_args.SetTypeAt(i, type);
+    type_arg ^= type_args.At(i);
+    mixin_app_args.SetTypeAt(i, type_arg);
   }
   if (FLAG_trace_class_finalization) {
     OS::Print("ResolveMixinAppType: mixin appl type args: %s\n",
@@ -2262,7 +2351,7 @@
   // collected type arguments from the super type and all mixin types.
   // This super type replaces the MixinAppType object in the class that extends
   // the mixin application.
-  return Type::New(mixin_app_class, mixin_app_args, mixin_app.token_pos());
+  return Type::New(mixin_app_class, mixin_app_args, mixin_app_type.token_pos());
 }
 
 
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 597c806..793674b 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -122,7 +122,7 @@
                                    const Type& type,
                                    const GrowableObjectArray& collected_args);
   static RawType* ResolveMixinAppType(const Class& cls,
-                                      const MixinAppType& mixin_app);
+                                      const MixinAppType& mixin_app_type);
   static void ResolveSuperTypeAndInterfaces(const Class& cls,
                                             GrowableArray<intptr_t>* visited);
   static void FinalizeTypeParameters(const Class& cls);
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 82e2561..a5f45bf 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1418,10 +1418,22 @@
   ASSERT(caller_code.is_optimized());
   const Function& target_function = Function::Handle(
       caller_code.GetStaticCallTargetFunctionAt(frame->pc()));
-  const Code& target_code = Code::Handle(target_function.CurrentCode());
-  CodePatcher::PatchStaticCallAt(frame->pc(), caller_code,
-                                 target_code.EntryPoint());
-  caller_code.SetStaticCallTargetCodeAt(frame->pc(), target_code);
+
+  // Check whether the code object has been detached from the target function.
+  // If it has been detached, reattach it.
+  Code& target_code = Code::Handle();
+  if (target_function.HasCode()) {
+    target_code ^= target_function.CurrentCode();
+    CodePatcher::PatchStaticCallAt(frame->pc(), caller_code,
+                                   target_code.EntryPoint());
+    caller_code.SetStaticCallTargetCodeAt(frame->pc(), target_code);
+  } else {
+    ASSERT(target_function.unoptimized_code() == Code::null());
+    target_code ^= caller_code.GetStaticCallTargetCodeAt(frame->pc());
+    ASSERT(!target_code.IsNull());
+    ASSERT(!target_code.is_optimized());
+    target_function.ReattachCode(target_code);
+  }
   if (FLAG_trace_patching) {
     OS::PrintErr("FixCallersTarget: patching from %#" Px " to '%s' %#" Px "\n",
         frame->pc(),
diff --git a/runtime/vm/custom_isolate_test.cc b/runtime/vm/custom_isolate_test.cc
index d64e836..7d43473 100644
--- a/runtime/vm/custom_isolate_test.cc
+++ b/runtime/vm/custom_isolate_test.cc
@@ -24,7 +24,7 @@
 static const char* kCustomIsolateScriptChars =
     "import 'dart:isolate';\n"
     "\n"
-    "ReceivePort mainPort;\n"
+    "RawReceivePort mainPort;\n"
     "\n"
     "echo(arg) native \"native_echo\";\n"
     "\n"
@@ -51,21 +51,23 @@
     "\n"
     "isolateMain() {\n"
     "   echo('Running isolateMain');\n"
-    "   mainPort.receive((message, SendPort replyTo) {\n"
-    "     echo('Received: $message');\n"
-    "     replyTo.send((message + 1), null);\n"
-    "   });\n"
+    "   mainPort.handler = (message) {\n"
+    "     var data = message[0];\n"
+    "     var replyTo = message[1];\n"
+    "     echo('Received: $data');\n"
+    "     replyTo.send(data + 1);\n"
+    "   };\n"
     "}\n"
     "\n"
     "main() {\n"
     "  var isolate = new CustomIsolate(\"isolateMain\");\n"
-    "  var receivePort = new ReceivePort();\n"
+    "  var receivePort = new RawReceivePort();\n"
     "  SendPort port = isolate.spawn();\n"
-    "  port.send(42, receivePort.toSendPort());\n"
-    "  receivePort.receive((message, _) {\n"
+    "  port.send([42, receivePort.sendPort]);\n"
+    "  receivePort.handler = (message) {\n"
     "    receivePort.close();\n"
     "    echo('Received: $message');\n"
-    "  });\n"
+    "  };\n"
     "  return 'success';\n"
     "}\n";
 
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 0eff97c..32fc7bf 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1069,7 +1069,7 @@
   Library& isolate_lib = Library::Handle(isolate, Library::IsolateLibrary());
   ASSERT(!isolate_lib.IsNull());
   const String& class_name = String::Handle(
-      isolate, isolate_lib.PrivateName(Symbols::_ReceivePortImpl()));
+      isolate, isolate_lib.PrivateName(Symbols::_RawReceivePortImpl()));
   // TODO(asiva): Symbols should contain private keys.
   const String& function_name =
       String::Handle(isolate_lib.PrivateName(Symbols::_get_or_create()));
@@ -4014,6 +4014,8 @@
   }
   CHECK_CALLBACK_STATE(isolate);
 
+  NoHeapGrowthControlScope no_growth_control;
+
   library = Library::New(url_str);
   library.set_debuggable(true);
   library.Register();
@@ -4227,6 +4229,8 @@
   }
   CHECK_CALLBACK_STATE(isolate);
 
+  NoHeapGrowthControlScope no_growth_control;
+
   Library& library = Library::Handle(isolate, Library::LookupLibrary(url_str));
   if (library.IsNull()) {
     library = Library::New(url_str);
@@ -4321,6 +4325,8 @@
   }
   CHECK_CALLBACK_STATE(isolate);
 
+  NoHeapGrowthControlScope no_growth_control;
+
   const Script& script = Script::Handle(
       isolate, Script::New(url_str, source_str, RawScript::kSourceTag));
   Dart_Handle result;
@@ -4349,6 +4355,8 @@
   }
   CHECK_CALLBACK_STATE(isolate);
 
+  NoHeapGrowthControlScope no_growth_control;
+
   const Script& script = Script::Handle(
       isolate, Script::New(url_str, source_str, RawScript::kPatchTag));
   Dart_Handle result;
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 3524d71..63ea3a1 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -4,6 +4,7 @@
 
 #include "bin/builtin.h"
 #include "include/dart_api.h"
+#include "include/dart_debugger_api.h"
 #include "include/dart_mirrors_api.h"
 #include "include/dart_native_api.h"
 #include "platform/assert.h"
@@ -3672,22 +3673,24 @@
   const char* kScriptChars =
       "import 'dart:isolate';\n"
       "import 'dart:nativewrappers';\n"
-      "echo() {\n"
-      "  port.receive((msg, reply) {\n"
-      "    reply.send('echoing ${msg(1)}}');\n"
-      "  });\n"
+      "echo(msg) {\n"
+      "  var data = msg[0];\n"
+      "  var reply = msg[1];\n"
+      "  reply.send('echoing ${data(1)}}');\n"
       "}\n"
       "class Test extends NativeFieldWrapperClass2 {\n"
       "  Test(this.i, this.j);\n"
       "  int i, j;\n"
       "}\n"
       "main() {\n"
-      "  var snd = spawnFunction(echo);\n"
+      "  var port = new RawReceivePort();\n"
       "  var obj = new Test(1,2);\n"
-      "  snd.send(obj, port.toSendPort());\n"
-      "  port.receive((msg, reply) {\n"
+      "  var msg = [obj, port.sendPort];\n"
+      "  var snd = Isolate.spawn(echo, msg);\n"
+      "  port.handler = (msg) {\n"
+      "    port.close();\n"
       "    print('from worker ${msg}');\n"
-      "  });\n"
+      "  };\n"
       "}\n";
 
   DARTSCOPE(Isolate::Current());
@@ -4838,6 +4841,42 @@
   EXPECT_STREQ("library1_name", cstr);
 }
 
+TEST_CASE(LibraryId) {
+  const char* kLibrary1Chars =
+      "library library1_name;";
+  Dart_Handle url = NewString("library1_url");
+  Dart_Handle source = NewString(kLibrary1Chars);
+  Dart_Handle lib = Dart_LoadLibrary(url, source);
+  Dart_Handle error = Dart_NewApiError("incoming error");
+  EXPECT_VALID(lib);
+  intptr_t libraryId = -1;
+
+  Dart_Handle result = Dart_LibraryId(Dart_Null(), &libraryId);
+  EXPECT(Dart_IsError(result));
+  EXPECT_STREQ("Dart_LibraryId expects argument 'library' to be non-null.",
+               Dart_GetError(result));
+
+  result = Dart_LibraryId(Dart_True(), &libraryId);
+  EXPECT(Dart_IsError(result));
+  EXPECT_STREQ(
+      "Dart_LibraryId expects argument 'library' to be of type Library.",
+      Dart_GetError(result));
+
+  result = Dart_LibraryId(error, &libraryId);
+  EXPECT(Dart_IsError(result));
+  EXPECT_STREQ("incoming error", Dart_GetError(result));
+
+  result = Dart_LibraryId(lib, &libraryId);
+  EXPECT_VALID(result);
+  Dart_Handle libFromId = Dart_GetLibraryFromId(libraryId);
+  EXPECT(Dart_IsLibrary(libFromId));
+  result = Dart_LibraryName(libFromId);
+  EXPECT(Dart_IsString(result));
+  const char* cstr = NULL;
+  EXPECT_VALID(Dart_StringToCString(result, &cstr));
+  EXPECT_STREQ("library1_name", cstr);
+}
+
 
 TEST_CASE(LibraryUrl) {
   const char* kLibrary1Chars =
@@ -5780,12 +5819,12 @@
   const char* kScriptChars =
       "import 'dart:isolate';\n"
       "void callPort(SendPort port) {\n"
-      "  var receivePort = new ReceivePort();\n"
-      "  port.send(null, receivePort.toSendPort());\n"
-      "  receivePort.receive((message, _) {\n"
+      "  var receivePort = new RawReceivePort();\n"
+      "  port.send(null, receivePort.sendPort);\n"
+      "  receivePort.handler = (message) {\n"
       "    receivePort.close();\n"
       "    throw new Exception(message);\n"
-      "  });\n"
+      "  };\n"
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
   Dart_EnterScope();
@@ -5834,26 +5873,24 @@
   const char* kScriptChars =
       "import 'builtin';\n"
       "import 'dart:isolate';\n"
-      "void entry() {\n"
-      "  port.receive((message, replyTo) {\n"
-      "    if (message) {\n"
-      "      throw new Exception('MakeChildExit');\n"
-      "    } else {\n"
-      "      replyTo.call('hello');\n"
-      "      port.close();\n"
-      "    }\n"
-      "  });\n"
+      "void entry(message) {\n"
+      "  var data = message[0];\n"
+      "  var replyTo = message[1];\n"
+      "  if (data) {\n"
+      "    throw new Exception('MakeChildExit');\n"
+      "  } else {\n"
+      "    replyTo.send('hello');\n"
+      "  }\n"
       "}\n"
       "\n"
       "void main(exc_child, exc_parent) {\n"
-      "  var port = spawnFunction(entry);\n"
-      "  var receivePort = new ReceivePort();\n"
-      "  port.send(exc_child, receivePort.toSendPort());\n"
-      "  receivePort.receive((message, _) {\n"
+      "  var receivePort = new RawReceivePort();\n"
+      "  Isolate.spawn(entry, [exc_child, receivePort.sendPort]);\n"
+      "  receivePort.handler = (message) {\n"
       "    receivePort.close();\n"
       "    if (message != 'hello') throw new Exception('ShouldNotHappen');\n"
       "    if (exc_parent) throw new Exception('MakeParentExit');\n"
-      "  });\n"
+      "  };\n"
       "}\n";
 
   if (Dart_CurrentIsolate() != NULL) {
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 118f25d..332965e 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -383,7 +383,7 @@
     Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
     ASSERT(!isolate_lib.IsNull());
     const String& class_name =
-        String::Handle(isolate_lib.PrivateName(Symbols::_ReceivePortImpl()));
+        String::Handle(isolate_lib.PrivateName(Symbols::_RawReceivePortImpl()));
     const String& function_name =
         String::Handle(isolate_lib.PrivateName(Symbols::_lookupReceivePort()));
     function = Resolver::ResolveStatic(isolate_lib,
@@ -415,7 +415,7 @@
     Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
     ASSERT(!isolate_lib.IsNull());
     const String& class_name =
-        String::Handle(isolate_lib.PrivateName(Symbols::_ReceivePortImpl()));
+        String::Handle(isolate_lib.PrivateName(Symbols::_RawReceivePortImpl()));
     const String& function_name =
         String::Handle(isolate_lib.PrivateName(Symbols::_handleMessage()));
     function = Resolver::ResolveStatic(isolate_lib,
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 205a6d3..67b1c0de 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -864,7 +864,6 @@
 
 
 Debugger::~Debugger() {
-  PortMap::ClosePort(isolate_id_);
   isolate_id_ = ILLEGAL_ISOLATE_ID;
   ASSERT(!in_event_notification_);
   ASSERT(src_breakpoints_ == NULL);
@@ -1920,11 +1919,10 @@
     return;
   }
   isolate_ = isolate;
-  // Create a port here, we don't expect to receive any messages on this port.
+  // Use the isolate's control port as the isolate_id for debugging.
   // This port will be used as a unique ID to represet the isolate in the
   // debugger wire protocol messages.
-  // NOTE: SetLive is never called on this port.
-  isolate_id_ = PortMap::CreatePort(isolate->message_handler());
+  isolate_id_ = isolate->main_port();
   initialized_ = true;
 
   // Signal isolate creation event.
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index bdeb371..3ce60f9 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -397,6 +397,8 @@
 }
 
 
+// This function must be in sync with FlowGraphCompiler::SaveLiveRegisters
+// and FlowGraphCompiler::SlowPathEnvironmentFor.
 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) {
   if (is_optimizing()) {
     BitmapBuilder* bitmap = locs->stack_bitmap();
@@ -411,7 +413,7 @@
     // Slow path code can have registers at the safepoint.
     if (!locs->always_calls()) {
       RegisterSet* regs = locs->live_registers();
-      if (regs->fpu_regs_count() > 0) {
+      if (regs->FpuRegisterCount() > 0) {
         // Denote FPU registers with 0 bits in the stackmap.  Based on the
         // assumption that there are normally few live FPU registers, this
         // encoding is simpler and roughly as compact as storing a separate
@@ -448,6 +450,75 @@
 }
 
 
+// This function must be in sync with FlowGraphCompiler::RecordSafepoint and
+// FlowGraphCompiler::SaveLiveRegisters.
+Environment* FlowGraphCompiler::SlowPathEnvironmentFor(
+    Instruction* instruction) {
+  if (instruction->env() == NULL) return NULL;
+
+  Environment* env = instruction->env()->DeepCopy();
+  // 1. Iterate the registers in the order they will be spilled to compute
+  //    the slots they will be spilled to.
+  intptr_t next_slot = StackSize();
+  RegisterSet* regs = instruction->locs()->live_registers();
+  intptr_t fpu_reg_slots[kNumberOfFpuRegisters];
+  intptr_t cpu_reg_slots[kNumberOfCpuRegisters];
+  const intptr_t kFpuRegisterSpillFactor = kFpuRegisterSize / kWordSize;
+  // FPU registers are spilled first from highest to lowest register number.
+  for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) {
+    FpuRegister reg = static_cast<FpuRegister>(i);
+    if (regs->ContainsFpuRegister(reg)) {
+      // We use the lowest address (thus highest index) to identify a
+      // multi-word spill slot.
+      next_slot += kFpuRegisterSpillFactor;
+      fpu_reg_slots[i] = (next_slot - 1);
+    } else {
+      fpu_reg_slots[i] = -1;
+    }
+  }
+  // General purpose registers are spilled from lowest to highest register
+  // number.
+  for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
+    Register reg = static_cast<Register>(i);
+    if (regs->ContainsRegister(reg)) {
+      cpu_reg_slots[i] = next_slot++;
+    } else {
+      cpu_reg_slots[i] = -1;
+    }
+  }
+
+  // 2. Iterate the environment and replace register locations with the
+  //    corresponding spill slot locations.
+  for (Environment::DeepIterator it(env); !it.Done(); it.Advance()) {
+    Location loc = it.CurrentLocation();
+    if (loc.IsRegister()) {
+      intptr_t index = cpu_reg_slots[loc.reg()];
+      ASSERT(index >= 0);
+      it.SetCurrentLocation(Location::StackSlot(index));
+    } else if (loc.IsFpuRegister()) {
+      assembler()->Comment("You betcha!");
+      intptr_t index = fpu_reg_slots[loc.fpu_reg()];
+      ASSERT(index >= 0);
+      Value* value = it.CurrentValue();
+      switch (value->definition()->representation()) {
+        case kUnboxedDouble:
+        case kUnboxedMint:
+          it.SetCurrentLocation(Location::DoubleStackSlot(index));
+          break;
+        case kUnboxedFloat32x4:
+        case kUnboxedUint32x4:
+          it.SetCurrentLocation(Location::QuadStackSlot(index));
+          break;
+        default:
+          UNREACHABLE();
+      }
+    }
+  }
+
+  return env;
+}
+
+
 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id,
                                        DeoptReasonId reason) {
   ASSERT(is_optimizing_);
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 00f31ec..18c9028 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -285,7 +285,7 @@
 
   void TryIntrinsify();
 
-  void GenerateCallRuntime(intptr_t token_pos,
+  void GenerateRuntimeCall(intptr_t token_pos,
                            intptr_t deopt_id,
                            const RuntimeEntry& entry,
                            intptr_t argument_count,
@@ -434,6 +434,8 @@
   void SaveLiveRegisters(LocationSummary* locs);
   void RestoreLiveRegisters(LocationSummary* locs);
 
+  Environment* SlowPathEnvironmentFor(Instruction* instruction);
+
   // Returns true if the compiled function has a finally clause.
   bool HasFinally() const;
 
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index cad4610..f56b5d2 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -8,6 +8,7 @@
 #include "vm/flow_graph_compiler.h"
 
 #include "vm/ast_printer.h"
+#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/deopt_instructions.h"
 #include "vm/il_printer.h"
@@ -599,7 +600,7 @@
     __ PushList((1 << R1) | (1 << R2));
     __ LoadObject(R0, test_cache);
     __ Push(R0);
-    GenerateCallRuntime(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
+    GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
     // Pop the parameters supplied to the runtime entry. The result of the
     // instanceof runtime call will be left as the result of the operation.
     __ Drop(5);
@@ -678,7 +679,7 @@
     __ Push(R0);  // Push the source object.
     __ PushObject(dst_name);  // Push the name of the destination.
     __ PushObject(error_message);
-    GenerateCallRuntime(token_pos,
+    GenerateRuntimeCall(token_pos,
                         deopt_id,
                         kMalformedTypeErrorRuntimeEntry,
                         3,
@@ -708,7 +709,7 @@
   __ PushObject(dst_name);  // Push the name of the destination.
   __ LoadObject(R0, test_cache);
   __ Push(R0);
-  GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
   // type check runtime call is the checked value.
   __ Drop(6);
@@ -1228,7 +1229,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
+void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos,
                                             intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             intptr_t argument_count,
@@ -1368,8 +1369,18 @@
   // be invoked as a normal Dart function.
   __ add(IP, R2, ShifterOperand(R3, LSL, 2));
   __ ldr(R0, FieldAddress(IP, base + kWordSize));
-  __ ldr(R0, FieldAddress(R0, Function::code_offset()));
-  __ ldr(R0, FieldAddress(R0, Code::instructions_offset()));
+  __ ldr(R1, FieldAddress(R0, Function::code_offset()));
+  if (FLAG_collect_code) {
+    // If we are collecting code, the code object may be null.
+    Label is_compiled;
+    __ CompareImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
+    __ b(&is_compiled, NE);
+    __ BranchLink(&StubCode::CompileFunctionRuntimeCallLabel());
+    // R0: target function.
+    __ ldr(R1, FieldAddress(R0, Function::code_offset()));
+    __ Bind(&is_compiled);
+  }
+  __ ldr(R0, FieldAddress(R1, Code::instructions_offset()));
   __ LoadObject(R5, ic_data);
   __ LoadObject(R4, arguments_descriptor);
   __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag);
@@ -1495,9 +1506,11 @@
 }
 
 
+// This function must be in sync with FlowGraphCompiler::RecordSafepoint and
+// FlowGraphCompiler::SlowPathEnvironmentFor.
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
   // TODO(vegorov): consider saving only caller save (volatile) registers.
-  const intptr_t fpu_regs_count = locs->live_registers()->fpu_regs_count();
+  const intptr_t fpu_regs_count = locs->live_registers()->FpuRegisterCount();
   if (fpu_regs_count > 0) {
     __ AddImmediate(SP, -(fpu_regs_count * kFpuRegisterSize));
     // Store fpu registers with the lowest register number at the lowest
@@ -1536,7 +1549,7 @@
     __ PopList(cpu_registers);
   }
 
-  const intptr_t fpu_regs_count = locs->live_registers()->fpu_regs_count();
+  const intptr_t fpu_regs_count = locs->live_registers()->FpuRegisterCount();
   if (fpu_regs_count > 0) {
     // Fpu registers have the lowest register number at the lowest address.
     intptr_t offset = 0;
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 3098944..ce869b6 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -8,6 +8,7 @@
 #include "vm/flow_graph_compiler.h"
 
 #include "vm/ast_printer.h"
+#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/deopt_instructions.h"
 #include "vm/il_printer.h"
@@ -612,7 +613,7 @@
     __ pushl(EDX);  // Instantiator type arguments.
     __ LoadObject(EAX, test_cache);
     __ pushl(EAX);
-    GenerateCallRuntime(token_pos,
+    GenerateRuntimeCall(token_pos,
                         deopt_id,
                         kInstanceofRuntimeEntry,
                         5,
@@ -700,7 +701,7 @@
     __ pushl(EAX);  // Push the source object.
     __ PushObject(dst_name);  // Push the name of the destination.
     __ PushObject(error_message);
-    GenerateCallRuntime(token_pos,
+    GenerateRuntimeCall(token_pos,
                         deopt_id,
                         kMalformedTypeErrorRuntimeEntry,
                         3,
@@ -730,7 +731,7 @@
   __ PushObject(dst_name);  // Push the name of the destination.
   __ LoadObject(EAX, test_cache);
   __ pushl(EAX);
-  GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
   // type check runtime call is the checked value.
   __ Drop(6);
@@ -1237,7 +1238,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
+void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos,
                                             intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             intptr_t argument_count,
@@ -1412,8 +1413,19 @@
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
   __ movl(EAX, FieldAddress(EDI, ECX, TIMES_4, base + kWordSize));
-  __ movl(EAX, FieldAddress(EAX, Function::code_offset()));
-  __ movl(EAX, FieldAddress(EAX, Code::instructions_offset()));
+  __ movl(EBX, FieldAddress(EAX, Function::code_offset()));
+  if (FLAG_collect_code) {
+    // If we are collecting code, the code object may be null.
+    Label is_compiled;
+    const Immediate& raw_null =
+        Immediate(reinterpret_cast<intptr_t>(Object::null()));
+    __ cmpl(EBX, raw_null);
+    __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump);
+    __ call(&StubCode::CompileFunctionRuntimeCallLabel());
+    __ movl(EBX, FieldAddress(EAX, Function::code_offset()));
+    __ Bind(&is_compiled);
+  }
+  __ movl(EAX, FieldAddress(EBX, Code::instructions_offset()));
   __ LoadObject(ECX, ic_data);
   __ LoadObject(EDX, arguments_descriptor);
   __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
@@ -1505,10 +1517,11 @@
 }
 
 
-// This function must be in sync with FlowGraphCompiler::RecordSafepoint.
+// This function must be in sync with FlowGraphCompiler::RecordSafepoint and
+// FlowGraphCompiler::SlowPathEnvironmentFor.
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
   // TODO(vegorov): consider saving only caller save (volatile) registers.
-  const intptr_t xmm_regs_count = locs->live_registers()->fpu_regs_count();
+  const intptr_t xmm_regs_count = locs->live_registers()->FpuRegisterCount();
   if (xmm_regs_count > 0) {
     __ subl(ESP, Immediate(xmm_regs_count * kFpuRegisterSize));
     // Store XMM registers with the lowest register number at the lowest
@@ -1545,7 +1558,7 @@
     }
   }
 
-  const intptr_t xmm_regs_count = locs->live_registers()->fpu_regs_count();
+  const intptr_t xmm_regs_count = locs->live_registers()->FpuRegisterCount();
   if (xmm_regs_count > 0) {
     // XMM registers have the lowest register number at the lowest address.
     intptr_t offset = 0;
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index f386d7f..75c2019 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -8,6 +8,7 @@
 #include "vm/flow_graph_compiler.h"
 
 #include "vm/ast_printer.h"
+#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/deopt_instructions.h"
 #include "vm/il_printer.h"
@@ -603,7 +604,7 @@
     __ sw(A1, Address(SP, 1 * kWordSize));  // Push type arguments.
     __ LoadObject(A0, test_cache);
     __ sw(A0, Address(SP, 0 * kWordSize));
-    GenerateCallRuntime(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
+    GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
     // Pop the parameters supplied to the runtime entry. The result of the
     // instanceof runtime call will be left as the result of the operation.
     __ lw(T0, Address(SP, 5 * kWordSize));
@@ -691,7 +692,7 @@
     __ LoadObject(TMP1, error_message);
     __ sw(TMP1, Address(SP, 0 * kWordSize));
 
-    GenerateCallRuntime(token_pos,
+    GenerateRuntimeCall(token_pos,
                         deopt_id,
                         kMalformedTypeErrorRuntimeEntry,
                         3,
@@ -730,7 +731,7 @@
   __ LoadObject(T0, test_cache);
   __ sw(T0, Address(SP, 0 * kWordSize));
 
-  GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
   // type check runtime call is the checked value.
   __ lw(A0, Address(SP, 6 * kWordSize));
@@ -1272,7 +1273,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
+void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos,
                                             intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             intptr_t argument_count,
@@ -1412,11 +1413,20 @@
   // proper target for the given name and arguments descriptor.  If the
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
-  __ sll(TMP1, T3, 2);
-  __ addu(TMP1, T2, TMP1);
-  __ lw(T0, FieldAddress(TMP, base + kWordSize));
-  __ lw(T0, FieldAddress(T0, Function::code_offset()));
-  __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
+  __ sll(T1, T3, 2);
+  __ addu(T1, T2, T1);
+  __ lw(T0, FieldAddress(T1, base + kWordSize));
+  __ lw(T1, FieldAddress(T0, Function::code_offset()));
+  if (FLAG_collect_code) {
+    // If we are collecting code, the code object may be null.
+    Label is_compiled;
+    __ BranchNotEqual(T1, reinterpret_cast<int32_t>(Object::null()),
+                      &is_compiled);
+    __ BranchLink(&StubCode::CompileFunctionRuntimeCallLabel());
+    __ lw(T1, FieldAddress(T0, Function::code_offset()));
+    __ Bind(&is_compiled);
+  }
+  __ lw(T0, FieldAddress(T1, Code::instructions_offset()));
   __ LoadObject(S5, ic_data);
   __ LoadObject(S4, arguments_descriptor);
   __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
@@ -1552,10 +1562,12 @@
 }
 
 
+// This function must be in sync with FlowGraphCompiler::RecordSafepoint and
+// FlowGraphCompiler::SlowPathEnvironmentFor.
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
   __ TraceSimMsg("SaveLiveRegisters");
   // TODO(vegorov): consider saving only caller save (volatile) registers.
-  const intptr_t fpu_regs_count= locs->live_registers()->fpu_regs_count();
+  const intptr_t fpu_regs_count= locs->live_registers()->FpuRegisterCount();
   if (fpu_regs_count > 0) {
     __ AddImmediate(SP, -(fpu_regs_count * kFpuRegisterSize));
     // Store fpu registers with the lowest register number at the lowest
@@ -1607,7 +1619,7 @@
   }
   __ addiu(SP, SP, Immediate(register_count * kWordSize));
 
-  const intptr_t fpu_regs_count = locs->live_registers()->fpu_regs_count();
+  const intptr_t fpu_regs_count = locs->live_registers()->FpuRegisterCount();
   if (fpu_regs_count > 0) {
     // Fpu registers have the lowest register number at the lowest address.
     intptr_t offset = 0;
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 3fb0507..b8edc30 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -8,6 +8,7 @@
 #include "vm/flow_graph_compiler.h"
 
 #include "vm/ast_printer.h"
+#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/deopt_instructions.h"
 #include "vm/il_printer.h"
@@ -599,7 +600,7 @@
     __ pushq(RDX);  // Instantiator type arguments.
     __ LoadObject(RAX, test_cache, PP);
     __ pushq(RAX);
-    GenerateCallRuntime(token_pos,
+    GenerateRuntimeCall(token_pos,
                         deopt_id,
                         kInstanceofRuntimeEntry,
                         5,
@@ -682,7 +683,7 @@
     __ pushq(RAX);  // Push the source object.
     __ PushObject(dst_name, PP);  // Push the name of the destination.
     __ PushObject(error_message, PP);
-    GenerateCallRuntime(token_pos,
+    GenerateRuntimeCall(token_pos,
                         deopt_id,
                         kMalformedTypeErrorRuntimeEntry,
                         3,
@@ -712,7 +713,7 @@
   __ 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);
+  GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
   // type check runtime call is the checked value.
   __ Drop(6);
@@ -1272,7 +1273,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
+void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos,
                                             intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             intptr_t argument_count,
@@ -1447,8 +1448,19 @@
   // illegal class id was found, the target is a cache miss handler that can
   // be invoked as a normal Dart function.
   __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize));
-  __ movq(RAX, FieldAddress(RAX, Function::code_offset()));
-  __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
+  __ movq(RBX, FieldAddress(RAX, Function::code_offset()));
+  if (FLAG_collect_code) {
+    // If we are collecting code, the code object may be null.
+    Label is_compiled;
+    const Immediate& raw_null =
+        Immediate(reinterpret_cast<intptr_t>(Object::null()));
+    __ cmpq(RBX, raw_null);
+    __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump);
+    __ call(&StubCode::CompileFunctionRuntimeCallLabel());
+    __ movq(RBX, FieldAddress(RAX, Function::code_offset()));
+    __ Bind(&is_compiled);
+  }
+  __ movq(RAX, FieldAddress(RBX, Code::instructions_offset()));
   __ LoadObject(RBX, ic_data, PP);
   __ LoadObject(R10, arguments_descriptor, PP);
   __ AddImmediate(
@@ -1541,10 +1553,11 @@
 }
 
 
-// This function must be in sync with FlowGraphCompiler::RecordSafepoint.
+// This function must be in sync with FlowGraphCompiler::RecordSafepoint and
+// FlowGraphCompiler::SlowPathEnvironmentFor.
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
   // TODO(vegorov): consider saving only caller save (volatile) registers.
-  const intptr_t xmm_regs_count = locs->live_registers()->fpu_regs_count();
+  const intptr_t xmm_regs_count = locs->live_registers()->FpuRegisterCount();
   if (xmm_regs_count > 0) {
     __ AddImmediate(RSP, Immediate(-xmm_regs_count * kFpuRegisterSize), PP);
     // Store XMM registers with the lowest register number at the lowest
@@ -1581,7 +1594,7 @@
     }
   }
 
-  const intptr_t xmm_regs_count = locs->live_registers()->fpu_regs_count();
+  const intptr_t xmm_regs_count = locs->live_registers()->FpuRegisterCount();
   if (xmm_regs_count > 0) {
     // XMM registers have the lowest register number at the lowest address.
     intptr_t offset = 0;
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 185eaf3..2da67b0 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -2026,8 +2026,16 @@
                       deopt_id_,
                       function_,
                       (outer_ == NULL) ? NULL : outer_->DeepCopy());
+  if (locations_ != NULL) {
+    Location* new_locations =
+        Isolate::Current()->current_zone()->Alloc<Location>(length);
+    copy->set_locations(new_locations);
+  }
   for (intptr_t i = 0; i < length; ++i) {
     copy->values_.Add(values_[i]->Copy());
+    if (locations_ != NULL) {
+      copy->locations_[i] = locations_[i];
+    }
   }
   return copy;
 }
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 62cd8a6..deebded 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -6833,6 +6833,8 @@
 
   const Function& function() const { return function_; }
 
+  Environment* DeepCopy() const { return DeepCopy(Length()); }
+
   void DeepCopyTo(Instruction* instr) const;
   void DeepCopyToOuter(Instruction* instr) const;
 
@@ -6853,10 +6855,9 @@
         function_(function),
         outer_(outer) { }
 
-  // Deep copy an environment.  A 'length' parameter can be given, which may
-  // be less than the environment's length in order to drop values (e.g.,
-  // passed arguments) from the copy.
-  Environment* DeepCopy() const { return DeepCopy(Length()); }
+  // Deep copy an environment.  The 'length' parameter may be less than the
+  // environment's length in order to drop values (e.g., passed arguments)
+  // from the copy.
   Environment* DeepCopy(intptr_t length) const;
 
   GrowableArray<Value*> values_;
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 0ec3129..775a8e9 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -246,7 +246,7 @@
   __ b(&done, EQ);
 
   __ Push(reg);  // Push the source object.
-  compiler->GenerateCallRuntime(token_pos,
+  compiler->GenerateRuntimeCall(token_pos,
                                 deopt_id,
                                 kConditionTypeErrorRuntimeEntry,
                                 1,
@@ -1876,7 +1876,7 @@
 
 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode(
     FlowGraphCompiler* compiler) {
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kAllocateObjectWithBoundsCheckRuntimeEntry,
                                 3,
@@ -1924,7 +1924,7 @@
   __ PushObject(Object::ZoneHandle());  // Make room for the result.
   __ PushObject(type());
   __ Push(instantiator_reg);  // Push instantiator type arguments.
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kInstantiateTypeRuntimeEntry,
                                 2,
@@ -1971,7 +1971,7 @@
   __ PushObject(Object::ZoneHandle());  // Make room for the result.
   __ PushObject(type_arguments());
   __ Push(instantiator_reg);  // Push instantiator type arguments.
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kInstantiateTypeArgumentsRuntimeEntry,
                                 2,
@@ -2107,7 +2107,7 @@
 
   __ PushObject(Object::ZoneHandle());  // Make room for the result.
   __ Push(context_value);
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kCloneContextRuntimeEntry,
                                 1,
@@ -2178,8 +2178,9 @@
     // pending_deoptimization_env_ is needed to generate a runtime call that
     // may throw an exception.
     ASSERT(compiler->pending_deoptimization_env_ == NULL);
-    compiler->pending_deoptimization_env_ = instruction_->env();
-    compiler->GenerateCallRuntime(instruction_->token_pos(),
+    Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
+    compiler->pending_deoptimization_env_ = env;
+    compiler->GenerateRuntimeCall(instruction_->token_pos(),
                                   instruction_->deopt_id(),
                                   kStackOverflowRuntimeEntry,
                                   0,
@@ -4374,7 +4375,7 @@
 
 
 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kThrowRuntimeEntry,
                                 1,
@@ -4390,7 +4391,7 @@
 
 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   compiler->SetNeedsStacktrace(catch_try_index());
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kReThrowRuntimeEntry,
                                 2,
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index cd6d5fa..6daebaf 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -194,7 +194,7 @@
   __ j(EQUAL, &done, Assembler::kNearJump);
 
   __ pushl(reg);  // Push the source object.
-  compiler->GenerateCallRuntime(token_pos,
+  compiler->GenerateRuntimeCall(token_pos,
                                 deopt_id,
                                 kConditionTypeErrorRuntimeEntry,
                                 1,
@@ -1959,7 +1959,7 @@
 
 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode(
     FlowGraphCompiler* compiler) {
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kAllocateObjectWithBoundsCheckRuntimeEntry,
                                 3,
@@ -2006,7 +2006,7 @@
   __ PushObject(Object::ZoneHandle());  // Make room for the result.
   __ PushObject(type());
   __ pushl(instantiator_reg);  // Push instantiator type arguments.
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kInstantiateTypeRuntimeEntry,
                                 2,
@@ -2054,7 +2054,7 @@
   __ PushObject(Object::ZoneHandle());  // Make room for the result.
   __ PushObject(type_arguments());
   __ pushl(instantiator_reg);  // Push instantiator type arguments.
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kInstantiateTypeArgumentsRuntimeEntry,
                                 2,
@@ -2192,7 +2192,7 @@
 
   __ PushObject(Object::ZoneHandle());  // Make room for the result.
   __ pushl(context_value);
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kCloneContextRuntimeEntry,
                                 1,
@@ -2258,8 +2258,9 @@
     // pending_deoptimization_env_ is needed to generate a runtime call that
     // may throw an exception.
     ASSERT(compiler->pending_deoptimization_env_ == NULL);
-    compiler->pending_deoptimization_env_ = instruction_->env();
-    compiler->GenerateCallRuntime(instruction_->token_pos(),
+    Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
+    compiler->pending_deoptimization_env_ = env;
+    compiler->GenerateRuntimeCall(instruction_->token_pos(),
                                   instruction_->deopt_id(),
                                   kStackOverflowRuntimeEntry,
                                   0,
@@ -4704,7 +4705,7 @@
 
 
 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kThrowRuntimeEntry,
                                 1,
@@ -4720,7 +4721,7 @@
 
 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   compiler->SetNeedsStacktrace(catch_try_index());
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kReThrowRuntimeEntry,
                                 2,
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 9b8fdcf..a62d0d8 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -249,7 +249,7 @@
   __ BranchEqual(reg, Bool::False(), &done);
 
   __ Push(reg);  // Push the source object.
-  compiler->GenerateCallRuntime(token_pos,
+  compiler->GenerateRuntimeCall(token_pos,
                                 deopt_id,
                                 kConditionTypeErrorRuntimeEntry,
                                 1,
@@ -1944,7 +1944,7 @@
 
 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode(
     FlowGraphCompiler* compiler) {
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kAllocateObjectWithBoundsCheckRuntimeEntry,
                                 3,
@@ -1997,7 +1997,7 @@
   // Push instantiator type arguments.
   __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
 
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kInstantiateTypeRuntimeEntry,
                                 2,
@@ -2051,7 +2051,7 @@
   // Push instantiator type arguments.
   __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
 
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kInstantiateTypeArgumentsRuntimeEntry,
                                 2,
@@ -2194,7 +2194,7 @@
   __ sw(TMP1, Address(SP, 1 * kWordSize));
   __ sw(context_value, Address(SP, 0 * kWordSize));
 
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kCloneContextRuntimeEntry,
                                 1,
@@ -2269,8 +2269,9 @@
     // pending_deoptimization_env_ is needed to generate a runtime call that
     // may throw an exception.
     ASSERT(compiler->pending_deoptimization_env_ == NULL);
-    compiler->pending_deoptimization_env_ = instruction_->env();
-    compiler->GenerateCallRuntime(instruction_->token_pos(),
+    Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
+    compiler->pending_deoptimization_env_ = env;
+    compiler->GenerateRuntimeCall(instruction_->token_pos(),
                                   instruction_->deopt_id(),
                                   kStackOverflowRuntimeEntry,
                                   0,
@@ -3764,7 +3765,7 @@
 
 
 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kThrowRuntimeEntry,
                                 1,
@@ -3780,7 +3781,7 @@
 
 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   compiler->SetNeedsStacktrace(catch_try_index());
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kReThrowRuntimeEntry,
                                 2,
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index b005879..cf5e72d 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -347,7 +347,7 @@
   __ j(EQUAL, &done, Assembler::kNearJump);
 
   __ pushq(reg);  // Push the source object.
-  compiler->GenerateCallRuntime(token_pos,
+  compiler->GenerateRuntimeCall(token_pos,
                                 deopt_id,
                                 kConditionTypeErrorRuntimeEntry,
                                 1,
@@ -1898,7 +1898,7 @@
 
 void AllocateObjectWithBoundsCheckInstr::EmitNativeCode(
     FlowGraphCompiler* compiler) {
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kAllocateObjectWithBoundsCheckRuntimeEntry,
                                 3,
@@ -1945,7 +1945,7 @@
   __ PushObject(Object::ZoneHandle(), PP);  // Make room for the result.
   __ PushObject(type(), PP);
   __ pushq(instantiator_reg);  // Push instantiator type arguments.
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kInstantiateTypeRuntimeEntry,
                                 2,
@@ -1991,7 +1991,7 @@
   __ PushObject(Object::ZoneHandle(), PP);  // Make room for the result.
   __ PushObject(type_arguments(), PP);
   __ pushq(instantiator_reg);  // Push instantiator type arguments.
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kInstantiateTypeArgumentsRuntimeEntry,
                                 2,
@@ -2127,7 +2127,7 @@
 
   __ PushObject(Object::ZoneHandle(), PP);  // Make room for the result.
   __ pushq(context_value);
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kCloneContextRuntimeEntry,
                                 1,
@@ -2198,8 +2198,9 @@
     // pending_deoptimization_env_ is needed to generate a runtime call that
     // may throw an exception.
     ASSERT(compiler->pending_deoptimization_env_ == NULL);
-    compiler->pending_deoptimization_env_ = instruction_->env();
-    compiler->GenerateCallRuntime(instruction_->token_pos(),
+    Environment* env = compiler->SlowPathEnvironmentFor(instruction_);
+    compiler->pending_deoptimization_env_ = env;
+    compiler->GenerateRuntimeCall(instruction_->token_pos(),
                                   instruction_->deopt_id(),
                                   kStackOverflowRuntimeEntry,
                                   0,
@@ -4490,7 +4491,7 @@
 
 
 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kThrowRuntimeEntry,
                                 1,
@@ -4506,7 +4507,7 @@
 
 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   compiler->SetNeedsStacktrace(catch_try_index());
-  compiler->GenerateCallRuntime(token_pos(),
+  compiler->GenerateRuntimeCall(token_pos(),
                                 deopt_id(),
                                 kReThrowRuntimeEntry,
                                 2,
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index e5d4dd2..2674d82 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -55,6 +55,8 @@
       OneByteString_substringUnchecked, 25652388)                              \
   V(_OneByteString, _setAt, OneByteString_setAt, 308408714)                    \
   V(_OneByteString, _allocate, OneByteString_allocate, 1744068081)             \
+  V(_OneByteString, ==, OneByteString_equality, 1064139944)                    \
+  V(_TwoByteString, ==, TwoByteString_equality, 1616855207)                    \
 
 
 #define CORE_INTEGER_LIB_INTRINSIC_LIST(V)                                     \
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 071e2a3..bae81da 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -1422,7 +1422,7 @@
   __ CompareClassId(R0, kTwoByteStringCid, R3);
   __ b(&fall_through, NE);
   ASSERT(kSmiTagShift == 1);
-  __ AddImmediate(R0, OneByteString::data_offset() - kHeapObjectTag);
+  __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
   __ ldrh(R0, Address(R0, R1));
   __ SmiTag(R0);
   __ Ret();
@@ -1654,6 +1654,81 @@
   __ Bind(&fall_through);
 }
 
+
+// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
+void StringEquality(Assembler* assembler, intptr_t string_cid) {
+  Label fall_through, is_true, is_false, loop;
+  __ ldr(R0, Address(SP, 1 * kWordSize));  // This.
+  __ ldr(R1, Address(SP, 0 * kWordSize));  // Other.
+
+  // Are identical?
+  __ cmp(R0, ShifterOperand(R1));
+  __ b(&is_true, EQ);
+
+  // Is other OneByteString?
+  __ tst(R1, ShifterOperand(kSmiTagMask));
+  __ b(&fall_through, EQ);
+  __ CompareClassId(R1, string_cid, R2);
+  __ b(&fall_through, NE);
+
+  // Have same length?
+  __ ldr(R2, FieldAddress(R0, String::length_offset()));
+  __ ldr(R3, FieldAddress(R1, String::length_offset()));
+  __ cmp(R2, ShifterOperand(R3));
+  __ b(&is_false, NE);
+
+  // Check contents, no fall-through possible.
+  // TODO(zra): try out other sequences.
+  ASSERT((string_cid == kOneByteStringCid) ||
+         (string_cid == kTwoByteStringCid));
+  const intptr_t offset = (string_cid == kOneByteStringCid) ?
+      OneByteString::data_offset() : TwoByteString::data_offset();
+  __ AddImmediate(R0, offset - kHeapObjectTag);
+  __ AddImmediate(R1, offset - kHeapObjectTag);
+  __ SmiUntag(R2);
+  __ Bind(&loop);
+  __ AddImmediate(R2, -1);
+  __ cmp(R2, ShifterOperand(0));
+  __ b(&is_true, LT);
+  if (string_cid == kOneByteStringCid) {
+    __ ldrb(R3, Address(R0));
+    __ ldrb(R4, Address(R1));
+    __ AddImmediate(R0, 1);
+    __ AddImmediate(R1, 1);
+  } else if (string_cid == kTwoByteStringCid) {
+    __ ldrh(R3, Address(R0));
+    __ ldrh(R4, Address(R1));
+    __ AddImmediate(R0, 2);
+    __ AddImmediate(R1, 2);
+  } else {
+    UNIMPLEMENTED();
+  }
+  __ cmp(R3, ShifterOperand(R4));
+  __ b(&is_false, NE);
+  __ b(&loop);
+
+  __ Bind(&is_true);
+  __ LoadObject(R0, Bool::True());
+  __ Ret();
+
+  __ Bind(&is_false);
+  __ LoadObject(R0, Bool::False());
+  __ Ret();
+
+  __ Bind(&fall_through);
+}
+
+
+void Intrinsifier::OneByteString_equality(Assembler* assembler) {
+  StringEquality(assembler, kOneByteStringCid);
+}
+
+
+void Intrinsifier::TwoByteString_equality(Assembler* assembler) {
+  StringEquality(assembler, kTwoByteStringCid);
+}
+
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 239fcd4..c334b91 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -1735,6 +1735,73 @@
   __ Bind(&fall_through);
 }
 
+
+// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
+void StringEquality(Assembler* assembler, intptr_t string_cid) {
+  Label fall_through, is_true, is_false, loop;
+  __ movl(EAX, Address(ESP, + 2 * kWordSize));  // This.
+  __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Other.
+
+  // Are identical?
+  __ cmpl(EAX, EBX);
+  __ j(EQUAL, &is_true, Assembler::kNearJump);
+
+  // Is other OneByteString?
+  __ testl(EBX, Immediate(kSmiTagMask));
+  __ j(ZERO, &is_false);  // Smi
+  __ CompareClassId(EBX, string_cid, EDI);
+  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
+
+  // Have same length?
+  __ movl(EDI, FieldAddress(EAX, String::length_offset()));
+  __ cmpl(EDI, FieldAddress(EBX, String::length_offset()));
+  __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
+
+  // Check contents, no fall-through possible.
+  // TODO(srdjan): write a faster check.
+  __ SmiUntag(EDI);
+  __ Bind(&loop);
+  __ decl(EDI);
+  __ cmpl(EDI, Immediate(0));
+  __ j(LESS, &is_true, Assembler::kNearJump);
+  if (string_cid == kOneByteStringCid) {
+    __ movzxb(ECX,
+        FieldAddress(EAX, EDI, TIMES_1, OneByteString::data_offset()));
+    __ movzxb(EDX,
+        FieldAddress(EBX, EDI, TIMES_1, OneByteString::data_offset()));
+  } else if (string_cid == kTwoByteStringCid) {
+    __ movzxw(ECX,
+        FieldAddress(EAX, EDI, TIMES_2, TwoByteString::data_offset()));
+    __ movzxw(EDX,
+        FieldAddress(EBX, EDI, TIMES_2, TwoByteString::data_offset()));
+  } else {
+    UNIMPLEMENTED();
+  }
+  __ cmpl(ECX, EDX);
+  __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
+  __ jmp(&loop, Assembler::kNearJump);
+
+  __ Bind(&is_true);
+  __ LoadObject(EAX, Bool::True());
+  __ ret();
+
+  __ Bind(&is_false);
+  __ LoadObject(EAX, Bool::False());
+  __ ret();
+
+  __ Bind(&fall_through);
+}
+
+
+void Intrinsifier::OneByteString_equality(Assembler* assembler) {
+  StringEquality(assembler, kOneByteStringCid);
+}
+
+
+void Intrinsifier::TwoByteString_equality(Assembler* assembler) {
+  StringEquality(assembler, kTwoByteStringCid);
+}
+
 #undef __
 }  // namespace dart
 
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index 0f6a92a..d150f52 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -1737,6 +1737,70 @@
   __ Bind(&fall_through);
 }
 
+
+// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
+void StringEquality(Assembler* assembler, intptr_t string_cid) {
+  Label fall_through, is_true, is_false, loop;
+  __ lw(T0, Address(SP, 1 * kWordSize));  // This.
+  __ lw(T1, Address(SP, 0 * kWordSize));  // Other.
+
+  // Are identical?
+  __ beq(T0, T1, &is_true);
+
+  // Is other OneByteString?
+  __ andi(CMPRES, T1, Immediate(kSmiTagMask));
+  __ beq(CMPRES, ZR, &fall_through);  // Other is Smi.
+  __ LoadClassId(CMPRES1, T1);  // Class ID check.
+  __ BranchNotEqual(CMPRES1, string_cid, &fall_through);
+
+  // Have same length?
+  __ lw(T2, FieldAddress(T0, String::length_offset()));
+  __ lw(T3, FieldAddress(T1, String::length_offset()));
+  __ bne(T2, T3, &is_false);
+
+  // Check contents, no fall-through possible.
+  ASSERT((string_cid == kOneByteStringCid) ||
+         (string_cid == kTwoByteStringCid));
+  __ SmiUntag(T2);
+  __ Bind(&loop);
+  __ AddImmediate(T2, -1);
+  __ BranchSignedLess(T2, 0, &is_true);
+  if (string_cid == kOneByteStringCid) {
+    __ lbu(V0, FieldAddress(T0, OneByteString::data_offset()));
+    __ lbu(V1, FieldAddress(T1, OneByteString::data_offset()));
+    __ AddImmediate(T0, 1);
+    __ AddImmediate(T1, 1);
+  } else if (string_cid == kTwoByteStringCid) {
+    __ lhu(V0, FieldAddress(T0, OneByteString::data_offset()));
+    __ lhu(V1, FieldAddress(T1, OneByteString::data_offset()));
+    __ AddImmediate(T0, 2);
+    __ AddImmediate(T1, 2);
+  } else {
+    UNIMPLEMENTED();
+  }
+  __ bne(V0, V1, &is_false);
+  __ b(&loop);
+
+  __ Bind(&is_false);
+  __ LoadObject(V0, Bool::False());
+  __ Ret();
+  __ Bind(&is_true);
+  __ LoadObject(V0, Bool::True());
+  __ Ret();
+
+  __ Bind(&fall_through);
+}
+
+
+void Intrinsifier::OneByteString_equality(Assembler* assembler) {
+  StringEquality(assembler, kOneByteStringCid);
+}
+
+
+void Intrinsifier::TwoByteString_equality(Assembler* assembler) {
+  StringEquality(assembler, kTwoByteStringCid);
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index e976fd5..62b2f5c 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -1647,6 +1647,72 @@
 }
 
 
+// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
+void StringEquality(Assembler* assembler, intptr_t string_cid) {
+  Label fall_through, is_true, is_false, loop;
+  __ movq(RAX, Address(RSP, + 2 * kWordSize));  // This.
+  __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Other.
+
+  // Are identical?
+  __ cmpq(RAX, RCX);
+  __ j(EQUAL, &is_true, Assembler::kNearJump);
+
+  // Is other OneByteString?
+  __ testq(RCX, Immediate(kSmiTagMask));
+  __ j(ZERO, &is_false);  // Smi
+  __ CompareClassId(RCX, string_cid);
+  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
+
+  // Have same length?
+  __ movq(RDI, FieldAddress(RAX, String::length_offset()));
+  __ cmpq(RDI, FieldAddress(RCX, String::length_offset()));
+  __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
+
+  // Check contents, no fall-through possible.
+  // TODO(srdjan): write a faster check.
+  __ SmiUntag(RDI);
+  __ Bind(&loop);
+  __ decq(RDI);
+  __ cmpq(RDI, Immediate(0));
+  __ j(LESS, &is_true, Assembler::kNearJump);
+  if (string_cid == kOneByteStringCid) {
+    __ movzxb(RBX,
+        FieldAddress(RAX, RDI, TIMES_1, OneByteString::data_offset()));
+    __ movzxb(RDX,
+        FieldAddress(RCX, RDI, TIMES_1, OneByteString::data_offset()));
+  } else if (string_cid == kTwoByteStringCid) {
+    __ movzxw(RBX,
+        FieldAddress(RAX, RDI, TIMES_2, TwoByteString::data_offset()));
+    __ movzxw(RDX,
+        FieldAddress(RCX, RDI, TIMES_2, TwoByteString::data_offset()));
+  } else {
+    UNIMPLEMENTED();
+  }
+  __ cmpq(RBX, RDX);
+  __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
+  __ jmp(&loop, Assembler::kNearJump);
+
+  __ Bind(&is_true);
+  __ LoadObject(RAX, Bool::True(), PP);
+  __ ret();
+
+  __ Bind(&is_false);
+  __ LoadObject(RAX, Bool::False(), PP);
+  __ ret();
+
+  __ Bind(&fall_through);
+}
+
+
+void Intrinsifier::OneByteString_equality(Assembler* assembler) {
+  StringEquality(assembler, kOneByteStringCid);
+}
+
+
+void Intrinsifier::TwoByteString_equality(Assembler* assembler) {
+  StringEquality(assembler, kTwoByteStringCid);
+}
+
 #undef __
 
 }  // namespace dart
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index d8ab9a5..cecc088 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -510,6 +510,7 @@
 
     Object& result = Object::Handle();
     result = state->ResolveFunction();
+    bool is_spawn_uri = state->is_spawn_uri();
     delete state;
     state = NULL;
     if (result.IsError()) {
@@ -519,7 +520,31 @@
     ASSERT(result.IsFunction());
     Function& func = Function::Handle(isolate);
     func ^= result.raw();
-    result = DartEntry::InvokeFunction(func, Object::empty_array());
+    func = func.ImplicitClosureFunction();
+
+    // Instead of directly invoking the entry point we call '_startIsolate' with
+    // the entry point as argument. The '_startIsolate' function will
+    // communicate with the spawner to receive the initial message before it
+    // executes the real entry point.
+    // Since this function ("RunIsolate") is used for both Isolate.spawn and
+    // Isolate.spawnUri we also send a boolean flag as argument so that the
+    // "_startIsolate" function can act corresponding to how the isolate was
+    // created.
+    const Array& args = Array::Handle(Array::New(2));
+    args.SetAt(0, Instance::Handle(func.ImplicitStaticClosure()));
+    args.SetAt(1, is_spawn_uri ? Bool::True() : Bool::False());
+
+    // Dispatching through _startIsolate will open a control port as a live
+    // port. Account for this by increasing the number of open control ports.
+    isolate->message_handler()->increment_control_ports();
+
+    const Library& lib = Library::Handle(Library::IsolateLibrary());
+    const String& entry_name = String::Handle(String::New("_startIsolate"));
+    const Function& entry_point =
+        Function::Handle(lib.LookupLocalFunction(entry_name));
+    ASSERT(entry_point.IsFunction() && !entry_point.IsNull());
+
+    result = DartEntry::InvokeFunction(entry_point, args);
     if (result.IsError()) {
       StoreError(isolate, result);
       return false;
@@ -968,23 +993,13 @@
 }
 
 
-static char* GetRootScriptUri(Isolate* isolate) {
-  const Library& library =
-      Library::Handle(isolate->object_store()->root_library());
-  ASSERT(!library.IsNull());
-  const String& script_name = String::Handle(library.url());
-  return isolate->current_zone()->MakeCopyOfString(script_name.ToCString());
-}
-
-
-IsolateSpawnState::IsolateSpawnState(const Function& func,
-                                     const Function& callback_func)
+IsolateSpawnState::IsolateSpawnState(const Function& func)
     : isolate_(NULL),
       script_url_(NULL),
       library_url_(NULL),
       function_name_(NULL),
       exception_callback_name_(NULL) {
-  script_url_ = strdup(GetRootScriptUri(Isolate::Current()));
+  script_url_ = NULL;
   const Class& cls = Class::Handle(func.Owner());
   ASSERT(cls.IsTopLevel());
   const Library& lib = Library::Handle(cls.library());
@@ -993,12 +1008,7 @@
 
   const String& func_name = String::Handle(func.name());
   function_name_ = strdup(func_name.ToCString());
-  if (!callback_func.IsNull()) {
-    const String& callback_name = String::Handle(callback_func.name());
-    exception_callback_name_ = strdup(callback_name.ToCString());
-  } else {
-    exception_callback_name_ = strdup("_unhandledExceptionCallback");
-  }
+  exception_callback_name_ = strdup("_unhandledExceptionCallback");
 }
 
 
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 128f7e2..f42247e 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -512,7 +512,7 @@
 
 class IsolateSpawnState {
  public:
-  IsolateSpawnState(const Function& func, const Function& callback_func);
+  explicit IsolateSpawnState(const Function& func);
   explicit IsolateSpawnState(const char* script_url);
   ~IsolateSpawnState();
 
@@ -522,6 +522,7 @@
   char* library_url() const { return library_url_; }
   char* function_name() const { return function_name_; }
   char* exception_callback_name() const { return exception_callback_name_; }
+  bool is_spawn_uri() const { return library_url_ == NULL; }
 
   RawObject* ResolveFunction();
   void Cleanup();
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc
index 6565d38..2af007e 100644
--- a/runtime/vm/isolate_test.cc
+++ b/runtime/vm/isolate_test.cc
@@ -23,10 +23,10 @@
 TEST_CASE(IsolateSpawn) {
   const char* kScriptChars =
       "import 'dart:isolate';\n"
-      "void entry() {}\n"
+      "void entry(message) {}\n"
       "int testMain() {\n"
       "  try {\n"
-      "    spawnFunction(entry);\n"
+      "    Isolate.spawn(entry, null);\n"
       "  } catch (e) {\n"
       "    rethrow;\n"
       "  }\n"
diff --git a/runtime/vm/locations.cc b/runtime/vm/locations.cc
index fb19c1f..265b198 100644
--- a/runtime/vm/locations.cc
+++ b/runtime/vm/locations.cc
@@ -12,6 +12,17 @@
 
 namespace dart {
 
+intptr_t RegisterSet::RegisterCount(intptr_t registers) {
+  // Brian Kernighan's algorithm for counting the bits set.
+  intptr_t count = 0;
+  while (registers != 0) {
+    ++count;
+    registers &= (registers - 1);  // Clear the least significant bit set.
+  }
+  return count;
+}
+
+
 LocationSummary::LocationSummary(intptr_t input_count,
                                  intptr_t temp_count,
                                  LocationSummary::ContainsCall contains_call)
diff --git a/runtime/vm/locations.h b/runtime/vm/locations.h
index 24bf0a0..8e34046 100644
--- a/runtime/vm/locations.h
+++ b/runtime/vm/locations.h
@@ -368,15 +368,10 @@
     return (fpu_registers_ & (1 << fpu_reg)) != 0;
   }
 
-  intptr_t fpu_regs_count() const {
-    intptr_t count = 0;
-    for (intptr_t reg_idx = 0; reg_idx < kNumberOfFpuRegisters; reg_idx++) {
-      if (ContainsFpuRegister(static_cast<FpuRegister>(reg_idx))) {
-        count++;
-      }
-    }
-    return count;
-  }
+  intptr_t CpuRegisterCount() const { return RegisterCount(cpu_registers_); }
+  intptr_t FpuRegisterCount() const { return RegisterCount(fpu_registers_); }
+
+  static intptr_t RegisterCount(intptr_t registers);
 
   intptr_t cpu_registers() const { return cpu_registers_; }
   intptr_t fpu_registers() const { return fpu_registers_; }
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index f5c068e..a1df2a8 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -32,6 +32,7 @@
 MessageHandler::MessageHandler()
     : queue_(new MessageQueue()),
       oob_queue_(new MessageQueue()),
+      control_ports_(0),
       live_ports_(0),
       pool_(NULL),
       task_(NULL),
@@ -269,4 +270,22 @@
   live_ports_--;
 }
 
+
+void MessageHandler::increment_control_ports() {
+  MonitorLocker ml(&monitor_);
+#if defined(DEBUG)
+  CheckAccess();
+#endif
+  control_ports_++;
+}
+
+
+void MessageHandler::decrement_control_ports() {
+  MonitorLocker ml(&monitor_);
+#if defined(DEBUG)
+  CheckAccess();
+#endif
+  control_ports_--;
+}
+
 }  // namespace dart
diff --git a/runtime/vm/message_handler.h b/runtime/vm/message_handler.h
index 26335cd..f7707aa 100644
--- a/runtime/vm/message_handler.h
+++ b/runtime/vm/message_handler.h
@@ -53,8 +53,15 @@
   // Returns true on success.
   bool HandleOOBMessages();
 
+  // The number of opened control ports is determined whether the isolate has
+  // live ports. An isolate is considered not having any live ports if only
+  // control ports are open.
+  // Usually either 0 or 1.
+  void increment_control_ports();
+  void decrement_control_ports();
+
   // A message handler tracks how many live ports it has.
-  bool HasLivePorts() const { return live_ports_ > 0; }
+  bool HasLivePorts() const { return live_ports_ > control_ports_; }
 
 #if defined(DEBUG)
   // Check that it is safe to access this message handler.
@@ -120,7 +127,8 @@
   Monitor monitor_;  // Protects all fields in MessageHandler.
   MessageQueue* queue_;
   MessageQueue* oob_queue_;
-  intptr_t live_ports_;
+  intptr_t control_ports_;  // The number of open control ports usually 0 or 1.
+  intptr_t live_ports_;  // The number of open ports, including control ports.
   ThreadPool* pool_;
   ThreadPool::Task* task_;
   StartCallback start_callback_;
diff --git a/runtime/vm/mirrors_api_impl.cc b/runtime/vm/mirrors_api_impl.cc
index caa1346..af7c096 100644
--- a/runtime/vm/mirrors_api_impl.cc
+++ b/runtime/vm/mirrors_api_impl.cc
@@ -323,6 +323,19 @@
   return Api::NewHandle(isolate, name.raw());
 }
 
+DART_EXPORT Dart_Handle Dart_LibraryId(Dart_Handle library,
+                                       intptr_t* library_id) {
+  Isolate* isolate = Isolate::Current();
+  DARTSCOPE(isolate);
+  const Library& lib = Api::UnwrapLibraryHandle(isolate, library);
+  if (lib.IsNull()) {
+    RETURN_TYPE_ERROR(isolate, library, Library);
+  }
+  if (library_id != NULL) {
+    *library_id = lib.index();
+  }
+  return Api::Success();
+}
 
 DART_EXPORT Dart_Handle Dart_LibraryGetClassNames(Dart_Handle library) {
   Isolate* isolate = Isolate::Current();
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 65fb850..314f142 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2610,7 +2610,6 @@
 
 
 void Class::set_mixin(const Type& value) const {
-  // Resolution and application of mixin type occurs in finalizer.
   ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->mixin_, value.raw());
 }
@@ -2620,6 +2619,9 @@
   return mixin() != Type::null();
 }
 
+bool Class::IsAnonymousMixinApplication() const {
+  return IsMixinApplication() && !is_mixin_typedef();
+}
 
 void Class::set_patch_class(const Class& cls) const {
   ASSERT(patch_class() == Class::null());
@@ -4039,6 +4041,22 @@
 }
 
 
+void Function::DetachCode() const {
+  // Set unoptimized code as non-entrant, and set code and unoptimized code
+  // to null.
+  CodePatcher::PatchEntry(Code::Handle(unoptimized_code()));
+  StorePointer(&raw_ptr()->code_, Code::null());
+  StorePointer(&raw_ptr()->unoptimized_code_, Code::null());
+}
+
+
+void Function::ReattachCode(const Code& code) const {
+  set_unoptimized_code(code);
+  SetCode(code);
+  CodePatcher::RestoreEntry(code);
+}
+
+
 void Function::SwitchToUnoptimizedCode() const {
   ASSERT(HasOptimizedCode());
 
@@ -4047,7 +4065,7 @@
   // Optimized code object might have been actually fully produced by the
   // intrinsifier in this case nothing has to be done. In fact an attempt to
   // patch such code will cause crash.
-  // TODO(vegorov): if intrisifier can fully intrisify the function then we
+  // TODO(vegorov): if intrisifier can fully intrinsify the function then we
   // should not later try to optimize it.
   if (PcDescriptors::Handle(current_code.pc_descriptors()).Length() == 0) {
     return;
@@ -4067,6 +4085,7 @@
 
 
 void Function::set_unoptimized_code(const Code& value) const {
+  ASSERT(!value.is_optimized());
   StorePointer(&raw_ptr()->unoptimized_code_, value.raw());
 }
 
@@ -7893,11 +7912,6 @@
 }
 
 
-RawLibrary* Library::JsonLibrary() {
-  return Isolate::Current()->object_store()->json_library();
-}
-
-
 RawLibrary* Library::MathLibrary() {
   return Isolate::Current()->object_store()->math_library();
 }
@@ -7912,6 +7926,10 @@
   return Isolate::Current()->object_store()->native_wrappers_library();
 }
 
+RawLibrary* Library::PlatformLibrary() {
+  return Isolate::Current()->object_store()->platform_library();
+}
+
 
 RawLibrary* Library::TypedDataLibrary() {
   return Isolate::Current()->object_store()->typed_data_library();
@@ -9260,6 +9278,19 @@
 }
 
 
+RawCode* Code::GetStaticCallTargetCodeAt(uword pc) const {
+  const intptr_t i = BinarySearchInSCallTable(pc);
+  if (i < 0) {
+    return Code::null();
+  }
+  const Array& array =
+      Array::Handle(raw_ptr()->static_calls_target_table_);
+  Code& code = Code::Handle();
+  code ^= array.At(i + kSCallTableCodeEntry);
+  return code.raw();
+}
+
+
 void Code::SetStaticCallTargetCodeAt(uword pc, const Code& code) const {
   const intptr_t i = BinarySearchInSCallTable(pc);
   ASSERT(i >= 0);
@@ -12205,13 +12236,12 @@
 
 
 intptr_t MixinAppType::token_pos() const {
-  return Class::Handle(MixinAppAt(0)).token_pos();
+  return AbstractType::Handle(MixinTypeAt(0)).token_pos();
 }
 
 
 intptr_t MixinAppType::Depth() const {
-  const Array& mixin_apps = Array::Handle(mixins());
-  return mixin_apps.Length();
+  return Array::Handle(mixin_types()).Length();
 }
 
 
@@ -12221,15 +12251,15 @@
 
 
 const char* MixinAppType::ToCString() const {
-  const char* format = "MixinAppType: super type: %s; first mixin app: %s";
+  const char* format = "MixinAppType: super type: %s; first mixin type: %s";
   const char* super_type_cstr = String::Handle(AbstractType::Handle(
-      SuperType()).Name()).ToCString();
-  const char* first_mixin_app_cstr = String::Handle(Class::Handle(
-      MixinAppAt(0)).Name()).ToCString();
+      super_type()).Name()).ToCString();
+  const char* first_mixin_type_cstr = String::Handle(AbstractType::Handle(
+      MixinTypeAt(0)).Name()).ToCString();
   intptr_t len = OS::SNPrint(
-      NULL, 0, format, super_type_cstr, first_mixin_app_cstr) + 1;
+      NULL, 0, format, super_type_cstr, first_mixin_type_cstr) + 1;
   char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
-  OS::SNPrint(chars, len, format, super_type_cstr, first_mixin_app_cstr);
+  OS::SNPrint(chars, len, format, super_type_cstr, first_mixin_type_cstr);
   return chars;
 }
 
@@ -12239,18 +12269,18 @@
 }
 
 
-RawAbstractType* MixinAppType::SuperType() const {
-  return Class::Handle(MixinAppAt(0)).super_type();
+RawAbstractType* MixinAppType::MixinTypeAt(intptr_t depth) const {
+  return AbstractType::RawCast(Array::Handle(mixin_types()).At(depth));
 }
 
 
-RawClass* MixinAppType::MixinAppAt(intptr_t depth) const {
-  return Class::RawCast(Array::Handle(mixins()).At(depth));
+void MixinAppType::set_super_type(const AbstractType& value) const {
+  StorePointer(&raw_ptr()->super_type_, value.raw());
 }
 
 
-void MixinAppType::set_mixins(const Array& value) const {
-  StorePointer(&raw_ptr()->mixins_, value.raw());
+void MixinAppType::set_mixin_types(const Array& value) const {
+  StorePointer(&raw_ptr()->mixin_types_, value.raw());
 }
 
 
@@ -12266,9 +12296,11 @@
 }
 
 
-RawMixinAppType* MixinAppType::New(const Array& mixins) {
+RawMixinAppType* MixinAppType::New(const AbstractType& super_type,
+                                   const Array& mixin_types) {
   const MixinAppType& result = MixinAppType::Handle(MixinAppType::New());
-  result.set_mixins(mixins);
+  result.set_super_type(super_type);
+  result.set_mixin_types(mixin_types);
   return result.raw();
 }
 
@@ -15241,19 +15273,19 @@
 
 RawString* Stacktrace::FullStacktrace() const {
   const Array& code_array = Array::Handle(raw_ptr()->catch_code_array_);
+  intptr_t idx = 0;
   if (!code_array.IsNull() && (code_array.Length() > 0)) {
     const Array& pc_offset_array =
         Array::Handle(raw_ptr()->catch_pc_offset_array_);
     const Stacktrace& catch_trace = Stacktrace::Handle(
         Stacktrace::New(code_array, pc_offset_array));
-    intptr_t idx = Length();
-    const String& trace =
-        String::Handle(String::New(catch_trace.ToCStringInternal(idx)));
-    const String& throw_trace =
-        String::Handle(String::New(ToCStringInternal(0)));
-    return String::Concat(throw_trace, trace);
+    const String& throw_string =
+        String::Handle(String::New(ToCStringInternal(&idx)));
+    const String& catch_string =
+        String::Handle(String::New(catch_trace.ToCStringInternal(&idx)));
+    return String::Concat(throw_string, catch_string);
   }
-  return String::New(ToCStringInternal(0));
+  return String::New(ToCStringInternal(&idx));
 }
 
 
@@ -15315,7 +15347,7 @@
 }
 
 
-const char* Stacktrace::ToCStringInternal(intptr_t frame_index) const {
+const char* Stacktrace::ToCStringInternal(intptr_t* frame_index) const {
   Isolate* isolate = Isolate::Current();
   Function& function = Function::Handle();
   Code& code = Code::Handle();
@@ -15323,7 +15355,6 @@
   // for each frame.
   intptr_t total_len = 0;
   GrowableArray<char*> frame_strings;
-  intptr_t current_frame_index = frame_index;
   for (intptr_t i = 0; i < Length(); i++) {
     function = FunctionAtFrame(i);
     if (function.IsNull()) {
@@ -15351,13 +15382,13 @@
           ASSERT(code.EntryPoint() <= pc);
           ASSERT(pc < (code.EntryPoint() + code.Size()));
           total_len += PrintOneStacktrace(
-              isolate, &frame_strings, pc, function, code, current_frame_index);
-          current_frame_index++;  // To account for inlined frames.
+              isolate, &frame_strings, pc, function, code, *frame_index);
+          (*frame_index)++;  // To account for inlined frames.
         }
       } else {
         total_len += PrintOneStacktrace(
-            isolate, &frame_strings, pc, function, code, current_frame_index);
-        current_frame_index++;
+            isolate, &frame_strings, pc, function, code, *frame_index);
+        (*frame_index)++;
       }
     }
   }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 53c0563..d477a41 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -785,6 +785,7 @@
   void set_mixin(const Type& value) const;
 
   bool IsMixinApplication() const;
+  bool IsAnonymousMixinApplication() const;
 
   RawClass* patch_class() const {
     return raw_ptr()->patch_class_;
@@ -1477,6 +1478,13 @@
   // Sets function's code and code's function.
   void SetCode(const Code& value) const;
 
+  // Detaches code from the function by setting the code to null, and patches
+  // the code to be non-entrant.
+  void DetachCode() const;
+
+  // Reattaches code to the function, and patches the code to be entrant.
+  void ReattachCode(const Code& code) const;
+
   // Disables optimized code and switches to unoptimized code.
   void SwitchToUnoptimizedCode() const;
 
@@ -1487,6 +1495,9 @@
   RawCode* unoptimized_code() const { return raw_ptr()->unoptimized_code_; }
   void set_unoptimized_code(const Code& value) const;
   static intptr_t code_offset() { return OFFSET_OF(RawFunction, code_); }
+  static intptr_t unoptimized_code_offset() {
+    return OFFSET_OF(RawFunction, unoptimized_code_);
+  }
   inline bool HasCode() const;
 
   // Returns true if there is at least one debugger breakpoint
@@ -2529,10 +2540,10 @@
   static RawLibrary* CollectionLibrary();
   static RawLibrary* CollectionDevLibrary();
   static RawLibrary* IsolateLibrary();
-  static RawLibrary* JsonLibrary();
   static RawLibrary* MathLibrary();
   static RawLibrary* MirrorsLibrary();
   static RawLibrary* NativeWrappersLibrary();
+  static RawLibrary* PlatformLibrary();
   static RawLibrary* TypedDataLibrary();
   static RawLibrary* UtfLibrary();
 
@@ -2658,6 +2669,9 @@
  public:
   intptr_t size() const { return raw_ptr()->size_; }  // Excludes HeaderSize().
   RawCode* code() const { return raw_ptr()->code_; }
+  static intptr_t code_offset() {
+    return OFFSET_OF(RawInstructions, code_);
+  }
   RawArray* object_pool() const { return raw_ptr()->object_pool_; }
   static intptr_t object_pool_offset() {
     return OFFSET_OF(RawInstructions, object_pool_);
@@ -3120,6 +3134,8 @@
 
   // Returns null if there is no static call at 'pc'.
   RawFunction* GetStaticCallTargetFunctionAt(uword pc) const;
+  // Returns null if there is no static call at 'pc'.
+  RawCode* GetStaticCallTargetCodeAt(uword pc) const;
   // Aborts if there is no static call at 'pc'.
   void SetStaticCallTargetCodeAt(uword pc, const Code& code) const;
 
@@ -4269,15 +4285,16 @@
 };
 
 
-// A MixinAppType represents a mixin application clause, e.g.
-// "S<T> with M<U>, N<V>". The class finalizer builds the type
-// parameters and arguments at finalization time.
+// A MixinAppType represents a parsed mixin application clause, e.g.
+// "S<T> with M<U>, N<V>".
 // MixinAppType objects do not survive finalization, so they do not
 // need to be written to and read from snapshots.
+// The class finalizer creates synthesized classes S&M and S&M&N if they do not
+// yet exist in the library declaring the mixin application clause.
 class MixinAppType : public AbstractType {
  public:
-  // A MixinAppType object is replaced at class finalization time with a
-  // finalized Type or BoundedType object.
+  // A MixinAppType object is unfinalized by definition, since it is replaced at
+  // class finalization time with a finalized Type or BoundedType object.
   virtual bool IsFinalized() const { return false; }
   // TODO(regis): Handle malformed and malbounded MixinAppType.
   virtual bool IsMalformed() const { return false; }
@@ -4290,27 +4307,27 @@
   // Returns the mixin composition depth of this mixin application type.
   intptr_t Depth() const;
 
-  // Returns the declared super type of the mixin application, which is also
-  // the super type of the first synthesized class, e.g. "S&M" refers to
-  // super type "S<T>".
-  RawAbstractType* SuperType() const;
+  // Returns the declared super type of the mixin application, which will also
+  // be the super type of the first synthesized class, e.g. class "S&M" will
+  // refer to super type "S<T>".
+  RawAbstractType* super_type() const { return raw_ptr()->super_type_; }
 
-  // Returns the synthesized class representing the mixin application at
-  // the given mixin composition depth, e.g. class "S&M" at depth 0, class
-  // "S&M&N" at depth 1.
-  // Each class refers to its mixin type, e.g. "S&M" refers to mixin type "M<U>"
-  // and "S&M&N" refers to mixin type "N<V>".
-  RawClass* MixinAppAt(intptr_t depth) const;
+  // Returns the mixin type at the given mixin composition depth, e.g. N<V> at
+  // depth 0 and M<U> at depth 1.
+  RawAbstractType* MixinTypeAt(intptr_t depth) const;
 
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawMixinAppType));
   }
 
-  static RawMixinAppType* New(const Array& mixins);
+  static RawMixinAppType* New(const AbstractType& super_type,
+                              const Array& mixin_types);
 
  private:
-  RawArray* mixins() const { return raw_ptr()->mixins_; }
-  void set_mixins(const Array& value) const;
+  void set_super_type(const AbstractType& value) const;
+
+  RawArray* mixin_types() const { return raw_ptr()->mixin_types_; }
+  void set_mixin_types(const Array& value) const;
 
   static RawMixinAppType* New();
 
@@ -5998,7 +6015,7 @@
                             Heap::Space space = Heap::kNew);
 
   RawString* FullStacktrace() const;
-  const char* ToCStringInternal(intptr_t frame_index) const;
+  const char* ToCStringInternal(intptr_t* frame_index) const;
 
  private:
   void set_code_array(const Array& code_array) const;
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index ce35ea8..8ea5ed7 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -54,7 +54,6 @@
     builtin_library_(Library::null()),
     core_library_(Library::null()),
     isolate_library_(Library::null()),
-    json_library_(Library::null()),
     math_library_(Library::null()),
     mirrors_library_(Library::null()),
     native_wrappers_library_(Library::null()),
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index eb07bf5..d131951 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -27,9 +27,9 @@
     kCollectionDev,
     kConvert,
     kIsolate,
-    kJson,
     kMath,
     kMirrors,
+    kPlatform,
     kTypedData,
     kUtf,
   };
@@ -277,9 +277,9 @@
   }
   RawLibrary* convert_library() const { return convert_library_; }
   RawLibrary* isolate_library() const { return isolate_library_; }
-  RawLibrary* json_library() const { return json_library_; }
   RawLibrary* math_library() const { return math_library_; }
   RawLibrary* mirrors_library() const { return mirrors_library_; }
+  RawLibrary* platform_library() const { return platform_library_; }
   RawLibrary* typed_data_library() const { return typed_data_library_; }
   RawLibrary* utf_library() const { return utf_library_; }
   void set_bootstrap_library(BootstrapLibraryId index, const Library& value) {
@@ -302,15 +302,15 @@
       case kIsolate:
         isolate_library_ = value.raw();
         break;
-      case kJson:
-        json_library_ = value.raw();
-        break;
       case kMath:
         math_library_ = value.raw();
         break;
       case kMirrors:
         mirrors_library_ = value.raw();
         break;
+      case kPlatform:
+        platform_library_ = value.raw();
+        break;
       case kTypedData:
         typed_data_library_ = value.raw();
         break;
@@ -480,10 +480,10 @@
   RawLibrary* collection_dev_library_;
   RawLibrary* convert_library_;
   RawLibrary* isolate_library_;
-  RawLibrary* json_library_;
   RawLibrary* math_library_;
   RawLibrary* mirrors_library_;
   RawLibrary* native_wrappers_library_;
+  RawLibrary* platform_library_;
   RawLibrary* root_library_;
   RawLibrary* typed_data_library_;
   RawLibrary* utf_library_;
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 2e82fcd..c9b1539 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -23,6 +23,12 @@
             "Print free list statistics before a GC");
 DEFINE_FLAG(bool, print_free_list_after_gc, false,
             "Print free list statistics after a GC");
+DEFINE_FLAG(bool, collect_code, true,
+            "Attempt to GC infrequently used code.");
+DEFINE_FLAG(int, code_collection_interval_in_us, 30000000,
+            "Time between attempts to collect unused code.");
+DEFINE_FLAG(bool, log_code_drop, false,
+            "Emit a log message when pointers to unused code are dropped.");
 
 HeapPage* HeapPage::Initialize(VirtualMemory* memory, PageType type) {
   ASSERT(memory->size() > VirtualMemory::PageSize());
@@ -378,11 +384,68 @@
 }
 
 
+
+class CodeDetacherVisitor : public ObjectVisitor {
+ public:
+  explicit CodeDetacherVisitor(Isolate* isolate) : ObjectVisitor(isolate) { }
+
+  virtual void VisitObject(RawObject* obj);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CodeDetacherVisitor);
+};
+
+
+void CodeDetacherVisitor::VisitObject(RawObject* raw_obj) {
+  Isolate* isolate = Isolate::Current();
+  HANDLESCOPE(isolate);
+  const Object& obj = Object::Handle(raw_obj);
+  if (obj.GetClassId() == kFunctionCid) {
+    const Function& fn = Function::Cast(obj);
+    if (!fn.HasOptimizedCode() &&
+        !fn.HasBreakpoint() &&
+        fn.HasCode() &&  // Not already detached.
+        (fn.usage_counter() > 0)) {
+      fn.set_usage_counter(fn.usage_counter() / 2);
+      if (fn.usage_counter() == 0) {
+        if (FLAG_log_code_drop) {
+          const String& name = String::Handle(fn.name());
+          OS::Print("Detaching code for function %s\n", name.ToCString());
+        }
+        fn.DetachCode();
+      }
+    }
+  }
+}
+
+
+void PageSpace::TryDetachingCode() {
+  // Try to collect code if enough time has passed since the last attempt.
+  const int64_t start = OS::GetCurrentTimeMicros();
+  const int64_t last_code_collection_in_us =
+      page_space_controller_.last_code_collection_in_us();
+  if ((start - last_code_collection_in_us) >
+       FLAG_code_collection_interval_in_us) {
+    if (FLAG_log_code_drop) {
+      OS::Print("Trying to detach code.\n");
+    }
+    Isolate* isolate = Isolate::Current();
+    CodeDetacherVisitor code_detacher(isolate);
+    heap_->IterateObjects(&code_detacher);
+    page_space_controller_.set_last_code_collection_in_us(start);
+  }
+}
+
+
 void PageSpace::MarkSweep(bool invoke_api_callbacks) {
   // MarkSweep is not reentrant. Make sure that is the case.
   ASSERT(!sweeping_);
   sweeping_ = true;
   Isolate* isolate = Isolate::Current();
+  if (FLAG_collect_code) {
+    TryDetachingCode();
+  }
+
   NoHandleScope no_handles(isolate);
 
   if (FLAG_print_free_list_before_gc) {
@@ -398,7 +461,7 @@
     OS::PrintErr(" done.\n");
   }
 
-  int64_t start = OS::GetCurrentTimeMicros();
+  const int64_t start = OS::GetCurrentTimeMicros();
 
   // Mark all reachable old-gen objects.
   GCMarker marker(heap_);
@@ -490,7 +553,8 @@
       heap_growth_ratio_(heap_growth_ratio),
       desired_utilization_((100.0 - heap_growth_ratio) / 100.0),
       heap_growth_rate_(heap_growth_rate),
-      garbage_collection_time_ratio_(garbage_collection_time_ratio) {
+      garbage_collection_time_ratio_(garbage_collection_time_ratio),
+      last_code_collection_in_us_(OS::GetCurrentTimeMicros()) {
 }
 
 
diff --git a/runtime/vm/pages.h b/runtime/vm/pages.h
index c29121b..7543e3b 100644
--- a/runtime/vm/pages.h
+++ b/runtime/vm/pages.h
@@ -11,6 +11,9 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, collect_code);
+DECLARE_FLAG(bool, log_code_drop);
+
 // Forward declarations.
 class Heap;
 class ObjectPointerVisitor;
@@ -121,6 +124,11 @@
   void EvaluateGarbageCollection(intptr_t in_use_before, intptr_t in_use_after,
                                  int64_t start, int64_t end);
 
+  int64_t last_code_collection_in_us() { return last_code_collection_in_us_; }
+  void set_last_code_collection_in_us(int64_t t) {
+    last_code_collection_in_us_ = t;
+  }
+
   void set_is_enabled(bool state) {
     is_enabled_ = state;
   }
@@ -149,6 +157,10 @@
   // garbage collection can be performed.
   int garbage_collection_time_ratio_;
 
+  // The time in microseconds of the last time we tried to collect unused
+  // code.
+  int64_t last_code_collection_in_us_;
+
   PageSpaceGarbageCollectionHistory history_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpaceController);
@@ -188,6 +200,10 @@
   RawObject* FindObject(FindObjectVisitor* visitor,
                         HeapPage::PageType type) const;
 
+  // Runs a visitor that attempts to drop references to code that has not
+  // been run in awhile.
+  void TryDetachingCode();
+
   // Collect the garbage in the page space using mark-sweep.
   void MarkSweep(bool invoke_api_callbacks);
 
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index fbd1068..1801810 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -97,22 +97,6 @@
 }
 
 
-static ThrowNode* GenerateRethrow(intptr_t token_pos, const Object& obj) {
-  const UnhandledException& excp = UnhandledException::Cast(obj);
-  Instance& exception = Instance::ZoneHandle(excp.exception());
-  if (exception.IsNew()) {
-    exception ^= Object::Clone(exception, Heap::kOld);
-  }
-  Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace());
-  if (stack_trace.IsNew()) {
-    stack_trace ^= Object::Clone(stack_trace, Heap::kOld);
-  }
-  return new ThrowNode(token_pos,
-                       new LiteralNode(token_pos, exception),
-                       new LiteralNode(token_pos, stack_trace));
-}
-
-
 LocalVariable* ParsedFunction::EnsureExpressionTemp() {
   if (!has_expression_temp_var()) {
     LocalVariable* temp =
@@ -460,6 +444,7 @@
     num_optional_parameters = 0;
     has_optional_positional_parameters = false;
     has_optional_named_parameters = false;
+    has_explicit_default_values = false;
     has_field_initializer = false;
     implicitly_final = false;
     skipped = false;
@@ -505,6 +490,7 @@
   int num_optional_parameters;
   bool has_optional_positional_parameters;
   bool has_optional_named_parameters;
+  bool has_explicit_default_values;
   bool has_field_initializer;
   bool implicitly_final;
   bool skipped;
@@ -897,7 +883,7 @@
     if (expr->EvalConstExpr() == NULL) {
       ErrorMsg(expr_pos, "expression must be a compile-time constant");
     }
-    const Instance& val = EvaluateConstExpr(expr);
+    const Instance& val = EvaluateConstExpr(expr_pos, expr);
     meta_values.Add(val);
   }
   return Array::MakeArray(meta_values);
@@ -1494,6 +1480,7 @@
       ExpectToken(Token::kCOLON);
     }
     params->num_optional_parameters++;
+    params->has_explicit_default_values = true;  // Also if explicitly NULL.
     if (is_top_level_) {
       // Skip default value parsing.
       SkipExpr();
@@ -2128,13 +2115,15 @@
   ConsumeToken();
   ExpectToken(Token::kASSIGN);
   AstNode* init_expr = NULL;
+  intptr_t expr_pos = TokenPos();
   if (field.is_const()) {
     init_expr = ParseConstExpr();
   } else {
     init_expr = ParseExpr(kAllowConst, kConsumeCascades);
     if (init_expr->EvalConstExpr() != NULL) {
       init_expr =
-          new LiteralNode(field.token_pos(), EvaluateConstExpr(init_expr));
+          new LiteralNode(field.token_pos(),
+                          EvaluateConstExpr(expr_pos, init_expr));
     }
   }
   set_current_class(saved_class);
@@ -2173,10 +2162,11 @@
         if (field.is_const()) {
           init_expr = ParseConstExpr();
         } else {
+          intptr_t expr_pos = TokenPos();
           init_expr = ParseExpr(kAllowConst, kConsumeCascades);
           if (init_expr->EvalConstExpr() != NULL) {
             init_expr = new LiteralNode(field.token_pos(),
-                                        EvaluateConstExpr(init_expr));
+                                        EvaluateConstExpr(expr_pos, init_expr));
           }
         }
       }
@@ -3036,6 +3026,12 @@
   String& redirection_identifier = String::Handle();
   bool is_redirecting = false;
   if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) {
+    // Default parameter values are disallowed in redirecting factories.
+    if (method->params.has_explicit_default_values) {
+      ErrorMsg("redirecting factory '%s' may not specify default values "
+               "for optional parameters",
+               method->name->ToCString());
+    }
     ConsumeToken();
     const intptr_t type_pos = TokenPos();
     is_redirecting = true;
@@ -3766,7 +3762,7 @@
                String::Handle(super_type.UserVisibleName()).ToCString());
     }
     if (CurrentToken() == Token::kWITH) {
-      super_type = ParseMixins(pending_classes, super_type);
+      super_type = ParseMixins(super_type);
     }
     if (is_mixin_declaration) {
       cls.set_is_mixin_typedef();
@@ -3968,7 +3964,7 @@
   if (CurrentToken() != Token::kWITH) {
     ErrorMsg("mixin application 'with Type' expected");
   }
-  type = ParseMixins(pending_classes, type);
+  type = ParseMixins(type);
 
   mixin_application.set_super_type(type);
   mixin_application.set_is_synthesized_class();
@@ -4351,62 +4347,30 @@
 }
 
 
-RawAbstractType* Parser::ParseMixins(const GrowableObjectArray& pending_classes,
-                                     const AbstractType& super_type) {
+RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) {
   TRACE_PARSER("ParseMixins");
   ASSERT(CurrentToken() == Token::kWITH);
   ASSERT(super_type.IsType());  // TODO(regis): Could be a BoundedType.
-  AbstractType& mixin_super_type = AbstractType::Handle(super_type.raw());
-
-  const GrowableObjectArray& mixin_apps =
+  const GrowableObjectArray& mixin_types =
       GrowableObjectArray::Handle(GrowableObjectArray::New());
   AbstractType& mixin_type = AbstractType::Handle();
-  Class& mixin_app_class = Class::Handle();
-  String& mixin_app_class_name = String::Handle();
-  String& mixin_type_class_name = String::Handle();
   do {
     ConsumeToken();
-    const intptr_t mixin_pos = TokenPos();
     mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters);
+    if (mixin_type.IsDynamicType()) {
+      // The string 'dynamic' is not resolved yet at this point, but a malformed
+      // type mapped to dynamic can be encountered here.
+      ErrorMsg(mixin_type.token_pos(), "illegal mixin of a malformed type");
+    }
     if (mixin_type.IsTypeParameter()) {
-      ErrorMsg(mixin_pos,
+      ErrorMsg(mixin_type.token_pos(),
                "mixin type '%s' may not be a type parameter",
                String::Handle(mixin_type.UserVisibleName()).ToCString());
     }
-
-    // The name of the mixin application class is a combination of
-    // the super class name and mixin class name.
-    mixin_app_class_name = mixin_super_type.ClassName();
-    mixin_app_class_name = String::Concat(mixin_app_class_name,
-                                          Symbols::Ampersand());
-    mixin_type_class_name = mixin_type.ClassName();
-    mixin_app_class_name = String::Concat(mixin_app_class_name,
-                                          mixin_type_class_name);
-    mixin_app_class_name = Symbols::New(mixin_app_class_name);
-
-    mixin_app_class = Class::New(mixin_app_class_name, script_, mixin_pos);
-    mixin_app_class.set_super_type(mixin_super_type);
-    mixin_app_class.set_mixin(Type::Cast(mixin_type));
-    mixin_app_class.set_library(library_);
-    mixin_app_class.set_is_synthesized_class();
-    pending_classes.Add(mixin_app_class, Heap::kOld);
-
-    // The class finalizer will add the mixin type to the interfaces that the
-    // mixin application class implements. This is necessary so that type tests
-    // work. The mixin class may not be resolved yet, so it is not possible to
-    // add the interface with the correct type arguments here.
-
-    // Add the synthesized class to the list of mixin apps.
-    mixin_apps.Add(mixin_app_class);
-
-    // This mixin application class becomes the type class of the super type of
-    // the next mixin application class. It is however too early to provide the
-    // correct super type arguments. We use the raw type for now.
-    mixin_super_type = Type::New(mixin_app_class,
-                                 Object::null_abstract_type_arguments(),
-                                 mixin_pos);
+    mixin_types.Add(mixin_type);
   } while (CurrentToken() == Token::kCOMMA);
-  return MixinAppType::New(Array::Handle(Array::MakeArray(mixin_apps)));
+  return MixinAppType::New(super_type,
+                           Array::Handle(Array::MakeArray(mixin_types)));
 }
 
 
@@ -7649,7 +7613,7 @@
   if (expr->EvalConstExpr() == NULL) {
     ErrorMsg(expr_pos, "expression is not a valid compile-time constant");
   }
-  return new LiteralNode(expr_pos, EvaluateConstExpr(expr));
+  return new LiteralNode(expr_pos, EvaluateConstExpr(expr_pos, expr));
 }
 
 
@@ -7862,8 +7826,11 @@
 
 LiteralNode* Parser::ParseConstExpr() {
   TRACE_PARSER("ParseConstExpr");
+  intptr_t expr_pos = TokenPos();
   AstNode* expr = ParseExpr(kRequireConst, kNoCascades);
-  ASSERT(expr->IsLiteralNode());
+  if (!expr->IsLiteralNode()) {
+    ErrorMsg(expr_pos, "expression must be a compile-time constant");
+  }
   return expr->AsLiteralNode();
 }
 
@@ -9572,7 +9539,9 @@
                                      map_constr,
                                      constr_args));
     if (constructor_result.IsUnhandledException()) {
-      return GenerateRethrow(literal_pos, constructor_result);
+      AppendErrorMsg(Error::Cast(constructor_result),
+                     literal_pos,
+                     "error executing const Map constructor");
     } else {
       const Instance& const_instance = Instance::Cast(constructor_result);
       return new LiteralNode(literal_pos,
@@ -9620,6 +9589,8 @@
                                      factory_method,
                                      factory_param);
   }
+  UNREACHABLE();
+  return NULL;
 }
 
 
@@ -9685,7 +9656,9 @@
                                    constr,
                                    constr_args));
   if (result.IsUnhandledException()) {
-    return GenerateRethrow(symbol_pos, result);
+    AppendErrorMsg(Error::Cast(result),
+                   symbol_pos,
+                   "error executing const Symbol constructor");
   }
   const Instance& instance = Instance::Cast(result);
   return new LiteralNode(symbol_pos, Instance::ZoneHandle(instance.raw()));
@@ -9923,7 +9896,11 @@
                                      constructor,
                                      arguments));
     if (constructor_result.IsUnhandledException()) {
-      new_object = GenerateRethrow(new_pos, constructor_result);
+      // It's a compile-time error if invocation of a const constructor
+      // call fails.
+      AppendErrorMsg(Error::Cast(constructor_result),
+                     new_pos,
+                     "error while evaluating const constructor");
     } else {
       const Instance& const_instance = Instance::Cast(constructor_result);
       new_object = new LiteralNode(new_pos,
@@ -10060,7 +10037,7 @@
             const_expr->IsBool() ||
             const_expr->IsNull())) {
           // Change expr into a literal.
-          expr = new LiteralNode(expr_pos, EvaluateConstExpr(expr));
+          expr = new LiteralNode(expr_pos, EvaluateConstExpr(expr_pos, expr));
         } else {
           is_compiletime_const = false;
         }
@@ -10258,7 +10235,7 @@
 
 // Evaluate expression in expr and return the value. The expression must
 // be a compile time constant.
-const Instance& Parser::EvaluateConstExpr(AstNode* expr) {
+const Instance& Parser::EvaluateConstExpr(intptr_t expr_pos, AstNode* expr) {
   if (expr->IsLiteralNode()) {
     return expr->AsLiteralNode()->literal();
   } else if (expr->IsLoadLocalNode() &&
@@ -10275,9 +10252,9 @@
 
     Object& result = Object::Handle(Compiler::ExecuteOnce(seq));
     if (result.IsError()) {
-      // Propagate the compilation error.
-      isolate()->long_jump_base()->Jump(1, Error::Cast(result));
-      UNREACHABLE();
+      AppendErrorMsg(Error::Cast(result),
+                     expr_pos,
+                     "error evaluating constant expression");
     }
     ASSERT(result.IsInstance());
     Instance& value = Instance::ZoneHandle();
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 60b02be..5d8cc9b 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -337,7 +337,7 @@
 
   void CheckRecursiveInvocation();
 
-  const Instance& EvaluateConstExpr(AstNode* expr);
+  const Instance& EvaluateConstExpr(intptr_t expr_pos, AstNode* expr);
   AstNode* RunStaticFieldInitializer(const Field& field);
   RawObject* EvaluateConstConstructorCall(
       const Class& type_class,
@@ -420,8 +420,7 @@
                          GrowableArray<Field*>* initialized_fields);
   String& ParseNativeDeclaration();
   void ParseInterfaceList(const Class& cls);
-  RawAbstractType* ParseMixins(const GrowableObjectArray& pending_classes,
-                               const AbstractType& super_type);
+  RawAbstractType* ParseMixins(const AbstractType& super_type);
   static StaticCallNode* BuildInvocationMirrorAllocation(
       intptr_t call_pos,
       const String& function_name,
diff --git a/runtime/vm/port.cc b/runtime/vm/port.cc
index 3f45846..0c9a627 100644
--- a/runtime/vm/port.cc
+++ b/runtime/vm/port.cc
@@ -82,6 +82,12 @@
   ASSERT(index >= 0);
   map_[index].live = true;
   map_[index].handler->increment_live_ports();
+  if (FLAG_trace_isolates) {
+    OS::Print("[^] Live port: \n"
+              "\thandler:    %s\n"
+              "\tport:       %" Pd64 "\n",
+              map_[index].handler->name(), port);
+  }
 }
 
 
@@ -137,6 +143,13 @@
   used_++;
   MaintainInvariants();
 
+  if (FLAG_trace_isolates) {
+    OS::Print("[+] Opening port: \n"
+              "\thandler:    %s\n"
+              "\tport:       %" Pd64 "\n",
+              handler->name(), entry.port);
+  }
+
   return entry.port;
 }
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index f329f56..2bda25b 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -483,7 +483,7 @@
   RawLibrary* library_;
   RawTypeArguments* type_parameters_;  // Array of TypeParameter.
   RawAbstractType* super_type_;
-  RawType* mixin_;
+  RawType* mixin_;  // Generic mixin type, e.g. M<T>, not M<int>.
   RawClass* patch_class_;
   RawFunction* signature_function_;  // Associated function for signature class.
   RawArray* constants_;  // Canonicalized values of this class.
@@ -1203,11 +1203,12 @@
   RAW_HEAP_OBJECT_IMPLEMENTATION(MixinAppType);
 
   RawObject** from() {
-    return reinterpret_cast<RawObject**>(&ptr()->mixins_);
+    return reinterpret_cast<RawObject**>(&ptr()->super_type_);
   }
-  RawArray* mixins_;  // Array of synthesized mixin application classes.
+  RawAbstractType* super_type_;
+  RawArray* mixin_types_;  // Array of AbstractType.
   RawObject** to() {
-    return reinterpret_cast<RawObject**>(&ptr()->mixins_);
+    return reinterpret_cast<RawObject**>(&ptr()->mixin_types_);
   }
 };
 
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 17264e8..365d9e0 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -2604,8 +2604,8 @@
       "main() {\n"
       "  var messageCount = 0;\n"
       "  var exception = '';\n"
-      "  var port = new ReceivePort();\n"
-      "  port.receive((message, replyTo) {\n"
+      "  var port = new RawReceivePort();\n"
+      "  port.handler = (message) {\n"
       "    if (messageCount < 8) {\n"
       "      exception = '$exception${message}';\n"
       "    } else {\n"
@@ -2616,8 +2616,8 @@
       "    }\n"
       "    messageCount++;\n"
       "    if (messageCount == 9) throw new Exception(exception);\n"
-      "  });\n"
-      "  return port.toSendPort();\n"
+      "  };\n"
+      "  return port.sendPort;\n"
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
   Dart_EnterScope();
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index a8351cd..322c39f 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -42,6 +42,7 @@
   V(JumpToExceptionHandler)                                                    \
   V(UnoptimizedIdenticalWithNumberCheck)                                       \
   V(OptimizedIdenticalWithNumberCheck)                                         \
+  V(CompileFunctionRuntimeCall)                                                \
 
 // Is it permitted for the stubs above to refer to Object::null(), which is
 // allocated in the VM isolate and shared across all isolates.
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 8e78555..768ca07 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1589,8 +1589,25 @@
 
   __ Bind(&call_target_function);
   // R0: target function.
-  __ ldr(R0, FieldAddress(R0, Function::code_offset()));
-  __ ldr(R0, FieldAddress(R0, Code::instructions_offset()));
+  __ ldr(R1, FieldAddress(R0, Function::code_offset()));
+  if (FLAG_collect_code) {
+    // If we are collecting code, the code object may be null.
+    Label is_compiled;
+    __ CompareImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
+    __ b(&is_compiled, NE);
+    __ EnterStubFrame();
+    // Preserve arg desc. and IC data object.
+    __ PushList((1 << R4) | (1 << R5));
+    __ Push(R0);  // Pass function.
+    __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
+    __ Pop(R0);  // Discard argument.
+    __ PopList((1 << R4) | (1 << R5));  // Restore arg desc. and IC data.
+    __ LeaveStubFrame();
+    // R0: target function.
+    __ ldr(R1, FieldAddress(R0, Function::code_offset()));
+    __ Bind(&is_compiled);
+  }
+  __ ldr(R0, FieldAddress(R1, Code::instructions_offset()));
   __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag);
   __ bx(R0);
 
@@ -1758,6 +1775,23 @@
 }
 
 
+// Stub for calling the CompileFunction runtime call.
+// R5: IC-Data.
+// R4: Arguments descriptor.
+// R0: Function.
+void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) {
+  // Preserve arg desc. and IC data object.
+  __ EnterStubFrame();
+  __ PushList((1 << R4) | (1 << R5));
+  __ Push(R0);  // Pass function.
+  __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
+  __ Pop(R0);  // Restore argument.
+  __ PopList((1 << R4) | (1 << R5));  // Restore arg desc. and IC data.
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
   __ Comment("BreakpointRuntime stub");
   __ EnterStubFrame();
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 38da005..5e83dd6 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1613,8 +1613,25 @@
 
   __ Bind(&call_target_function);
   // EAX: Target function.
-  __ movl(EAX, FieldAddress(EAX, Function::code_offset()));
-  __ movl(EAX, FieldAddress(EAX, Code::instructions_offset()));
+  Label is_compiled;
+  __ movl(EBX, FieldAddress(EAX, Function::code_offset()));
+  if (FLAG_collect_code) {
+    // If code might be GC'd, then EBX might be null. If it is, recompile.
+    __ cmpl(EBX, raw_null);
+    __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump);
+    __ EnterStubFrame();
+    __ pushl(EDX);  // Preserve arguments descriptor array.
+    __ pushl(ECX);  // Preserve IC data object.
+    __ pushl(EAX);  // Pass function.
+    __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
+    __ popl(EAX);  // Restore function.
+    __ popl(ECX);  // Restore IC data array.
+    __ popl(EDX);  // Restore arguments descriptor array.
+    __ LeaveFrame();
+    __ movl(EBX, FieldAddress(EAX, Function::code_offset()));
+    __ Bind(&is_compiled);
+  }
+  __ movl(EAX, FieldAddress(EBX, Code::instructions_offset()));
   __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
   __ jmp(EAX);
 
@@ -1796,6 +1813,24 @@
 }
 
 
+// Stub for calling the CompileFunction runtime call.
+// ECX: IC-Data.
+// EDX: Arguments descriptor.
+// EAX: Function.
+void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushl(EDX);  // Preserve arguments descriptor array.
+  __ pushl(ECX);  // Preserve IC data object.
+  __ pushl(EAX);  // Pass function.
+  __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
+  __ popl(EAX);  // Restore function.
+  __ popl(ECX);  // Restore IC data array.
+  __ popl(EDX);  // Restore arguments descriptor array.
+  __ LeaveFrame();
+  __ ret();
+}
+
+
 // EDX, ECX: May contain arguments to runtime stub.
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
   __ EnterStubFrame();
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index aea2d8e..4ddc9b0 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -1812,8 +1812,26 @@
 
   __ Bind(&call_target_function);
   // T3: Target function.
-  __ lw(T3, FieldAddress(T3, Function::code_offset()));
-  __ lw(T3, FieldAddress(T3, Code::instructions_offset()));
+  Label is_compiled;
+  __ lw(T4, FieldAddress(T3, Function::code_offset()));
+  if (FLAG_collect_code) {
+    __ BranchNotEqual(T4, reinterpret_cast<int32_t>(Object::null()),
+                      &is_compiled);
+    __ EnterStubFrame();
+    __ addiu(SP, SP, Immediate(-3 * kWordSize));
+    __ sw(S5, Address(SP, 2 * kWordSize));  // Preserve IC data.
+    __ sw(S4, Address(SP, 1 * kWordSize));  // Preserve arg desc.
+    __ sw(T3, Address(SP, 0 * kWordSize));  // Function argument.
+    __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
+    __ lw(T3, Address(SP, 0 * kWordSize));  // Restore Function.
+    __ lw(S4, Address(SP, 1 * kWordSize));  // Restore arg desc.
+    __ lw(S5, Address(SP, 2 * kWordSize));  // Restore IC data.
+    __ addiu(SP, SP, Immediate(3 * kWordSize));
+    __ LeaveStubFrame();
+    __ lw(T4, FieldAddress(T3, Function::code_offset()));
+    __ Bind(&is_compiled);
+  }
+  __ lw(T3, FieldAddress(T4, Code::instructions_offset()));
   __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag);
   __ jr(T3);
 
@@ -1993,6 +2011,24 @@
 }
 
 
+// Stub for calling the CompileFunction runtime call.
+// S5: IC-Data.
+// S4: Arguments descriptor.
+// T0: Function.
+void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ addiu(SP, SP, Immediate(-3 * kWordSize));
+  __ sw(S5, Address(SP, 2 * kWordSize));  // Preserve IC data object.
+  __ sw(S4, Address(SP, 1 * kWordSize));  // Preserve args descriptor array.
+  __ sw(T0, Address(SP, 0 * kWordSize));  // Pass function.
+  __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
+  __ lw(T0, Address(SP, 0 * kWordSize));  // Restore function.
+  __ lw(S4, Address(SP, 1 * kWordSize));  // Restore args descriptor array.
+  __ lw(S5, Address(SP, 2 * kWordSize));  // Restore IC data array.
+  __ LeaveStubFrameAndReturn();
+}
+
+
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
   __ Comment("BreakpointRuntime stub");
   __ EnterStubFrame();
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 24d4259..31abeec 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1600,8 +1600,25 @@
 
   __ Bind(&call_target_function);
   // RAX: Target function.
-  __ movq(RAX, FieldAddress(RAX, Function::code_offset()));
-  __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
+  Label is_compiled;
+  __ movq(RCX, FieldAddress(RAX, Function::code_offset()));
+  if (FLAG_collect_code) {
+    // If code might be GC'd, then EBX might be null. If it is, recompile.
+    __ CompareObject(RCX, Object::null_object(), PP);
+    __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump);
+    __ EnterStubFrame();
+    __ pushq(R10);  // Preserve arguments descriptor array.
+    __ pushq(RBX);  // Preserve IC data object.
+    __ pushq(RAX);  // Pass function.
+    __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
+    __ popq(RAX);  // Restore function.
+    __ popq(RBX);  // Restore IC data array.
+    __ popq(R10);  // Restore arguments descriptor array.
+    __ LeaveFrame();
+    __ movq(RCX, FieldAddress(RAX, Function::code_offset()));
+    __ Bind(&is_compiled);
+  }
+  __ movq(RAX, FieldAddress(RCX, Code::instructions_offset()));
   __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
   __ jmp(RAX);
 
@@ -1782,6 +1799,24 @@
 }
 
 
+// Stub for calling the CompileFunction runtime call.
+// RCX: IC-Data.
+// RDX: Arguments descriptor.
+// RAX: Function.
+void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushq(RDX);  // Preserve arguments descriptor array.
+  __ pushq(RCX);  // Preserve IC data object.
+  __ pushq(RAX);  // Pass function.
+  __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
+  __ popq(RAX);  // Restore function.
+  __ popq(RCX);  // Restore IC data array.
+  __ popq(RDX);  // Restore arguments descriptor array.
+  __ LeaveFrame();
+  __ ret();
+}
+
+
 //  RBX, R10: May contain arguments to runtime stub.
 //  TOS(0): return address (Dart code).
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 60464fb..27b64cf 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -216,7 +216,7 @@
   V(InvocationMirror, "_InvocationMirror")                                     \
   V(AllocateInvocationMirror, "_allocateInvocationMirror")                     \
   V(toString, "toString")                                                      \
-  V(_ReceivePortImpl, "_ReceivePortImpl")                                      \
+  V(_RawReceivePortImpl, "_RawReceivePortImpl")                                \
   V(_lookupReceivePort, "_lookupReceivePort")                                  \
   V(_handleMessage, "_handleMessage")                                          \
   V(_SendPortImpl, "_SendPortImpl")                                            \
@@ -234,7 +234,7 @@
   V(InternalError, "InternalError")                                            \
   V(NullThrownError, "NullThrownError")                                        \
   V(IsolateSpawnException, "IsolateSpawnException")                            \
-  V(IsolateUnhandledException, "IsolateUnhandledException")                    \
+  V(IsolateUnhandledException, "_IsolateUnhandledException")                   \
   V(JavascriptIntegerOverflowError, "_JavascriptIntegerOverflowError")         \
   V(MirroredCompilationError, "MirroredCompilationError")                      \
   V(_setupFullStackTrace, "_setupFullStackTrace")                              \
@@ -265,7 +265,6 @@
   V(DartCollectionDev, "dart:_collection-dev")                                 \
   V(DartConvert, "dart:convert")                                               \
   V(DartIsolate, "dart:isolate")                                               \
-  V(DartJson, "dart:json")                                                     \
   V(DartMath, "dart:math")                                                     \
   V(DartMirrors, "dart:mirrors")                                               \
   V(DartTypedData, "dart:typed_data")                                          \
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index 904eb1b..d8ff0b4 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -23,7 +23,8 @@
     'mirrors_patch_cc_file': '<(gen_source_dir)/mirrors_patch_gen.cc',
     'isolate_cc_file': '<(gen_source_dir)/isolate_gen.cc',
     'isolate_patch_cc_file': '<(gen_source_dir)/isolate_patch_gen.cc',
-    'json_cc_file': '<(gen_source_dir)/json_gen.cc',
+    'platform_cc_file': '<(gen_source_dir)/platform_gen.cc',
+    'platform_patch_cc_file': '<(gen_source_dir)/platform_patch_gen.cc',
     'typed_data_cc_file': '<(gen_source_dir)/typed_data_gen.cc',
     'typed_data_patch_cc_file': '<(gen_source_dir)/typed_data_patch_gen.cc',
     'utf_cc_file': '<(gen_source_dir)/utf_gen.cc',
@@ -108,9 +109,10 @@
         'generate_math_patch_cc_file#host',
         'generate_isolate_cc_file#host',
         'generate_isolate_patch_cc_file#host',
-        'generate_json_cc_file#host',
         'generate_mirrors_cc_file#host',
         'generate_mirrors_patch_cc_file#host',
+        'generate_platform_cc_file#host',
+        'generate_platform_patch_cc_file#host',
         'generate_typed_data_cc_file#host',
         'generate_typed_data_patch_cc_file#host',
         'generate_utf_cc_file#host',
@@ -122,6 +124,7 @@
         '../lib/isolate_sources.gypi',
         '../lib/math_sources.gypi',
         '../lib/mirrors_sources.gypi',
+        '../lib/platform_sources.gypi',
         '../lib/typed_data_sources.gypi',
       ],
       'sources': [
@@ -141,9 +144,10 @@
         '<(math_patch_cc_file)',
         '<(isolate_cc_file)',
         '<(isolate_patch_cc_file)',
-        '<(json_cc_file)',
         '<(mirrors_cc_file)',
         '<(mirrors_patch_cc_file)',
+        '<(platform_cc_file)',
+        '<(platform_patch_cc_file)',
         '<(typed_data_cc_file)',
         '<(typed_data_patch_cc_file)',
         '<(utf_cc_file)',
@@ -163,6 +167,7 @@
         '../lib/isolate_sources.gypi',
         '../lib/math_sources.gypi',
         '../lib/mirrors_sources.gypi',
+        '../lib/platform_sources.gypi',
         '../lib/typed_data_sources.gypi',
       ],
       'sources': [
@@ -812,35 +817,81 @@
       ]
     },
     {
-      'target_name': 'generate_json_cc_file',
+      'target_name': 'generate_platform_cc_file',
       'type': 'none',
       'toolsets':['host'],
       'includes': [
-        # Load the shared json sources.
-        '../../sdk/lib/json/json_sources.gypi',
+        '../../sdk/lib/platform/platform_sources.gypi',
+      ],
+      'sources/': [
+        # Exclude all .[cc|h] files.
+        # This is only here for reference. Excludes happen after
+        # variable expansion, so the script has to do its own
+        # exclude processing of the sources being passed.
+        ['exclude', '\\.cc|h$'],
       ],
       'actions': [
         {
-          'action_name': 'generate_json_cc',
+          'action_name': 'generate_platform_cc',
           'inputs': [
             '../tools/gen_library_src_paths.py',
             '<(libgen_in_cc_file)',
             '<@(_sources)',
           ],
           'outputs': [
-            '<(json_cc_file)',
+            '<(platform_cc_file)',
           ],
           'action': [
             'python',
             'tools/gen_library_src_paths.py',
-            '--output', '<(json_cc_file)',
+            '--output', '<(platform_cc_file)',
             '--input_cc', '<(libgen_in_cc_file)',
             '--include', 'vm/bootstrap.h',
-            '--var_name', 'dart::Bootstrap::json_source_paths_',
-            '--library_name', 'dart:json',
+            '--var_name', 'dart::Bootstrap::platform_source_paths_',
+            '--library_name', 'dart:platform',
             '<@(_sources)',
           ],
-          'message': 'Generating ''<(json_cc_file)'' file.'
+          'message': 'Generating ''<(platform_cc_file)'' file.'
+        },
+      ]
+    },
+    {
+      'target_name': 'generate_platform_patch_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'includes': [
+        # Load the runtime implementation sources.
+        '../lib/platform_sources.gypi',
+      ],
+      'sources/': [
+        # Exclude all .[cc|h] files.
+        # This is only here for reference. Excludes happen after
+        # variable expansion, so the script has to do its own
+        # exclude processing of the sources being passed.
+        ['exclude', '\\.cc|h$'],
+      ],
+      'actions': [
+        {
+          'action_name': 'generate_platform_patch_cc',
+          'inputs': [
+            '../tools/gen_library_src_paths.py',
+            '<(libgen_in_cc_file)',
+            '<@(_sources)',
+          ],
+          'outputs': [
+            '<(platform_patch_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/gen_library_src_paths.py',
+            '--output', '<(platform_patch_cc_file)',
+            '--input_cc', '<(libgen_in_cc_file)',
+            '--include', 'vm/bootstrap.h',
+            '--var_name', 'dart::Bootstrap::platform_patch_paths_',
+            '--library_name', 'dart:platform',
+            '<@(_sources)',
+          ],
+          'message': 'Generating ''<(platform_patch_cc_file)'' file.'
         },
       ]
     },
diff --git a/sdk/lib/_collection_dev/iterable.dart b/sdk/lib/_collection_dev/iterable.dart
index 96fc924..651e346 100644
--- a/sdk/lib/_collection_dev/iterable.dart
+++ b/sdk/lib/_collection_dev/iterable.dart
@@ -18,35 +18,6 @@
   int get length;
 }
 
-// This is a hack to make @deprecated work in dart:io. Don't remove or use this,
-// unless coordinated with either me or the core library team. Thanks!
-// TODO(ajohnsen): Remove at the 11th of August 2013.
-// TODO(ajohnsen): Remove hide in:
-//    tools/dom/templates/html/dart2js/html_dart2js.darttemplate
-//    tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
-//    tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
-//    tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
-//    tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
-//    tools/dom/templates/html/dartium/html_dartium.darttemplate
-//    tools/dom/templates/html/dartium/svg_dartium.darttemplate
-//    tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
-//    tools/dom/templates/html/dartium/web_gl_dartium.darttemplate
-//    tools/dom/templates/html/dartium/web_sql_dartium.darttemplate
-//    sdk/lib/core/regexp.dart
-// TODO(floitsch): also used in dart:async until end of September for
-//    deprecation of runZonedExperimental.
-// TODO(floitsch): also used in dart:json and dart:utf until middle of October
-//    for deprecation of json and utf libraries.
-// TODO(floitsch): and dart:async until middle of October for deprecation of
-//    getAttachedStackTrace.
-// TODO(floitsch): and dart:async until end of October for deprecation of
-//    runAsync.
-
-// We use a random string constant to avoid it clashing with other constants.
-// This is, because we have a test that verifies that no metadata is included
-// in the output, when no mirrors need them.
-const deprecated = "qB2n4PYM";
-
 /**
  * An [Iterable] for classes that have efficient [length] and [elementAt].
  *
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index f72214b..022acb4 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -173,10 +173,9 @@
 
     Uri resourceUri = translateUri(readableUri, node);
     // TODO(johnniwinther): Wrap the result from [provider] in a specialized
-    // [Future] to ensure that we never execute an asynchronous action without setting
-    // up the current element of the compiler.
-    return new Future.sync(() => callUserProvider(resourceUri))
-        .then((data) {
+    // [Future] to ensure that we never execute an asynchronous action without
+    // setting up the current element of the compiler.
+    return new Future.sync(() => callUserProvider(resourceUri)).then((data) {
       SourceFile sourceFile;
       String resourceUriString = resourceUri.toString();
       if (data is List<int>) {
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 93474dc..61638b4 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -68,13 +68,13 @@
   }
 }
 
-typedef void PostProcessAction();
+typedef void DeferredAction();
 
-class PostProcessTask {
+class DeferredTask {
   final Element element;
-  final PostProcessAction action;
+  final DeferredAction action;
 
-  PostProcessTask(this.element, this.action);
+  DeferredTask(this.element, this.action);
 }
 
 abstract class Backend {
@@ -1028,13 +1028,17 @@
         }
         FunctionElement mainMethod = main;
         FunctionSignature parameters = mainMethod.computeSignature(this);
-        parameters.forEachParameter((Element parameter) {
-          reportError(
-              parameter,
-              MessageKind.GENERIC,
-              {'text':
-                "Error: '$MAIN' cannot have parameters."});
-        });
+        if (parameters.parameterCount > 2) {
+          int index = 0;
+          parameters.forEachParameter((Element parameter) {
+            if (index++ < 2) return;
+            reportError(
+                parameter,
+                MessageKind.GENERIC,
+                {'text':
+                  "Error: '$MAIN' cannot have more than two parameters."});
+          });
+        }
       }
 
       mirrorUsageAnalyzerTask.analyzeUsage(mainApp);
@@ -1141,6 +1145,15 @@
   void processQueue(Enqueuer world, Element main) {
     world.nativeEnqueuer.processNativeClasses(libraries.values);
     if (main != null) {
+      FunctionElement mainMethod = main;
+      if (mainMethod.computeSignature(this).parameterCount != 0) {
+        // TODO(ngeoffray, floitsch): we should also ensure that the
+        // class IsolateMessage is instantiated. Currently, just enabling
+        // isolate support works.
+        world.enableIsolateSupport(main.getLibrary());
+        world.registerInstantiatedClass(listClass, globalDependencies);
+        world.registerInstantiatedClass(stringClass, globalDependencies);
+      }
       world.addToWorkList(main);
     }
     progress.reset();
@@ -1148,9 +1161,6 @@
       withCurrentElement(work.element, () => work.run(this, world));
     });
     world.queueIsClosed = true;
-    world.forEachPostProcessTask((PostProcessTask work) {
-      withCurrentElement(work.element, () => work.action());
-    });
     if (compilationFailed) return;
     assert(world.checkNoEnqueuedInvokedInstanceMethods());
     if (DUMP_INFERRED_TYPES && phase == PHASE_COMPILING) {
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 8d2bba5..36ce3e4 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -687,6 +687,7 @@
   void forEachExport(f(Element element));
 
   bool hasLibraryName();
+  String getLibraryName();
   String getLibraryOrScriptName();
 
   int compareTo(LibraryElement other);
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index b7d6f5e..56a35e9 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -934,6 +934,15 @@
   bool hasLibraryName() => libraryTag != null;
 
   /**
+   * Returns the library name, which is either the name given in the library tag
+   * or the empty string if there is no library tag.
+   */
+  String getLibraryName() {
+    if (libraryTag == null) return '';
+    return libraryTag.name.toString();
+  }
+
+  /**
    * Returns the library name (as defined by the library tag) or for script
    * (which have no library tag) the script file name. The latter case is used
    * to private 'library name' for scripts to use for instance in dartdoc.
diff --git a/sdk/lib/_internal/compiler/implementation/enqueue.dart b/sdk/lib/_internal/compiler/implementation/enqueue.dart
index c0a5bac..06ed03b 100644
--- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
+++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
@@ -251,6 +251,7 @@
   }
 
   void enableNoSuchMethod(Element element) {}
+  void enableIsolateSupport(LibraryElement element) {}
 
   void onRegisterInstantiatedClass(ClassElement cls) {
     task.measure(() {
@@ -539,11 +540,13 @@
         // TODO(johnniwinther): Find an optimal process order.
         f(queue.removeLast());
       }
-      compiler.backend.onQueueEmpty(this);
+      onQueueEmpty();
     } while (!queue.isEmpty);
   }
 
-  void forEachPostProcessTask(f(PostProcessTask work)) {}
+  void onQueueEmpty() {
+    compiler.backend.onQueueEmpty(this);
+  }
 
   void logSummary(log(message)) {
     _logSpecificSummary(log);
@@ -569,17 +572,17 @@
   final Queue<ResolutionWorkItem> queue;
 
   /**
-   * A post-processing queue for the resolution phase which is processed
-   * immediately after the resolution queue has been closed.
+   * A deferred task queue for the resolution phase which is processed
+   * when the resolution queue has been emptied.
    */
-  final Queue<PostProcessTask> postQueue;
+  final Queue<DeferredTask> deferredTaskQueue;
 
   ResolutionEnqueuer(Compiler compiler,
                      ItemCompilationContext itemCompilationContextCreator())
       : super('resolution enqueuer', compiler, itemCompilationContextCreator),
         resolvedElements = new Map<Element, TreeElements>(),
         queue = new Queue<ResolutionWorkItem>(),
-        postQueue = new Queue<PostProcessTask>();
+        deferredTaskQueue = new Queue<DeferredTask>();
 
   bool get isResolutionQueue => true;
 
@@ -672,26 +675,31 @@
   }
 
   /**
-   * Adds an action to the post-processing queue.
+   * Adds an action to the deferred task queue.
    *
-   * 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 action is performed the next time the resolution queue has been
+   * emptied.
    *
    * The queue is processed in FIFO order.
    */
-  void addPostProcessAction(Element element, PostProcessAction action) {
+  void addDeferredAction(Element element, DeferredAction action) {
     if (queueIsClosed) {
       throw new SpannableAssertionFailure(element,
           "Resolution work list is closed. "
-          "Trying to add post process action for $element");
+          "Trying to add deferred action for $element");
     }
-    postQueue.add(new PostProcessTask(element, action));
+    deferredTaskQueue.add(new DeferredTask(element, action));
   }
 
-  void forEachPostProcessTask(f(PostProcessTask work)) {
-    while (!postQueue.isEmpty) {
-      f(postQueue.removeFirst());
+  void onQueueEmpty() {
+    emptyDeferredTaskQueue();
+    super.onQueueEmpty();
+  }
+
+  void emptyDeferredTaskQueue() {
+    while (!deferredTaskQueue.isEmpty) {
+      DeferredTask task = deferredTaskQueue.removeFirst();
+      compiler.withCurrentElement(task.element, task.action);
     }
   }
 
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 54602bd..ea4c22e 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
@@ -246,10 +246,8 @@
       // goes in the work queue.
       giveUp(inferrer);
       if (element.isField()) {
-        InterfaceType rawType = element.computeType(inferrer.compiler).asRaw();
-        return rawType.treatAsDynamic
-            ? inferrer.types.dynamicType.type
-            : new TypeMask.subtype(rawType.element);
+        return inferrer.typeOfNativeBehavior(
+            native.NativeBehavior.ofFieldLoad(element, inferrer.compiler)).type;
       } else {
         assert(element.isFunction()
                || element.isGetter()
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 3080e5a..4cbc51c 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -626,8 +626,7 @@
     extendableArrayType = new HBoundedType(
         new TypeMask.nonNullExact(jsExtendableArrayClass));
 
-    typeVariableClass =
-        compiler.findHelper('TypeVariable');
+    typeVariableClass = compiler.findHelper('TypeVariable');
   }
 
   void validateInterceptorImplementsAllObjectMethods(
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
index bd143b4..ac0cec4 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
@@ -1318,7 +1318,7 @@
           if (buffer != null) {
             var metadata = metadataEmitter.buildMetadataFunction(library);
             mainBuffer
-                ..write('["${library.getLibraryOrScriptName()}",$_')
+                ..write('["${library.getLibraryName()}",$_')
                 ..write('"${uri}",$_')
                 ..write(metadata == null
                         ? "" : jsAst.prettyPrint(metadata, compiler))
@@ -1336,7 +1336,7 @@
           buffer = buffers[1];
           if (buffer != null) {
             deferredLibraries
-                ..write('["${library.getLibraryOrScriptName()}",$_')
+                ..write('["${library.getLibraryName()}",$_')
                 ..write('"${uri}",$_')
                 ..write('[],$_')
                 ..write(namer.globalObjectFor(library))
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index a53f550..0d24f1d 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -69,6 +69,11 @@
 
   /// Emits a summary information using the [log] function.
   void logSummary(log(message)) {}
+
+  // Do not use annotations in dart2dart.
+  ClassElement get annotationCreatesClass => null;
+  ClassElement get annotationReturnsClass => null;
+  ClassElement get annotationJsNameClass => null;
 }
 
 
@@ -851,7 +856,7 @@
       return cls.computeType(compiler);
     }
 
-    NativeEnqueuerBase enqueuer = compiler.enqueuer.resolution.nativeEnqueuer;
+    NativeEnqueuer enqueuer = compiler.enqueuer.resolution.nativeEnqueuer;
     var creates = _collect(element, compiler, enqueuer.annotationCreatesClass,
                            lookup);
     var returns = _collect(element, compiler, enqueuer.annotationReturnsClass,
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index b8d6fa7..bab8bfe 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -556,7 +556,7 @@
     }
 
     if (Elements.isStaticOrTopLevelField(element)) {
-      visitor.addPostProcessAction(element, () {
+      visitor.addDeferredAction(element, () {
         compiler.constantHandler.compileVariable(
             element, isConst: element.modifiers.isConst());
       });
@@ -1517,8 +1517,8 @@
     compiler.unimplemented(message, node: node);
   }
 
-  void addPostProcessAction(Element element, PostProcessAction action) {
-    compiler.enqueuer.resolution.addPostProcessAction(element, action);
+  void addDeferredAction(Element element, DeferredAction action) {
+    compiler.enqueuer.resolution.addDeferredAction(element, action);
   }
 }
 
@@ -1777,7 +1777,7 @@
       // Remove the guarded when this is fixed.
       if (!compiler.enqueuer.resolution.queueIsClosed &&
           addTypeVariableBoundsCheck) {
-        visitor.addPostProcessAction(
+        visitor.addDeferredAction(
             visitor.enclosingElement,
             () => checkTypeVariableBounds(node, type));
       }
@@ -2175,7 +2175,7 @@
       }
       parameterNodes = parameterNodes.tail;
     });
-    addPostProcessAction(enclosingElement, () {
+    addDeferredAction(enclosingElement, () {
       functionParameters.forEachOptionalParameter((Element parameter) {
         compiler.constantHandler.compileConstant(parameter);
       });
@@ -2896,7 +2896,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.
-    addPostProcessAction(constructor, () {
+    addDeferredAction(constructor, () {
       compiler.resolver.resolveRedirectionChain(constructor, node);
     });
 
@@ -3041,7 +3041,7 @@
   }
 
   void analyzeConstant(Node node, {bool isConst: true}) {
-    addPostProcessAction(enclosingElement, () {
+    addDeferredAction(enclosingElement, () {
        compiler.constantHandler.compileNodeWithDefinitions(
            node, mapping, isConst: isConst);
     });
@@ -3586,7 +3586,7 @@
             bound = element.bound;
           }
         }
-        addPostProcessAction(element, checkTypeVariableBound);
+        addDeferredAction(element, checkTypeVariableBound);
       } else {
         variableElement.bound = compiler.objectClass.computeType(compiler);
       }
@@ -3625,7 +3625,7 @@
     void checkCyclicReference() {
       element.checkCyclicReference(compiler);
     }
-    addPostProcessAction(element, checkCyclicReference);
+    addDeferredAction(element, checkCyclicReference);
   }
 }
 
@@ -4233,7 +4233,7 @@
           new VariableElementX(name, variables, kind, link.head);
       resolver.defineElement(link.head, element);
       if (definitions.modifiers.isConst()) {
-        compiler.enqueuer.resolution.addPostProcessAction(element, () {
+        compiler.enqueuer.resolution.addDeferredAction(element, () {
           compiler.constantHandler.compileVariable(element, isConst: true);
         });
       }
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart b/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart
index 5eb9129..e6d3cef 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart
@@ -23,7 +23,8 @@
    * etc.
    */
   void appendStringToken(PrecedenceInfo info, String value) {
-    tail.next = new StringToken.fromString(info, value, tokenStart, true);
+    tail.next = new StringToken.fromString(info, value, tokenStart,
+                                           canonicalize: true);
     tail = tail.next;
   }
 
@@ -96,7 +97,7 @@
   }
 
   /**
-   * Notifies on [$LF] characters in multi-line commends or strings.
+   * Notifies on [$LF] characters in multi-line comments or strings.
    *
    * This method is used by the scanners to track line breaks and create the
    * [lineStarts] map.
@@ -122,7 +123,7 @@
   }
 
   /**
-   * Appends a token that begins a ends group, represented by [value].
+   * Appends a token that begins an end group, represented by [value].
    * It handles the group end tokens '}', ')' and ']'. The tokens '>' and
    * '>>' are handled separately bo [appendGt] and [appendGtGt].
    */
@@ -194,16 +195,15 @@
   }
 
   /**
-   * We call this method to discard '<' from the "grouping" stack
-   * (maintained by subclasses).
+   * This method is called to discard '<' from the "grouping" stack.
    *
    * [PartialParser.skipExpression] relies on the fact that we do not
    * create groups for stuff like:
    * [:a = b < c, d = e > f:].
    *
    * In other words, this method is called when the scanner recognizes
-   * something which cannot possibly be part of a type
-   * parameter/argument list.
+   * something which cannot possibly be part of a type parameter/argument
+   * list, like the '=' in the above example.
    */
   void discardOpenLt() {
     while (!groupingStack.isEmpty
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/scanner.dart b/sdk/lib/_internal/compiler/implementation/scanner/scanner.dart
index 771290b..0d00bd0 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/scanner.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/scanner.dart
@@ -49,13 +49,12 @@
    */
   final SourceFile file;
 
-  final List<int> lineStarts = [0];
+  final List<int> lineStarts = <int>[0];
 
   AbstractScanner(this.file, this.includeComments) {
     this.tail = this.tokens;
   }
 
-
   /**
    * Advances and returns the next character.
    *
@@ -76,7 +75,7 @@
    *
    * The [Utf8BytesScanner] decodes the next unicode code point starting at the
    * current position. Note that every unicode character is returned as a single
-   * code point, i.e., for '\u{1d11e}' it returns 119070, and the following
+   * code point, that is, for '\u{1d11e}' it returns 119070, and the following
    * [advance] returns the next character.
    *
    * The [StringScanner] returns the current character unchanged, which might
@@ -855,7 +854,7 @@
   }
 
   /**
-   * [next] is the first character after the qoute.
+   * [next] is the first character after the quote.
    * [start] is the scanOffset of the quote.
    *
    * The token contains a substring of the source file, including the
@@ -929,7 +928,7 @@
 
   int tokenizeSingleLineRawString(int next, int quoteChar, int start) {
     bool asciiOnly = true;
-    next = advance(); // Advance past the quote
+    next = advance(); // Advance past the quote.
     while (next != $EOF) {
       if (identical(next, quoteChar)) {
         if (!asciiOnly) handleUnicode(start);
@@ -952,7 +951,7 @@
     bool asciiOnlyString = true;
     bool asciiOnlyLine = true;
     int unicodeStart = start;
-    int next = advance(); // Advance past the (last) quote (of three)
+    int next = advance(); // Advance past the (last) quote (of three).
     outer: while (!identical(next, $EOF)) {
       while (!identical(next, quoteChar)) {
         if (identical(next, $LF)) {
@@ -1045,10 +1044,10 @@
     String error = 'unmatched "${begin.stringValue}"';
     Token close =
         new StringToken.fromString(
-            BAD_INPUT_INFO, error, begin.charOffset, true);
+            BAD_INPUT_INFO, error, begin.charOffset, canonicalize: true);
 
     // We want to ensure that unmatched BeginGroupTokens are reported
-    // as errors. However, the rest of the parser assume the groups
+    // as errors. However, the rest of the parser assumes the groups
     // are well-balanced and will never look at the endGroup
     // token. This is a nice property that allows us to skip quickly
     // over correct code. By inserting an additional error token in
@@ -1062,7 +1061,7 @@
     // reported when parsing the [next] token.
 
     Token next = new StringToken.fromString(
-        BAD_INPUT_INFO, error, begin.charOffset, true);
+        BAD_INPUT_INFO, error, begin.charOffset, canonicalize: true);
     begin.endGroup = close;
     close.next = next;
     next.next = begin.next;
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/scanner_task.dart b/sdk/lib/_internal/compiler/implementation/scanner/scanner_task.dart
index 869e20e..0fa7c57 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/scanner_task.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/scanner_task.dart
@@ -40,8 +40,8 @@
    * Returns the tokens for the [source].
    *
    * The [StringScanner] implementation works on strings that end with a '0'
-   * value ('\x00'). If [source] does not with '0', the string is copied before
-   * scanning.
+   * value ('\x00'). If [source] does not end with '0', the string is copied
+   * before scanning.
    */
   Token tokenize(String source) {
     return measure(() {
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart b/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart
index 2dd92f9..f0f11e0 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart
@@ -42,14 +42,13 @@
 
   void handleUnicode(int startScanOffset) { }
 
-
   Token firstToken() => tokens.next;
   Token previousToken() => tail;
 
   void appendSubstringToken(PrecedenceInfo info, int start,
                             bool asciiOnly, [int extraOffset = 0]) {
     tail.next = new StringToken.fromSubstring(info, string, start,
-        scanOffset + extraOffset, tokenStart, true);
+        scanOffset + extraOffset, tokenStart, canonicalize: true);
     tail = tail.next;
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/token.dart b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
index d9909e3..8251963 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/token.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
@@ -103,13 +103,12 @@
   /**
    * The string represented by this token, a substring of the source code.
    *
-   * For [StringToken]s the value includes the quotes, explicit escapes, etc.
-   *
+   * For [StringToken]s the [value] includes the quotes, explicit escapes, etc.
    */
   String get value;
 
   /**
-   * For symbol and keyword tokens, returns the string value reprenseted by this
+   * For symbol and keyword tokens, returns the string value represented by this
    * token. For [StringToken]s this method returns [:null:].
    *
    * For [SymbolToken]s and [KeywordToken]s, the string value is a compile-time
@@ -140,7 +139,7 @@
 
   /**
    * True if this token is an identifier. Some keywords allowed as identifiers,
-   * see implementaiton in [KeywordToken].
+   * see implementation in [KeywordToken].
    */
   bool isIdentifier();
 
@@ -171,7 +170,7 @@
 }
 
 /**
- * A symbol token represents the symbol in its precendence info.
+ * A [SymbolToken] represents the symbol in its precendence info.
  * Also used for end of file with EOF_INFO.
  */
 class SymbolToken extends Token {
@@ -190,7 +189,7 @@
 }
 
 /**
- * A [BeginGroupToken] reprsents a symbol that may be the beginning of
+ * A [BeginGroupToken] represents a symbol that may be the beginning of
  * a pair of brackets, i.e., ( { [ < or ${
  * The [endGroup] token points to the matching closing bracked in case
  * it can be identified during scanning.
@@ -199,7 +198,7 @@
   Token endGroup;
 
   BeginGroupToken(PrecedenceInfo info, int charOffset)
-    : super(info, charOffset);
+      : super(info, charOffset);
 }
 
 /**
@@ -223,7 +222,7 @@
 
 /**
  * A String-valued token. Represents identifiers, string literals,
- * number literals, comments and error tokens, using the corresponding
+ * number literals, comments, and error tokens, using the corresponding
  * precedence info.
  */
 class StringToken extends Token {
@@ -237,7 +236,7 @@
    */
   static const int LAZY_THRESHOLD = 4;
 
-  var valueOrLazySubstring;
+  var /* String | LazySubtring */ valueOrLazySubstring;
 
   final PrecedenceInfo info;
 
@@ -246,7 +245,7 @@
    * is canonicalized before the token is created.
    */
   StringToken.fromString(this.info, String value, int charOffset,
-                         [bool canonicalize = false])
+                         {bool canonicalize : false})
       : valueOrLazySubstring = canonicalizedString(value, canonicalize),
         super(charOffset);
 
@@ -255,12 +254,12 @@
    * is canonicalized before the token is created.
    */
   StringToken.fromSubstring(this.info, String data, int start, int end,
-                            int charOffset, [bool canonicalize = false])
+                            int charOffset, {bool canonicalize : false})
       : super(charOffset) {
     int length = end - start;
     if (length <= LAZY_THRESHOLD) {
       valueOrLazySubstring = canonicalizedString(data.substring(start, end),
-                                            canonicalize);
+                                                 canonicalize);
     } else {
       valueOrLazySubstring =
           new LazySubstring(data, start, length, canonicalize);
@@ -308,7 +307,7 @@
   String toString() => "StringToken($value)";
 
   static final HashSet<String> canonicalizedSubstrings =
-      new HashSet();
+      new HashSet<String>();
 
   static String canonicalizedString(String s, bool canonicalize) {
     if (!canonicalize) return s;
@@ -334,8 +333,8 @@
 
 /**
  * This class represents the necessary information to compute a substring
- * lazily. The substring can either originate in a string or in a [:List<int>:]
- * of UTF-8 bytes.
+ * lazily. The substring can either originate from a string or from
+ * a [:List<int>:] of UTF-8 bytes.
  */
 abstract class LazySubstring {
   /** The original data, either a string or a List<int> */
@@ -345,10 +344,10 @@
   int get length;
 
   /**
-   * If this substring is based on a String, the boolean indicates wheter the
-   * resulting substring should be canonicalized.
+   * If this substring is based on a String, the [boolValue] indicates wheter
+   * the resulting substring should be canonicalized.
    *
-   * For substrings based on a byte array, the boolean value is true if the
+   * For substrings based on a byte array, the [boolValue] is true if the
    * array only holds ASCII characters. The resulting substring will be
    * canonicalized after decoding.
    */
@@ -373,9 +372,9 @@
 /**
  * This class encodes [start], [length] and [boolValue] in a single
  * 30 bit integer. It uses 20 bits for [start], which covers source files
- * of 1M. [length] has 9 bits, which covers 512 characters.
+ * of 1MB. [length] has 9 bits, which covers 512 characters.
  *
- * The file html_dart2js.dart is currently around 1M.
+ * The file html_dart2js.dart is currently around 1MB.
  */
 class CompactLazySubstring extends LazySubstring {
   final data;
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/utf8_bytes_scanner.dart b/sdk/lib/_internal/compiler/implementation/scanner/utf8_bytes_scanner.dart
index 7e7cdf713..523495c 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/utf8_bytes_scanner.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/utf8_bytes_scanner.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -13,7 +13,7 @@
   List<int> bytes;
 
   /**
-   * Points to the offset of the byte last returned by [advance].
+   * Points to the offset of the last byte returned by [advance].
    *
    * After invoking [currentAsUnicode], the [byteOffset] points to the last
    * byte that is part of the (unicode or ASCII) character. That way, [advance]
@@ -184,7 +184,6 @@
   Token firstToken() => tokens.next;
   Token previousToken() => tail;
 
-
   void appendSubstringToken(PrecedenceInfo info, int start, bool asciiOnly,
                             [int extraOffset = 0]) {
     tail.next = new StringToken.fromUtf8Bytes(
diff --git a/sdk/lib/_internal/compiler/implementation/source_file.dart b/sdk/lib/_internal/compiler/implementation/source_file.dart
index 25f2afb..45636ea 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file.dart
@@ -34,7 +34,7 @@
    * Sets the string length of this source file. For source files based on UTF-8
    * byte arrays, the string length is computed and assigned by the scanner.
    */
-  set length(v);
+  set length(int v);
 
   /**
    * A map from line numbers to offsets in the string text representation of
@@ -57,7 +57,7 @@
    * source file had one more empty line at the end. This simplifies the binary
    * search in [getLine].
    */
-  set lineStarts(v) => lineStartsCache = v;
+  set lineStarts(List<int> v) => lineStartsCache = v;
 
   List<int> lineStartsCache;
 
@@ -173,7 +173,7 @@
     }
     return lengthCache;
   }
-  set length(v) => lengthCache = v;
+  set length(int v) => lengthCache = v;
   int lengthCache = -1;
 }
 
@@ -184,7 +184,7 @@
   StringSourceFile(String filename, this.text) : super(filename);
 
   int get length => text.length;
-  set length(v) { }
+  set length(int v) { }
 
   String slowText() => text;
 
diff --git a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
index d1ae322..4640ff5 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
@@ -43,7 +43,7 @@
     List<int> source;
     try {
       source = readAll(uriPathToNative(resourceUri.path));
-    } on FileException catch (ex) {
+    } on FileSystemException catch (ex) {
       return new Future.error(
           "Error reading '${relativize(cwd, resourceUri, isWindows)}' "
           "(${ex.osError})");
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 8c3783a..392350c 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -608,6 +608,8 @@
       visitExpression(argument);
     } else if (argument is HCheck && !variableNames.hasName(argument)) {
       HCheck check = argument;
+      // This can only happen if the checked node does not have a name.
+      assert(!variableNames.hasName(check.checkedInput));
       use(check.checkedInput);
     } else {
       assert(variableNames.hasName(argument));
@@ -2434,39 +2436,39 @@
     }
   }
 
-  js.Expression generateTest(HCheck node) {
-    HInstruction input = node.checkedInput;
+  js.Expression generateTest(HInstruction input, HType checkedType) {
     TypeMask receiver = input.instructionType.computeMask(compiler);
-    TypeMask mask = node.instructionType.computeMask(compiler);
+    TypeMask mask = checkedType.computeMask(compiler);
     // Figure out if it is beneficial to turn this into a null check.
     // 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 turnIntoNumCheck = input.isIntegerOrNull() && node.isInteger();
+    bool turnIntoNumCheck = input.isIntegerOrNull() && checkedType.isInteger();
     bool turnIntoNullCheck = !turnIntoNumCheck
         && (mask.nullable() == receiver)
-        && (node.isInteger() || node.isIndexablePrimitive(compiler));
+        && (checkedType.isInteger()
+            || checkedType.isIndexablePrimitive(compiler));
     js.Expression test;
     if (turnIntoNullCheck) {
       use(input);
       test = new js.Binary("==", pop(), new js.LiteralNull());
-    } else if (node.isInteger() && !turnIntoNumCheck) {
+    } else if (checkedType.isInteger() && !turnIntoNumCheck) {
       // input is !int
       checkInt(input, '!==');
       test = pop();
-    } else if (node.isNumber() || turnIntoNumCheck) {
+    } else if (checkedType.isNumber() || turnIntoNumCheck) {
       // input is !num
       checkNum(input, '!==');
       test = pop();
-    } else if (node.isBoolean()) {
+    } else if (checkedType.isBoolean()) {
       // input is !bool
       checkBool(input, '!==');
       test = pop();
-    } else if (node.isString(compiler)) {
+    } else if (checkedType.isString(compiler)) {
       // input is !string
       checkString(input, '!==');
       test = pop();
-    } else if (node.isExtendableArray(compiler)) {
+    } else if (checkedType.isExtendableArray(compiler)) {
       // input is !Object || input is !Array || input.isFixed
       checkObject(input, '!==');
       js.Expression objectTest = pop();
@@ -2475,7 +2477,7 @@
       checkFixedArray(input);
       test = new js.Binary('||', objectTest, arrayTest);
       test = new js.Binary('||', test, pop());
-    } else if (node.isMutableArray(compiler)) {
+    } else if (checkedType.isMutableArray(compiler)) {
       // input is !Object
       // || ((input is !Array || input.isImmutable)
       //     && input is !JsIndexingBehavior)
@@ -2490,7 +2492,7 @@
           ? new js.Binary('&&', notArrayOrImmutable, pop())
           : notArrayOrImmutable;
       test = new js.Binary('||', objectTest, notIndexing);
-    } else if (node.isReadableArray(compiler)) {
+    } else if (checkedType.isReadableArray(compiler)) {
       // input is !Object
       // || (input is !Array && input is !JsIndexingBehavior)
       checkObject(input, '!==');
@@ -2502,7 +2504,7 @@
           ? new js.Binary('&&', arrayTest, pop())
           : arrayTest;
       test = new js.Binary('||', objectTest, notIndexing);
-    } else if (node.isIndexablePrimitive(compiler)) {
+    } else if (checkedType.isIndexablePrimitive(compiler)) {
       // input is !String
       // && (input is !Object
       //     || (input is !Array && input is !JsIndexingBehavior))
@@ -2529,8 +2531,9 @@
     if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) {
       // An int check if the input is not int or null, is not
       // sufficient for doing a argument or receiver check.
-      assert(!node.isInteger() || node.checkedInput.isIntegerOrNull());
-      js.Expression test = generateTest(node);
+      assert(!node.checkedType.isInteger() ||
+          node.checkedInput.isIntegerOrNull());
+      js.Expression test = generateTest(node.checkedInput, node.checkedType);
       js.Block oldContainer = currentContainer;
       js.Statement body = new js.Block.empty();
       currentContainer = body;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 7b76168..c72124e 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -2251,6 +2251,7 @@
   final int kind;
   final Selector receiverTypeCheckSelector;
   final bool contextIsTypeArguments;
+  HType checkedType;  // Not final because we refine it.
 
   static const int CHECKED_MODE_CHECK = 0;
   static const int ARGUMENT_TYPE_CHECK = 1;
@@ -2262,6 +2263,7 @@
                   HType type, HInstruction input,
                   [this.receiverTypeCheckSelector])
       : contextIsTypeArguments = false,
+        checkedType = type,
         super(<HInstruction>[input]) {
     assert(!isReceiverTypeCheck || receiverTypeCheckSelector != null);
     assert(typeExpression == null ||
@@ -2274,6 +2276,7 @@
                                          HType type, HInstruction input,
                                          HInstruction typeRepresentation)
       : contextIsTypeArguments = false,
+        checkedType = type,
         super(<HInstruction>[input, typeRepresentation]),
         receiverTypeCheckSelector = null {
     assert(typeExpression.kind != TypeKind.TYPEDEF);
@@ -2286,6 +2289,7 @@
                               HInstruction context,
                               {bool this.contextIsTypeArguments})
       : super(<HInstruction>[input, context]),
+        checkedType = type,
         receiverTypeCheckSelector = null {
     assert(typeExpression.kind != TypeKind.TYPEDEF);
     sourceElement = input.sourceElement;
@@ -2328,7 +2332,7 @@
   bool dataEquals(HTypeConversion other) {
     return kind == other.kind
         && typeExpression == other.typeExpression
-        && instructionType == other.instructionType;
+        && checkedType == other.checkedType;
   }
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index 3424ca0..d85cc01 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -600,7 +600,7 @@
         return node;
       }
     }
-    return removeIfCheckAlwaysSucceeds(node, node.instructionType);
+    return removeIfCheckAlwaysSucceeds(node, node.checkedType);
   }
 
   HInstruction visitTypeKnown(HTypeKnown node) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
index 7b1a34c..eea1cc5 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
@@ -263,6 +263,9 @@
   String visitExit(HExit node) => "exit";
 
   String visitFieldGet(HFieldGet node) {
+    if (node.isNullCheck) {
+      return 'null check on ${temporaryId(node.receiver)}';
+    }
     String fieldName = node.element.name;
     return 'field get ${temporaryId(node.receiver)}.$fieldName';
   }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
index e3a107b..4122364 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
@@ -140,21 +140,37 @@
   }
 
   HType visitTypeConversion(HTypeConversion instruction) {
-    HType oldType = instruction.instructionType;
-    // Do not change a checked mode check.
-    if (instruction.isCheckedModeCheck) return oldType;
-    // We must make sure a type conversion for receiver or argument check
-    // does not try to do an int check, because an int check is not enough.
-    // We only do an int check if the input is integer or null.
-    HInstruction checked = instruction.checkedInput;
-    if (oldType.isNumber()
-        && !oldType.isDouble()
-        && checked.isIntegerOrNull()) {
-      return HType.INTEGER;
-    } else if (oldType.isInteger() && !checked.isIntegerOrNull()) {
-      return HType.NUMBER;
+    HType inputType = instruction.checkedInput.instructionType;
+    HType checkedType = instruction.checkedType;
+    if (instruction.isArgumentTypeCheck || instruction.isReceiverTypeCheck) {
+      // We must make sure a type conversion for receiver or argument check
+      // does not try to do an int check, because an int check is not enough.
+      // We only do an int check if the input is integer or null.
+      if (checkedType.isNumber()
+          && !checkedType.isDouble()
+          && inputType.isIntegerOrNull()) {
+        instruction.checkedType = HType.INTEGER;
+      } else if (checkedType.isInteger() && !inputType.isIntegerOrNull()) {
+        instruction.checkedType = HType.NUMBER;
+      }
     }
-    return oldType;
+
+    HType outputType = checkedType.intersection(inputType, compiler);
+    if (outputType.isConflicting()) {
+      // Intersection of double and integer conflicts (is empty), but JS numbers
+      // can be both int and double at the same time.  For example, the input
+      // can be a literal double '8.0' that is marked as an integer (because 'is
+      // int' will return 'true').  What we really need to do is make the
+      // overlap between int and double values explicit in the HType system.
+      if (inputType.isIntegerOrNull() && checkedType.isDoubleOrNull()) {
+        if (inputType.canBeNull() && checkedType.canBeNull()) {
+          outputType = HType.DOUBLE_OR_NULL;
+        } else {
+          outputType = HType.DOUBLE;
+        }
+      }
+    }
+    return outputType;
   }
 
   HType visitTypeKnown(HTypeKnown instruction) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart b/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
index 6d1ef73..bf4262b 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
@@ -682,6 +682,10 @@
     for (int i = 0; i < phi.inputs.length; i++) {
       HInstruction input = phi.inputs[i];
       HBasicBlock predecessor = phi.block.predecessors[i];
+      // A [HTypeKnown] instruction never has a name, but its checked
+      // input might, therefore we need to do a copy instead of an
+      // assignment.
+      while (input is HTypeKnown) input = input.inputs[0];
       if (!needsName(input)) {
         names.addAssignment(predecessor, input, phi);
       } else {
diff --git a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
index 99f79b0..3d3f3c8 100644
--- a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
@@ -607,7 +607,7 @@
       // race conditions).
       try {
         dir.createSync();
-      } on DirectoryException catch (e) {
+      } on FileSystemException catch (e) {
         // Ignore.
       }
     }
@@ -803,7 +803,6 @@
     writeString(new File(filePath),
         '''library client;
         import 'dart:html';
-        import 'dart:json';
         import r'${path.toUri(path.join(clientDir, 'client-shared.dart'))}';
         import r'${path.toUri(path.join(clientDir, 'dropdown.dart'))}';
 
diff --git a/sdk/lib/_internal/dartdoc/lib/src/export_map.dart b/sdk/lib/_internal/dartdoc/lib/src/export_map.dart
index 169b0e9..25f6491 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/export_map.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/export_map.dart
@@ -10,7 +10,7 @@
 
 import 'dart:io';
 
-import 'package:analyzer_experimental/analyzer.dart';
+import 'package:analyzer/analyzer.dart';
 import 'package:path/path.dart' as pathos;
 
 import 'dartdoc/utils.dart';
@@ -46,7 +46,7 @@
       var importsAndExports;
       try {
         importsAndExports = _importsAndExportsForFile(path, packageRoot);
-      } on FileException catch (_) {
+      } on FileSystemException catch (_) {
         // Ignore unreadable/nonexistent files.
         return;
       }
diff --git a/sdk/lib/_internal/dartdoc/pubspec.yaml b/sdk/lib/_internal/dartdoc/pubspec.yaml
index cd4e771..3a19028 100644
--- a/sdk/lib/_internal/dartdoc/pubspec.yaml
+++ b/sdk/lib/_internal/dartdoc/pubspec.yaml
@@ -3,7 +3,7 @@
  Libraries for generating documentation from Dart source code.
 
 dependencies:
-  analyzer_experimental: ">=0.4.5 <1.0.0"
+  analyzer: ">=0.4.5 <1.0.0"
   args: ">=0.4.2 <1.0.0"
   path: ">=0.4.2 <1.0.0"
 
diff --git a/sdk/lib/_internal/lib/convert_patch.dart b/sdk/lib/_internal/lib/convert_patch.dart
index 1a84485..1f0b0575 100644
--- a/sdk/lib/_internal/lib/convert_patch.dart
+++ b/sdk/lib/_internal/lib/convert_patch.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.
 
-// Patch file for dart:json library.
+// Patch file for dart:convert library.
 
 import 'dart:_foreign_helper' show JS;
 import 'dart:_interceptors' show JSExtendableArray;
diff --git a/sdk/lib/_internal/lib/io_patch.dart b/sdk/lib/_internal/lib/io_patch.dart
index 0acb7d4..069e9a8 100644
--- a/sdk/lib/_internal/lib/io_patch.dart
+++ b/sdk/lib/_internal/lib/io_patch.dart
@@ -34,7 +34,7 @@
 
 patch class _EventHandler {
   patch static void _sendData(Object sender,
-                              ReceivePort receivePort,
+                              RawReceivePort receivePort,
                               int data) {
     throw new UnsupportedError("EventHandler._sendData");
   }
diff --git a/sdk/lib/_internal/lib/isolate_helper.dart b/sdk/lib/_internal/lib/isolate_helper.dart
index 7d9e722..ce6b5d3 100644
--- a/sdk/lib/_internal/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/lib/isolate_helper.dart
@@ -22,38 +22,6 @@
 
 ReceivePort lazyPort;
 
-class CloseToken {
-  /// This token is sent from [IsolateSink]s to [IsolateStream]s to ask them to
-  /// close themselves.
-  const CloseToken();
-}
-
-class JsIsolateSink extends EventSink<dynamic> implements IsolateSink {
-  bool _isClosed = false;
-  final SendPort _port;
-  JsIsolateSink.fromPort(this._port);
-
-  void add(dynamic message) {
-    _port.send(message);
-  }
-
-  void addError(errorEvent) {
-    throw new UnimplementedError("addError on isolate streams");
-  }
-
-  void close() {
-    if (_isClosed) return;
-    add(const CloseToken());
-    _isClosed = true;
-  }
-
-  bool operator==(var other) {
-    return other is IsolateSink && _port == other._port;
-  }
-
-  int get hashCode => _port.hashCode + 499;
-}
-
 /**
  * Called by the compiler to support switching
  * between isolates when we get a callback from the DOM.
@@ -90,7 +58,13 @@
   // by having a "default" isolate (the first one created).
   _globalState.currentContext = rootContext;
 
-  rootContext.eval(entry);
+  if (entry is _MainFunctionArgs) {
+    rootContext.eval(() { entry([]); });
+  } else if (entry is _MainFunctionArgsMessage) {
+    rootContext.eval(() { entry([], null); });
+  } else {
+    rootContext.eval(entry);
+  }
   _globalState.topEventLoop.run();
 }
 
@@ -417,6 +391,10 @@
 bool globalPostMessageDefined =
     JS('', "#.postMessage !== (void 0)", globalThis);
 
+typedef _MainFunction();
+typedef _MainFunctionArgs(args);
+typedef _MainFunctionArgsMessage(args, message);
+
 class IsolateNatives {
 
   static String thisScript = computeThisScript();
@@ -500,10 +478,13 @@
         Function entryPoint = (functionName == null)
             ? _globalState.entry
             : _getJSFunctionFromName(functionName);
+        var args = msg['args'];
+        var message = _deserializeMessage(msg['msg']);
+        var isSpawnUri = msg['isSpawnUri'];
         var replyTo = _deserializeMessage(msg['replyTo']);
         var context = new _IsolateContext();
         _globalState.topEventLoop.enqueue(context, () {
-          _startIsolate(entryPoint, replyTo);
+          _startIsolate(entryPoint, args, message, isSpawnUri, replyTo);
         }, 'worker-start');
         // Make sure we always have a current context in this worker.
         // TODO(7907): This is currently needed because we're using
@@ -515,13 +496,15 @@
         _globalState.topEventLoop.run();
         break;
       case 'spawn-worker':
-        _spawnWorker(msg['functionName'], msg['uri'], msg['replyPort']);
+        _spawnWorker(msg['functionName'], msg['uri'],
+                     msg['args'], msg['msg'],
+                     msg['isSpawnUri'], msg['replyPort']);
         break;
       case 'message':
         SendPort port = msg['port'];
         // If the port has been closed, we ignore the message.
         if (port != null) {
-          msg['port'].send(msg['msg'], msg['replyTo']);
+          msg['port'].send(msg['msg']);
         }
         _globalState.topEventLoop.run();
         break;
@@ -582,19 +565,25 @@
     return JS("", "new #()", ctor);
   }
 
-  static SendPort spawnFunction(void topLevelFunction()) {
+  static SendPort spawnFunction(void topLevelFunction(message), message) {
     final name = _getJSFunctionName(topLevelFunction);
     if (name == null) {
       throw new UnsupportedError(
           "only top-level functions can be spawned.");
     }
-    return spawn(name, null, false);
+    return spawn(name, null, null, message, false, false);
+  }
+
+  static SendPort spawnUri(Uri uri, List<String> args, message) {
+    return spawn(null, uri.toString(), args, message, false, true);
   }
 
   // TODO(sigmund): clean up above, after we make the new API the default:
 
   /// If [uri] is `null` it is replaced with the current script.
-  static spawn(String functionName, String uri, bool isLight) {
+  static SendPort spawn(String functionName, String uri,
+                        List<String> args, message,
+                        bool isLight, bool isSpawnUri) {
     // Assume that the compiled version of the Dart file lives just next to the
     // dart file.
     // TODO(floitsch): support precompiled version of dart2js output.
@@ -602,60 +591,86 @@
 
     Completer<SendPort> completer = new Completer<SendPort>.sync();
     ReceivePort port = new ReceivePort();
-    port.receive((msg, SendPort replyPort) {
+    port.listen((msg) {
       port.close();
-      assert(msg == _SPAWNED_SIGNAL);
-      completer.complete(replyPort);
+      assert(msg[0] == _SPAWNED_SIGNAL);
+      completer.complete(msg[1]);
     });
 
-    SendPort signalReply = port.toSendPort();
+    SendPort signalReply = port.sendPort;
 
     if (_globalState.useWorkers && !isLight) {
-      _startWorker(functionName, uri, signalReply);
+      _startWorker(functionName, uri, args, message, isSpawnUri, signalReply);
     } else {
-      _startNonWorker(functionName, uri, signalReply);
+      _startNonWorker(
+          functionName, uri, args, message, isSpawnUri, signalReply);
     }
     return new _BufferingSendPort(
         _globalState.currentContext.id, completer.future);
   }
 
-  static SendPort _startWorker(
-      String functionName, String uri, SendPort replyPort) {
+  static void _startWorker(
+      String functionName, String uri,
+      List<String> args, message,
+      bool isSpawnUri,
+      SendPort replyPort) {
     if (_globalState.isWorker) {
       _globalState.mainManager.postMessage(_serializeMessage({
           'command': 'spawn-worker',
           'functionName': functionName,
+          'args': args,
+          'msg': message,
           'uri': uri,
+          'isSpawnUri': isSpawnUri,
           'replyPort': replyPort}));
     } else {
-      _spawnWorker(functionName, uri, replyPort);
+      _spawnWorker(functionName, uri, args, message, isSpawnUri, replyPort);
     }
   }
 
-  static SendPort _startNonWorker(
-      String functionName, String uri, SendPort replyPort) {
+  static void _startNonWorker(
+      String functionName, String uri,
+      List<String> args, message,
+      bool isSpawnUri,
+      SendPort replyPort) {
     // TODO(eub): support IE9 using an iframe -- Dart issue 1702.
-    if (uri != null) throw new UnsupportedError(
-            "Currently spawnUri is not supported without web workers.");
+    if (uri != null) {
+      throw new UnsupportedError(
+          "Currently spawnUri is not supported without web workers.");
+    }
     _globalState.topEventLoop.enqueue(new _IsolateContext(), () {
       final func = _getJSFunctionFromName(functionName);
-      _startIsolate(func, replyPort);
+      _startIsolate(func, args, message, isSpawnUri, replyPort);
     }, 'nonworker start');
   }
 
-  static void _startIsolate(Function topLevel, SendPort replyTo) {
+  static void _startIsolate(Function topLevel,
+                            List<String> args, message,
+                            bool isSpawnUri,
+                            SendPort replyTo) {
     _IsolateContext context = JS_CURRENT_ISOLATE_CONTEXT();
     Primitives.initializeStatics(context.id);
     lazyPort = new ReceivePort();
-    replyTo.send(_SPAWNED_SIGNAL, port.toSendPort());
-    topLevel();
+    replyTo.send([_SPAWNED_SIGNAL, lazyPort.sendPort]);
+    if (!isSpawnUri) {
+      topLevel(message);
+    } else if (topLevel is _MainFunctionArgsMessage) {
+      topLevel(args, message);
+    } else if (topLevel is _MainFunctionArgs) {
+      topLevel(args);
+    } else {
+      topLevel();
+    }
   }
 
   /**
    * Spawns an isolate in a worker. [factoryName] is the Javascript constructor
    * name for the isolate entry point class.
    */
-  static void _spawnWorker(functionName, uri, replyPort) {
+  static void _spawnWorker(functionName, String uri,
+                           List<String> args, message,
+                           bool isSpawnUri,
+                           SendPort replyPort) {
     if (uri == null) uri = thisScript;
     final worker = JS('var', 'new Worker(#)', uri);
 
@@ -676,6 +691,9 @@
         // the port (port deserialization is sensitive to what is the current
         // workerId).
         'replyTo': _serializeMessage(replyPort),
+        'args': args,
+        'msg': _serializeMessage(message),
+        'isSpawnUri': isSpawnUri,
         'functionName': functionName }));
   }
 }
@@ -700,22 +718,7 @@
     }
   }
 
-  Future call(var message) {
-    final completer = new Completer();
-    final port = new ReceivePortImpl();
-    send(message, port.toSendPort());
-    port.receive((value, ignoreReplyTo) {
-      port.close();
-      if (value is Exception) {
-        completer.completeError(value);
-      } else {
-        completer.complete(value);
-      }
-    });
-    return completer.future;
-  }
-
-  void send(var message, [SendPort replyTo]);
+  void send(var message);
   bool operator ==(var other);
   int get hashCode;
 }
@@ -726,13 +729,12 @@
 
   const _NativeJsSendPort(this._receivePort, int isolateId) : super(isolateId);
 
-  void send(var message, [SendPort replyTo = null]) {
-    _waitForPendingPorts([message, replyTo], () {
-      _checkReplyTo(replyTo);
+  void send(var message, [SendPort replyTo]) {
+    _waitForPendingPorts(message, () {
       // Check that the isolate still runs and the port is still open
       final isolate = _globalState.isolates[_isolateId];
       if (isolate == null) return;
-      if (_receivePort._callback == null) return;
+      if (_receivePort._controller.isClosed) return;
 
       // We force serialization/deserialization as a simple way to ensure
       // isolate communication restrictions are respected between isolates that
@@ -744,18 +746,15 @@
       final shouldSerialize = _globalState.currentContext != null
           && _globalState.currentContext.id != _isolateId;
       var msg = message;
-      var reply = replyTo;
       if (shouldSerialize) {
         msg = _serializeMessage(msg);
-        reply = _serializeMessage(reply);
       }
       _globalState.topEventLoop.enqueue(isolate, () {
-        if (_receivePort._callback != null) {
+        if (!_receivePort._controller.isClosed) {
           if (shouldSerialize) {
             msg = _deserializeMessage(msg);
-            reply = _deserializeMessage(reply);
           }
-          _receivePort._callback(msg, reply);
+          _receivePort._controller.add(msg);
         }
       }, 'receive $message');
     });
@@ -776,14 +775,12 @@
   const _WorkerSendPort(this._workerId, int isolateId, this._receivePortId)
       : super(isolateId);
 
-  void send(var message, [SendPort replyTo = null]) {
-    _waitForPendingPorts([message, replyTo], () {
-      _checkReplyTo(replyTo);
+  void send(var message, [SendPort replyTo]) {
+    _waitForPendingPorts(message, () {
       final workerMessage = _serializeMessage({
           'command': 'message',
           'port': this,
-          'msg': message,
-          'replyTo': replyTo});
+          'msg': message});
 
       if (_globalState.isWorker) {
         // Communication from one worker to another go through the
@@ -838,7 +835,7 @@
     _futurePort.then((p) {
       _port = p;
       for (final item in pending) {
-        p.send(item['message'], item['replyTo']);
+        p.send(item);
       }
       pending = null;
     });
@@ -853,7 +850,7 @@
     if (_port != null) {
       _port.send(message, replyTo);
     } else {
-      pending.add({'message': message, 'replyTo': replyTo});
+      pending.add(message);
     }
   }
 
@@ -863,26 +860,32 @@
 }
 
 /** Implementation of a multi-use [ReceivePort] on top of JavaScript. */
-class ReceivePortImpl implements ReceivePort {
-  int _id;
-  Function _callback;
+class ReceivePortImpl extends Stream implements ReceivePort {
   static int _nextFreeId = 1;
+  final int _id;
+  StreamController _controller;
 
   ReceivePortImpl()
       : _id = _nextFreeId++ {
+    _controller = new StreamController(onCancel: close, sync: true);
     _globalState.currentContext.register(_id, this);
   }
 
-  void receive(void onMessage(var message, SendPort replyTo)) {
-    _callback = onMessage;
+  StreamSubscription listen(void onData(var event),
+                            {Function onError,
+                             void onDone(),
+                             bool cancelOnError}) {
+    return _controller.stream.listen(onData, onError: onError, onDone: onDone,
+                                     cancelOnError: cancelOnError);
   }
 
   void close() {
-    _callback = null;
+    if (_controller.isClosed) return;
+    _controller.close();
     _globalState.currentContext.unregister(_id);
   }
 
-  SendPort toSendPort() {
+  SendPort get sendPort {
     return new _NativeJsSendPort(this, _globalState.currentContext.id);
   }
 }
@@ -908,9 +911,7 @@
     final seen = _visited[list];
     if (seen != null) return;
     _visited[list] = true;
-    // TODO(sigmund): replace with the following: (bug #1660)
-    // list.forEach(_dispatch);
-    list.forEach((e) => _dispatch(e));
+    list.forEach(_dispatch);
   }
 
   visitMap(Map map) {
@@ -918,9 +919,7 @@
     if (seen != null) return;
 
     _visited[map] = true;
-    // TODO(sigmund): replace with the following: (bug #1660)
-    // map.values.forEach(_dispatch);
-    map.values.forEach((e) => _dispatch(e));
+    map.values.forEach(_dispatch);
   }
 
   visitSendPort(var port) {
@@ -928,14 +927,6 @@
       ports.add(port._futurePort);
     }
   }
-
-  visitIsolateSink(JsIsolateSink sink) {
-    visitSendPort(sink._port);
-  }
-
-  visitCloseToken(CloseToken token) {
-    // Do nothing.
-  }
 }
 
 /********************************************************
@@ -993,16 +984,6 @@
           " ports are resolved at this point.";
     }
   }
-
-  visitIsolateSink(JsIsolateSink sink) {
-    SendPort port = sink._port;
-    bool isClosed = sink._isClosed;
-    return ['isolateSink', visitSendPort(port), isClosed];
-  }
-
-  visitCloseToken(CloseToken token) {
-    return ['closeToken'];
-  }
 }
 
 
@@ -1036,18 +1017,6 @@
           " ports are resolved at this point.";
     }
   }
-
-  IsolateSink visitIsolateSink(JsIsolateSink sink) {
-    SendPort port = sink._port;
-    bool isClosed = sink._isClosed;
-    JsIsolateSink result = new JsIsolateSink.fromPort(visitSendPort(port));
-    result._isClosed = isClosed;
-    return result;
-  }
-
-  CloseToken visitCloseToken(CloseToken token) {
-    return token;  // Can be shared.
-  }
 }
 
 class _JsDeserializer extends _Deserializer {
@@ -1068,18 +1037,6 @@
       return new _WorkerSendPort(managerId, isolateId, receivePortId);
     }
   }
-
-  IsolateSink deserializeIsolateSink(List list) {
-    SendPort port = deserializeSendPort(list[1]);
-    bool isClosed = list[2];
-    JsIsolateSink result = new JsIsolateSink.fromPort(port);
-    result._isClosed = isClosed;
-    return result;
-  }
-
-  CloseToken deserializeCloseToken(List list) {
-    return const CloseToken();
-  }
 }
 
 class _JsVisitedMap implements _MessageTraverserVisitedMap {
@@ -1177,8 +1134,6 @@
     if (x is Map) return visitMap(x);
     if (x is SendPort) return visitSendPort(x);
     if (x is SendPortSync) return visitSendPortSync(x);
-    if (x is JsIsolateSink) return visitIsolateSink(x);
-    if (x is CloseToken) return visitCloseToken(x);
 
     // Overridable fallback.
     return visitObject(x);
@@ -1189,8 +1144,6 @@
   visitMap(Map x);
   visitSendPort(SendPort x);
   visitSendPortSync(SendPortSync x);
-  visitIsolateSink(IsolateSink x);
-  visitCloseToken(CloseToken x);
 
   visitObject(Object x) {
     // TODO(floitsch): make this a real exception. (which one)?
@@ -1302,8 +1255,6 @@
       case 'list': return _deserializeList(x);
       case 'map': return _deserializeMap(x);
       case 'sendport': return deserializeSendPort(x);
-      case 'isolateSink': return deserializeIsolateSink(x);
-      case 'closeToken': return deserializeCloseToken(x);
       default: return deserializeObject(x);
     }
   }
@@ -1345,10 +1296,6 @@
 
   deserializeSendPort(List x);
 
-  deserializeIsolateSink(List x);
-
-  deserializeCloseToken(List x);
-
   deserializeObject(List x) {
     // TODO(floitsch): Use real exception (which one?).
     throw "Unexpected serialized object";
diff --git a/sdk/lib/_internal/lib/isolate_patch.dart b/sdk/lib/_internal/lib/isolate_patch.dart
index 4e6982a..057e571 100644
--- a/sdk/lib/_internal/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/lib/isolate_patch.dart
@@ -10,31 +10,26 @@
                                    CloseToken,
                                    JsIsolateSink;
 
-patch class _Isolate {
-  patch static ReceivePort get port {
-    if (lazyPort == null) {
-      lazyPort = new ReceivePort();
+patch class Isolate {
+  patch static Future<Isolate> spawn(void entryPoint(message), var message) {
+    SendPort controlPort = IsolateNatives.spawnFunction(entryPoint, message);
+    return new Future<Isolate>.value(new Isolate._fromControlPort(controlPort));
+  }
+
+  patch static Future<Isolate> spawnUri(
+      Uri uri, List<String> args, var message) {
+    if (args is List<String>) {
+      for (int i = 0; i < args.length; i++) {
+        if (args[i] is! String) {
+          throw new ArgumentError("Args must be a list of Strings $args");
+        }
+      }
+    } else if (args != null) {
+      throw new ArgumentError("Args must be a list of Strings $args");
     }
-    return lazyPort;
+    SendPort controlPort = IsolateNatives.spawnUri(uri, args, message);
+    return new Future<Isolate>.value(new Isolate._fromControlPort(controlPort));
   }
-
-  patch static SendPort spawnFunction(void topLevelFunction(),
-      [bool unhandledExceptionCallback(IsolateUnhandledException e)]) {
-    if (unhandledExceptionCallback != null) {
-      // TODO(9012): Implement the UnhandledExceptionCallback.
-      throw new UnimplementedError(
-          "spawnFunction with unhandledExceptionCallback");
-    }
-    return IsolateNatives.spawnFunction(topLevelFunction);
-  }
-
-  patch static SendPort spawnUri(String uri) {
-    return IsolateNatives.spawn(null, uri, false);
-  }
-}
-
-patch bool _isCloseToken(var object) {
-  return identical(object, const CloseToken());
 }
 
 /** Default factory for receive ports. */
@@ -42,24 +37,14 @@
   patch factory ReceivePort() {
     return new ReceivePortImpl();
   }
+
+  patch factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
+    throw new UnimplementedError("ReceivePort.fromRawReceivePort");
+  }
 }
 
-patch class MessageBox {
-  patch MessageBox.oneShot() : this._oneShot(new ReceivePort());
-  MessageBox._oneShot(ReceivePort receivePort)
-      : stream = new IsolateStream._fromOriginalReceivePortOneShot(receivePort),
-        sink = new JsIsolateSink.fromPort(receivePort.toSendPort());
-
-  patch MessageBox() : this._(new ReceivePort());
-  MessageBox._(ReceivePort receivePort)
-      : stream = new IsolateStream._fromOriginalReceivePort(receivePort),
-        sink = new JsIsolateSink.fromPort(receivePort.toSendPort());
-}
-
-patch IsolateSink streamSpawnFunction(
-    void topLevelFunction(),
-    [bool unhandledExceptionCallback(IsolateUnhandledException e)]) {
-  SendPort sendPort = spawnFunction(topLevelFunction,
-                                    unhandledExceptionCallback);
-  return new JsIsolateSink.fromPort(sendPort);
+patch class RawReceivePort {
+  patch factory RawReceivePort([void handler(event)]) {
+    throw new UnimplementedError("RawReceivePort");
+  }
 }
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index 1890de0..ff0cf49 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -715,7 +715,7 @@
           selectorName,
           JSInvocationMirror.METHOD,
           arguments,
-          namedArguments == null ? null : namedArguments.keys.toList()));
+          namedArguments == null ? [] : namedArguments.keys.toList()));
     }
     // We bound 'this' to [function] because of how we compile
     // closures: escaped local variables are stored and accessed through
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index e5d73b0..f6f521d 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -253,6 +253,7 @@
   UnmodifiableMapView<Symbol, MethodMirror> _cachedSetters;
   UnmodifiableMapView<Symbol, VariableMirror> _cachedVariables;
   UnmodifiableMapView<Symbol, Mirror> _cachedMembers;
+  UnmodifiableMapView<Symbol, DeclarationMirror> _cachedDeclarations;
   UnmodifiableListView<InstanceMirror> _cachedMetadata;
 
   JsLibraryMirror(Symbol simpleName,
@@ -430,6 +431,17 @@
     return _cachedMembers = new UnmodifiableMapView<Symbol, Mirror>(result);
   }
 
+  Map<Symbol, DeclarationMirror> get declarations {
+    if (_cachedDeclarations != null) return _cachedDeclarations;
+    var result = new Map<Symbol, DeclarationMirror>();
+    addToResult(Symbol key, Mirror value) {
+      result[key] = value;
+    }
+    members.forEach(addToResult);
+    return _cachedDeclarations =
+        new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
+  }
+
   List<InstanceMirror> get metadata {
     if (_cachedMetadata != null) return _cachedMetadata;
     preserveMetadata();
@@ -535,6 +547,48 @@
   return mirror;
 }
 
+Map<Symbol, MethodMirror> filterMethods(List<MethodMirror> methods) {
+  var result = new Map();
+  for (JsMethodMirror method in methods) {
+    if (!method.isConstructor && !method.isGetter && !method.isSetter) {
+      result[method.simpleName] = method;
+    }
+  }
+  return result;
+}
+
+Map<Symbol, MethodMirror> filterGetters(List<MethodMirror> methods,
+                                        Map<Symbol, VariableMirror> fields) {
+  var result = new Map();
+  for (JsMethodMirror method in methods) {
+    if (method.isGetter) {
+
+      // TODO(ahe): This is a hack to remove getters corresponding to a field.
+      if (fields[method.simpleName] != null) continue;
+
+      result[method.simpleName] = method;
+    }
+  }
+  return result;
+}
+
+Map<Symbol, MethodMirror> filterSetters(List<MethodMirror> methods,
+                                          Map<Symbol, VariableMirror> fields) {
+  var result = new Map();
+  for (JsMethodMirror method in methods) {
+    if (method.isSetter) {
+
+      // TODO(ahe): This is a hack to remove setters corresponding to a field.
+      String name = n(method.simpleName);
+      name = name.substring(0, name.length - 1); // Remove '='.
+      if (fields[s(name)] != null) continue;
+
+      result[method.simpleName] = method;
+    }
+  }
+  return result;
+}
+
 int counter = 0;
 
 ClassMirror reflectMixinApplication(mixinNames, String mangledName) {
@@ -817,7 +871,7 @@
  * to JsCLassMirror that returns an empty list since it represents original
  * declarations and classes that are not generic.
  */
-class JsTypeBoundClassMirror implements ClassMirror {
+class JsTypeBoundClassMirror extends JsDeclarationMirror implements ClassMirror {
   final JsClassMirror _class;
 
   /**
@@ -832,8 +886,18 @@
    */
   var _typeArguments;
 
-  JsTypeBoundClassMirror(this._class, this._typeArguments);
+  Map<Symbol, VariableMirror> _cachedVariables;
+  Map<Symbol, MethodMirror> _cachedGetters;
+  Map<Symbol, MethodMirror> _cachedSetters;
+  Map<Symbol, MethodMirror> _cachedMethodsMap;
+  List<JsMethodMirror> _cachedMethods;
 
+  JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments)
+      : _class = originalDeclaration, 
+        super(originalDeclaration.simpleName);
+
+  String get _prettyName => 'ClassMirror';
+  
   List<TypeVariableMirror> get typeVariables => _class.typeVariables;
 
   List<TypeMirror> get typeArguments {
@@ -887,13 +951,38 @@
 
   Map<Symbol, MethodMirror> get constructors => _class.constructors;
 
-  Map<Symbol, MethodMirror> get methods => _class.methods;
+  List<JsMethodMirror> get _methods {
+    if (_cachedMethods != null) return _cachedMethods;
+    return _cachedMethods =_class._getMethodsWithOwner(this);
+  }
 
-  Map<Symbol, MethodMirror> get getters => _class.getters;
+  Map<Symbol, MethodMirror> get methods {
+    if (_cachedMethodsMap != null) return _cachedMethodsMap;
+    return _cachedMethodsMap = new UnmodifiableMapView<Symbol, MethodMirror>(
+        filterMethods(_methods));
+  }
 
-  Map<Symbol, MethodMirror> get setters => _class.setters;
+  Map<Symbol, MethodMirror> get getters {
+    if (_cachedGetters != null) return _cachedGetters;
+    return _cachedGetters = new UnmodifiableMapView<Symbol, MethodMirror>(
+        filterGetters(_methods, variables));
+  }
 
-  Map<Symbol, VariableMirror> get variables => _class.variables;
+  Map<Symbol, MethodMirror> get setters {
+    if (_cachedSetters != null) return _cachedSetters;
+    return _cachedSetters = new UnmodifiableMapView<Symbol, MethodMirror>(
+        filterSetters(_methods, variables));
+  }
+
+  Map<Symbol, VariableMirror> get variables {
+    if (_cachedVariables != null) return _cachedVariables;
+    var result = new Map();
+    for (JsVariableMirror mirror in  _class._getFieldsWithOwner(this)) {
+      result[mirror.simpleName] = mirror;
+    }
+    return _cachedVariables =
+        new UnmodifiableMapView<Symbol, VariableMirror>(result);
+  }
 
   Map<Symbol, Mirror> get members => _class.members;
 
@@ -986,6 +1075,7 @@
   UnmodifiableMapView<Symbol, MethodMirror> _cachedSetters;
   UnmodifiableMapView<Symbol, VariableMirror> _cachedVariables;
   UnmodifiableMapView<Symbol, Mirror> _cachedMembers;
+  UnmodifiableMapView<Symbol, DeclarationMirror> _cachedDeclarations;
   UnmodifiableListView<InstanceMirror> _cachedMetadata;
   UnmodifiableListView<ClassMirror> _cachedSuperinterfaces;
   UnmodifiableListView<TypeVariableMirror> _cachedTypeVariables;
@@ -1022,8 +1112,7 @@
         new UnmodifiableMapView<Symbol, MethodMirror>(result);
   }
 
-  List<JsMethodMirror> get _methods {
-    if (_cachedMethods != null) return _cachedMethods;
+  List<JsMethodMirror> _getMethodsWithOwner(DeclarationMirror methodOwner) {
     var prototype = JS('', '#.prototype', _jsConstructor);
     List<String> keys = extractKeys(prototype);
     var result = <JsMethodMirror>[];
@@ -1040,7 +1129,7 @@
           new JsMethodMirror.fromUnmangledName(
               simpleName, function, false, false);
       result.add(mirror);
-      mirror._owner = this;
+      mirror._owner = methodOwner;
     }
 
     keys = extractKeys(JS('', 'init.statics[#]', _mangledName));
@@ -1069,14 +1158,18 @@
           new JsMethodMirror.fromUnmangledName(
               unmangledName, jsFunction, isStatic, isConstructor);
       result.add(mirror);
-      mirror._owner = this;
+      mirror._owner = methodOwner;
     }
 
-    return _cachedMethods = result;
+    return result;
   }
 
-  List<VariableMirror> get _fields {
-    if (_cachedFields != null) return _cachedFields;
+  List<JsMethodMirror> get _methods {
+    if (_cachedMethods != null) return _cachedMethods;
+    return _cachedMethods = _getMethodsWithOwner(this);
+  }
+
+  List<VariableMirror> _getFieldsWithOwner(DeclarationMirror fieldOwner) {
     var result = <VariableMirror>[];
 
     var instanceFieldSpecfication = _fieldsDescriptor.split(';')[1];
@@ -1085,67 +1178,37 @@
           [instanceFieldSpecfication]..addAll(_fieldsMetadata);
     }
     parseCompactFieldSpecification(
-        this, instanceFieldSpecfication, false, result);
+        fieldOwner, instanceFieldSpecfication, false, result);
 
     var staticDescriptor = JS('', 'init.statics[#]', _mangledName);
     if (staticDescriptor != null) {
       parseCompactFieldSpecification(
-          this, JS('', '#[""]', staticDescriptor), true, result);
+          fieldOwner, JS('', '#[""]', staticDescriptor), true, result);
     }
-    _cachedFields = result;
-    return _cachedFields;
+    return result;
+  }
+
+  List<VariableMirror> get _fields {
+    if (_cachedFields != null) return _cachedFields;
+    return _cachedFields = _getFieldsWithOwner(this);
   }
 
   Map<Symbol, MethodMirror> get methods {
     if (_cachedMethodsMap != null) return _cachedMethodsMap;
-    var result = new Map();
-    for (JsMethodMirror method in _methods) {
-      if (!method.isConstructor && !method.isGetter && !method.isSetter) {
-        result[method.simpleName] = method;
-      }
-    }
     return _cachedMethodsMap =
-        new UnmodifiableMapView<Symbol, MethodMirror>(result);
+        new UnmodifiableMapView<Symbol, MethodMirror>(filterMethods(_methods));
   }
 
   Map<Symbol, MethodMirror> get getters {
     if (_cachedGetters != null) return _cachedGetters;
-    // TODO(ahe): This is a hack to remove getters corresponding to a field.
-    var fields = variables;
-
-    var result = new Map();
-    for (JsMethodMirror method in _methods) {
-      if (method.isGetter) {
-
-        // TODO(ahe): This is a hack to remove getters corresponding to a field.
-        if (fields[method.simpleName] != null) continue;
-
-        result[method.simpleName] = method;
-      }
-    }
-    return _cachedGetters =
-        new UnmodifiableMapView<Symbol, MethodMirror>(result);
+    return _cachedGetters = new UnmodifiableMapView<Symbol, MethodMirror>(
+        filterGetters(_methods, variables));
   }
 
   Map<Symbol, MethodMirror> get setters {
     if (_cachedSetters != null) return _cachedSetters;
-    // TODO(ahe): This is a hack to remove setters corresponding to a field.
-    var fields = variables;
-
-    var result = new Map();
-    for (JsMethodMirror method in _methods) {
-      if (method.isSetter) {
-
-        // TODO(ahe): This is a hack to remove setters corresponding to a field.
-        String name = n(method.simpleName);
-        name = name.substring(0, name.length - 1); // Remove '='.
-        if (fields[s(name)] != null) continue;
-
-        result[method.simpleName] = method;
-      }
-    }
-    return _cachedSetters =
-        new UnmodifiableMapView<Symbol, MethodMirror>(result);
+    return _cachedSetters = new UnmodifiableMapView<Symbol, MethodMirror>(
+        filterSetters(_methods, variables));
   }
 
   Map<Symbol, VariableMirror> get variables {
@@ -1176,6 +1239,19 @@
     return _cachedMembers = new UnmodifiableMapView<Symbol, Mirror>(result);
   }
 
+  Map<Symbol, DeclarationMirror> get declarations {
+    if (_cachedDeclarations != null) return _cachedDeclarations;
+    var result = new Map<Symbol, DeclarationMirror>();
+    addToResult(Symbol key, Mirror value) {
+      result[key] = value;
+    }
+    members.forEach(addToResult);
+    constructors.forEach(addToResult);
+    typeVariables.forEach((tv) => result[tv.simpleName] = tv);
+    return _cachedDeclarations =
+        new UnmodifiableMapView<Symbol, DeclarationMirror>(result);
+  }
+
   InstanceMirror setField(Symbol fieldName, Object arg) {
     JsVariableMirror mirror = variables[fieldName];
     if (mirror != null && mirror.isStatic && !mirror.isFinal) {
@@ -1336,11 +1412,11 @@
   List<TypeVariableMirror> get typeVariables {
    if (_cachedTypeVariables != null) return _cachedTypeVariables;
    List result = new List();
-   List typeVars =
+   List typeVariables =
         JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor);
-    if (typeVars == null) return result;
-    for (int i = 0; i < typeVars.length; i++) {
-      TypeVariable typeVariable = JS('', 'init.metadata[#]', typeVars[i]);
+    if (typeVariables == null) return result;
+    for (int i = 0; i < typeVariables.length; i++) {
+      TypeVariable typeVariable = JS('', 'init.metadata[#]', typeVariables[i]);
       result.add(new JsTypeVariableMirror(typeVariable, this));
     }
     return _cachedTypeVariables = new UnmodifiableListView(result);
@@ -1583,7 +1659,7 @@
 
   TypeMirror get returnType {
     metadata; // Compute _returnType as a side-effect of extracting metadata.
-    return typeMirrorFromRuntimeTypeRepresentation(_returnType);
+    return computeTypeMirror(owner, _returnType);
   }
 
   List<InstanceMirror> get metadata {
@@ -1681,7 +1757,9 @@
 
   String get _prettyName => 'ParameterMirror';
 
-  TypeMirror get type => typeMirrorFromRuntimeTypeRepresentation(_type);
+  TypeMirror get type {
+    return computeTypeMirror(owner, _type);
+  }
 
   // Only true for static fields, never for a parameter.
   bool get isStatic => false;
@@ -1707,11 +1785,12 @@
 
 class JsTypedefMirror extends JsDeclarationMirror implements TypedefMirror {
   final String _mangledName;
-  final JsFunctionTypeMirror referent;
+  JsFunctionTypeMirror referent;
 
   JsTypedefMirror(Symbol simpleName,  this._mangledName, _typeData)
-      : referent = new JsFunctionTypeMirror(_typeData),
-        super(simpleName);
+      : super(simpleName) {
+    referent = new JsFunctionTypeMirror(_typeData, this);
+  }
 
   JsFunctionTypeMirror get value => referent;
 
@@ -1723,8 +1802,9 @@
   String _cachedToString;
   TypeMirror _cachedReturnType;
   UnmodifiableListView<ParameterMirror> _cachedParameters;
+  DeclarationMirror owner;
 
-  JsFunctionTypeMirror(this._typeData);
+  JsFunctionTypeMirror(this._typeData, this.owner);
 
   bool get _hasReturnType => JS('bool', '"ret" in #', _typeData);
   get _returnType => JS('', '#.ret', _typeData);
@@ -1825,10 +1905,38 @@
   return reflectType(createRuntimeType(representation));
 }
 
+TypeMirror computeTypeMirror(DeclarationMirror owner, var type) {
+  if (type is! int) {
+    return typeMirrorFromRuntimeTypeRepresentation(type);
+  }
+  
+  ClassMirror ownerClass;
+  DeclarationMirror context = owner;
+    while(context != null) {
+    if (context is ClassMirror) {
+      ownerClass = context;
+      break;
+    }
+    context = context.owner;
+  }
+ 
+  TypeVariable typeVariable = JS('', 'init.metadata[#]', type);
+  Symbol name = new Symbol(typeVariable.name);
+  List<TypeVariableMirror> typeVariables = ownerClass.typeVariables;
+  for (int i = 0; i < typeVariables.length; i++) {
+    if (typeVariables[i].simpleName == name) {
+      if (ownerClass.isOriginalDeclaration) {
+        return typeVariables[i];
+      } else {
+        return ownerClass.typeArguments[i];
+      }
+    }
+  }
+}
+
 Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
   if (owner == null) return simpleName;
   String ownerName = n(owner.qualifiedName);
-  if (ownerName == '') return simpleName;
   return s('$ownerName.${n(simpleName)}');
 }
 
diff --git a/sdk/lib/_internal/lib/js_number.dart b/sdk/lib/_internal/lib/js_number.dart
index de6986e..1e3955c 100644
--- a/sdk/lib/_internal/lib/js_number.dart
+++ b/sdk/lib/_internal/lib/js_number.dart
@@ -58,8 +58,14 @@
   }
 
   num abs() => JS('num', r'Math.abs(#)', this);
+  
+  static const int _MIN_INT32 = -0x80000000;
+  static const int _MAX_INT32 = 0x7FFFFFFF;
 
   int toInt() {
+    if (this >= _MIN_INT32 && this <= _MAX_INT32) {
+      return JS('int', '# | 0', this);
+    }
     if (JS('bool', r'isFinite(#)', this)) {
       return JS('int', r'# + 0', truncateToDouble());  // Converts -0.0 to +0.0.
     }
diff --git a/sdk/lib/_internal/lib/platform_patch.dart b/sdk/lib/_internal/lib/platform_patch.dart
new file mode 100644
index 0000000..13fdeb8
--- /dev/null
+++ b/sdk/lib/_internal/lib/platform_patch.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+patch int get numberOfProcessors => null;
+
+patch String get pathSeparator => '/';
+
+patch String get operatingSystem => null;
+
+patch String get localHostname => null;
+
+patch String get version => null;
+
+patch Map<String, String> get environment => null;
+
+patch String get executable => null;
+
+patch Uri get script => null;
+
+// An unmodifiable list.
+patch List<String> get executableArguments => new List<String>(0);
+
+patch String get packageRoot => null;
diff --git a/sdk/lib/_internal/lib/regexp_helper.dart b/sdk/lib/_internal/lib/regexp_helper.dart
index 09fe861..1409c9b 100644
--- a/sdk/lib/_internal/lib/regexp_helper.dart
+++ b/sdk/lib/_internal/lib/regexp_helper.dart
@@ -150,8 +150,6 @@
     assert(JS("var", "#.index", _match) is int);
   }
 
-  // TODO(12843): Remove when grace period is over.
-  String get str => input;
   String get input => JS("String", "#.input", _match);
   int get start => JS("int", "#.index", _match);
   int get end => start + _match[0].length;
diff --git a/sdk/lib/_internal/lib/string_helper.dart b/sdk/lib/_internal/lib/string_helper.dart
index fa046d5..328cf29 100644
--- a/sdk/lib/_internal/lib/string_helper.dart
+++ b/sdk/lib/_internal/lib/string_helper.dart
@@ -28,9 +28,6 @@
     return result;
   }
 
-  // TODO(12843): Remove when grace period is over.
-  String get str => input;
-
   final int start;
   final String input;
   final String pattern;
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index 8da7a8c..6aa24dd 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -84,10 +84,6 @@
       maturity: Maturity.STABLE,
       dart2jsPath: "js/dart2js/js_dart2js.dart"),
 
-  "json": const LibraryInfo(
-      "json/json.dart",
-      maturity: Maturity.DEPRECATED),
-
   "math": const LibraryInfo(
       "math/math.dart",
       maturity: Maturity.STABLE,
@@ -95,7 +91,7 @@
 
   "mirrors": const LibraryInfo(
       "mirrors/mirrors.dart",
-      maturity: Maturity.UNSTABLE, 
+      maturity: Maturity.UNSTABLE,
       dart2jsPatchPath: "_internal/lib/mirrors_patch.dart"),
 
   "nativewrappers": const LibraryInfo(
@@ -105,6 +101,11 @@
       documented: false,
       platforms: VM_PLATFORM),
 
+  "platform": const LibraryInfo(
+      "platform/platform.dart",
+      maturity: Maturity.UNSTABLE,
+      dart2jsPatchPath: "_internal/lib/platform_patch.dart"),
+
   "typed_data": const LibraryInfo(
       "typed_data/typed_data.dart",
       maturity: Maturity.STABLE,
@@ -266,23 +267,23 @@
   final int level;
   final String name;
   final String description;
-  
+
   const Maturity(this.level, this.name, this.description);
-  
+
   String toString() => "$name: $level\n$description\n";
 
   static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
     "This library will be remove before next major release.");
-  
+
   static const Maturity EXPERIMENTAL = const Maturity(1, "Experimental",
     "This library is experimental and will likely change or be removed\n"
     "in future versions.");
-  
+
   static const Maturity UNSTABLE = const Maturity(2, "Unstable",
     "This library is in still changing and have not yet endured\n"
     "sufficient real-world testing.\n"
     "Backwards-compatibility is NOT guaranteed.");
-  
+
   static const Maturity WEB_STABLE = const Maturity(3, "Web Stable",
     "This library is tracking the DOM evolution as defined by WC3.\n"
     "Backwards-compatibility is NOT guaranteed.");
@@ -290,7 +291,7 @@
   static const Maturity STABLE = const Maturity(4, "Stable",
     "The library is stable. API backwards-compatibility is guaranteed.\n"
     "However implementation details might change.");
-  
+
   static const Maturity LOCKED = const Maturity(5, "Locked",
     "This library will not change except when serious bugs are encountered.");
 
diff --git a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
index bb51df0..d79cec7 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
@@ -7,7 +7,7 @@
 import 'dart:async';
 import 'dart:io';
 
-import 'package:analyzer_experimental/analyzer.dart';
+import 'package:analyzer/analyzer.dart';
 import 'package:barback/barback.dart';
 import 'package:path/path.dart' as path;
 
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 5481a50..3eb02b7 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
@@ -32,9 +32,11 @@
 import 'http://<<HOST_AND_PORT>>/packages/barback/barback.dart';
 
 /// Sets up the initial communication with the host isolate.
-void main() {
-  port.receive((args, replyTo) {
-    _sendFuture(replyTo, new Future.sync(() {
+void main(List<String> args, SendPort replyTo) {
+  var port = new ReceivePort();
+  replyTo.send(['success', port.sendPort]);
+  port.listen((args) {
+    _sendFuture(args['replyTo'], new Future.sync(() {
       var library = Uri.parse(args['library']);
       var configuration = JSON.decode(args['configuration']);
       return initialize(library, configuration).
@@ -112,10 +114,10 @@
   }
 
   Future<Asset> getInput(AssetId id) {
-    return _receiveFuture(_port.call({
+    return _callAndReceiveFuture(_port, {
       'type': 'getInput',
       'id': _serializeId(id)
-    })).then(_deserializeAsset);
+    }).then(_deserializeAsset);
   }
 
   Future<String> readInputAsString(AssetId id, {Encoding encoding}) {
@@ -181,7 +183,8 @@
 /// Converts [transformer] into a serializable map.
 Map _serializeTransformer(Transformer transformer) {
   var port = new ReceivePort();
-  port.receive((message, replyTo) {
+  port.listen((message) {
+    var replyTo = message['replyTo'];
     _sendFuture(replyTo, new Future.sync(() {
       if (message['type'] == 'isPrimary') {
         return transformer.isPrimary(_deserializeAsset(message['asset']));
@@ -196,7 +199,7 @@
   return {
     'type': 'Transformer',
     'toString': transformer.toString(),
-    'port': port.toSendPort()
+    'port': port.sendPort
   };
 }
 
@@ -211,11 +214,29 @@
   };
 }
 
+/// When the input receives a 'done' as data-event, transforms it to a
+/// done event and cancels the subscription.
+StreamSubscription doneTransformer(Stream input, bool cancelOnError) {
+  var subscription;
+  var transformed = input.transform(new StreamTransformer.fromHandlers(
+      handleData: (data, sink) {
+        if (data == 'done') {
+          sink.close();
+          subscription.cancel();
+        } else {
+          sink.add(data);
+        }
+      }));
+  subscription = transformed.listen(null, cancelOnError: cancelOnError);
+  return subscription;
+}
+
 /// Converts a serializable map into an [Asset].
 Asset _deserializeAsset(Map asset) {
-  var box = new MessageBox();
-  asset['sink'].add(box.sink);
-  return new Asset.fromStream(_deserializeId(asset['id']), box.stream);
+  var receivePort = new ReceivePort();
+  asset['sendPort'].send(receivePort.sendPort);
+  var stream = receivePort.transform(const StreamTransformer(doneTransformer));
+  return new Asset.fromStream(_deserializeId(asset['id']), stream);
 }
 
 /// Converts a serializable map into an [AssetId].
@@ -225,16 +246,18 @@
 Map _serializeAsset(Asset asset) {
   // We can't send IsolateStreams (issue 12437), so instead we send a sink and
   // get the isolate to send us back another sink.
-  var box = new MessageBox();
-  box.stream.first.then((sink) {
-    asset.read().listen(sink.add,
-        onError: sink.addError,
-        onDone: sink.close);
+  var receivePort = new ReceivePort();
+  receivePort.first.then((sendPort) {
+    asset.read().listen(sendPort.send,
+        onError: (error, stackTrace) {
+          throw new UnimplementedError('Error during asset serialization');
+        },
+        onDone: () { sendPort.send('done'); });
   });
 
   return {
     'id': _serializeId(asset.id),
-    'sink': box.sink
+    'sendPort': receivePort.sendPort
   };
 }
 
@@ -280,11 +303,18 @@
 
 /// Receives the result of [_sendFuture] from [portCall], which should be the
 /// return value of [SendPort.call].
-Future _receiveFuture(Future portCall) {
-  return portCall.then((response) {
-    if (response.containsKey('success')) return response['success'];
-    return new Future.error(
-        new CrossIsolateException.deserialize(response['error']));
+///
+/// The [message] argument is modified to include the [replyTo] port.
+Future _callAndReceiveFuture(SendPort port, Map message) {
+  var responsePort = new ReceivePort();
+  message['replyTo'] = responsePort.sendPort;
+  return new Future.sync(() {
+    port.send(message);
+    return responsePort.first.then((response) {
+      if (response.containsKey('success')) return response['success'];
+      return new Future.error(
+          new CrossIsolateException.deserialize(response['error']));
+    });
   });
 }
 
@@ -379,11 +409,11 @@
     log.fine("Loading transformers from $assetId");
 
     return dart.runInIsolate(code).then((sendPort) {
-      return _receiveFuture(sendPort.call({
+      return _callAndReceiveFuture(sendPort, {
         'library': uri,
         // TODO(nweiz): support non-JSON-encodable configuration maps.
         'configuration': JSON.encode(id.configuration)
-      })).then((transformers) {
+      }).then((transformers) {
         transformers = transformers.map(_deserializeTransformerOrGroup).toSet();
         log.fine("Transformers from $assetId: $transformers");
         return transformers;
@@ -422,17 +452,17 @@
         _toString = map['toString'];
 
   Future<bool> isPrimary(Asset asset) {
-    return _receiveFuture(_port.call({
+    return _callAndReceiveFuture(_port, {
       'type': 'isPrimary',
       'asset': _serializeAsset(asset)
-    }));
+    });
   }
 
   Future apply(Transform transform) {
-    return _receiveFuture(_port.call({
+    return _callAndReceiveFuture(_port, {
       'type': 'apply',
       'transform': _serializeTransform(transform)
-    }));
+    });
   }
 
   String toString() => _toString;
@@ -464,7 +494,8 @@
 /// Converts [transform] into a serializable map.
 Map _serializeTransform(Transform transform) {
   var receivePort = new ReceivePort();
-  receivePort.receive((message, replyTo) {
+  receivePort.listen((message) {
+    var replyTo = message['replyTo'];
     if (message['type'] == 'getInput') {
       _sendFuture(replyTo, transform.getInput(_deserializeId(message['id']))
           .then(_serializeAsset));
@@ -492,16 +523,34 @@
   });
 
   return {
-    'port': receivePort.toSendPort(),
+    'port': receivePort.sendPort,
     'primaryInput': _serializeAsset(transform.primaryInput)
   };
 }
 
+/// When the input receives a 'done' as data-event, transforms it to a
+/// done event and cancels the subscription.
+StreamSubscription doneTransformer(Stream input, bool cancelOnError) {
+  var subscription;
+  var transformed = input.transform(new StreamTransformer.fromHandlers(
+      handleData: (data, sink) {
+        if (data == 'done') {
+          sink.close();
+          subscription.cancel();
+        } else {
+          sink.add(data);
+        }
+      }));
+  subscription = transformed.listen(null, cancelOnError: cancelOnError);
+  return subscription;
+}
+
 /// Converts a serializable map into an [Asset].
 Asset _deserializeAsset(Map asset) {
-  var box = new MessageBox();
-  asset['sink'].add(box.sink);
-  return new Asset.fromStream(_deserializeId(asset['id']), box.stream);
+  var receivePort = new ReceivePort();
+  asset['sendPort'].send(receivePort.sendPort);
+  var stream = receivePort.transform(const StreamTransformer(doneTransformer));
+  return new Asset.fromStream(_deserializeId(asset['id']), stream);
 }
 
 /// Converts a serializable map into an [AssetId].
@@ -528,16 +577,18 @@
 Map _serializeAsset(Asset asset) {
   // We can't send IsolateStreams (issue 12437), so instead we send a sink and
   // get the isolate to send us back another sink.
-  var box = new MessageBox();
-  box.stream.first.then((sink) {
-    asset.read().listen(sink.add,
-        onError: sink.addError,
-        onDone: sink.close);
+  var receivePort = new ReceivePort();
+  receivePort.first.then((sendPort) {
+    asset.read().listen(sendPort.send,
+        onError: (error, stackTrace) {
+          throw new UnimplementedError('Error during asset serialization');
+        },
+        onDone: () { sendPort.send('done'); });
   });
 
   return {
     'id': _serializeId(asset.id),
-    'sink': box.sink
+    'sendPort': receivePort.sendPort
   };
 }
 
@@ -546,7 +597,7 @@
 
 /// Sends the result of [future] through [port].
 ///
-/// This should be received on the other end using [_receiveFuture]. It
+/// This should be received on the other end using [_callAndReceiveFuture]. It
 /// re-raises any exceptions on the other side as [dart.CrossIsolateException]s.
 void _sendFuture(SendPort port, Future future) {
   future.then((result) {
@@ -559,10 +610,17 @@
 
 /// Receives the result of [_sendFuture] from [portCall], which should be the
 /// return value of [SendPort.call].
-Future _receiveFuture(Future portCall) {
-  return portCall.then((response) {
-    if (response.containsKey('success')) return response['success'];
-    return new Future.error(
-        new dart.CrossIsolateException.deserialize(response['error']));
+///
+/// The [message] argument is modified to include the [replyTo] port.
+Future _callAndReceiveFuture(SendPort port, Map message) {
+  var responsePort = new ReceivePort();
+  message['replyTo'] = responsePort.sendPort;
+  return new Future.sync(() {
+    port.send(message);
+    return responsePort.first.then((response) {
+      if (response.containsKey('success')) return response['success'];
+      return new Future.error(
+          new dart.CrossIsolateException.deserialize(response['error']));
+    });
   });
 }
diff --git a/sdk/lib/_internal/pub/lib/src/barback/rewrite_import_transformer.dart b/sdk/lib/_internal/pub/lib/src/barback/rewrite_import_transformer.dart
index 072a4c2..bcaf500 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/rewrite_import_transformer.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/rewrite_import_transformer.dart
@@ -7,7 +7,7 @@
 import 'dart:async';
 
 import 'package:barback/barback.dart';
-import 'package:analyzer_experimental/analyzer.dart';
+import 'package:analyzer/analyzer.dart';
 
 /// A transformer used internally to rewrite "package:" imports so they point to
 /// the barback server rather than to pub's package root.
diff --git a/sdk/lib/_internal/pub/lib/src/barback/server.dart b/sdk/lib/_internal/pub/lib/src/barback/server.dart
index a427679..ec417b1 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/server.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/server.dart
@@ -109,7 +109,7 @@
             new BarbackServerResult._failure(request.uri, id, error));
 
         // If we couldn't read the asset, handle the error gracefully.
-        if (error is FileException) {
+        if (error is FileSystemException) {
           // Assume this means the asset was a file-backed source asset
           // and we couldn't read it, so treat it like a missing asset.
           _notFound(request, error);
diff --git a/sdk/lib/_internal/pub/lib/src/barback/watch_sources.dart b/sdk/lib/_internal/pub/lib/src/barback/watch_sources.dart
index bc1c7ec..6a176aa 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/watch_sources.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/watch_sources.dart
@@ -20,9 +20,20 @@
     // Add the initial sources.
     barback.updateSources(_listAssets(graph.entrypoint, package));
 
+    // If this package comes from a cached source, its contents won't change so
+    // we don't need to monitor it. `packageId` will be null for the application
+    // package, since that's not locked.
+    var packageId = graph.lockFile.packages[package.name];
+    if (packageId != null &&
+        graph.entrypoint.cache.sources[packageId.source].shouldCache) {
+      continue;
+    }
+
     // Watch the visible package directories for changes.
     for (var name in _getPublicDirectories(graph.entrypoint, package)) {
       var subdirectory = path.join(package.dir, name);
+      if (!dirExists(subdirectory)) continue;
+
       // TODO(nweiz): close these watchers when [barback] is closed.
       var watcher = new DirectoryWatcher(subdirectory);
       watcher.events.listen((event) {
diff --git a/sdk/lib/_internal/pub/lib/src/dart.dart b/sdk/lib/_internal/pub/lib/src/dart.dart
index 82686ca..e0701a4 100644
--- a/sdk/lib/_internal/pub/lib/src/dart.dart
+++ b/sdk/lib/_internal/pub/lib/src/dart.dart
@@ -8,7 +8,7 @@
 import 'dart:async';
 import 'dart:isolate';
 
-import 'package:analyzer_experimental/analyzer.dart';
+import 'package:analyzer/analyzer.dart';
 import 'package:path/path.dart' as path;
 import 'package:stack_trace/stack_trace.dart';
 import '../../../compiler/compiler.dart' as compiler;
@@ -92,14 +92,18 @@
   return withTempDir((dir) {
     var dartPath = path.join(dir, 'runInIsolate.dart');
     writeTextFile(dartPath, code, dontLogContents: true);
-    var bufferPort = spawnFunction(_isolateBuffer);
-    return bufferPort.call(path.toUri(dartPath).toString()).then((response) {
-      if (response.first == 'error') {
-        return new Future.error(
-            new CrossIsolateException.deserialize(response.last));
-      }
+    var port = new ReceivePort();
+    var initialMessage =  [path.toUri(dartPath).toString(), port.sendPort];
+    var isolate = Isolate.spawn(_isolateBuffer, initialMessage);
+    return isolate.then((_) {
+      return port.first.then((response) {
+        if (response.first == 'error') {
+          return new Future.error(
+              new CrossIsolateException.deserialize(response.last));
+        }
 
-      return response.last;
+        return response.last;
+      });
     });
   });
 }
@@ -110,14 +114,18 @@
 /// [spawnUri] synchronously loads the file and its imports, which can deadlock
 /// the host isolate if there's an HTTP import pointing at a server in the host.
 /// Adding an additional isolate in the middle works around this.
-void _isolateBuffer() {
-  port.receive((uri, replyTo) {
-    try {
-      replyTo.send(['success', spawnUri(uri)]);
-    } catch (e, stack) {
+void _isolateBuffer(initialMessage) {
+  var uri = initialMessage[0];
+  var replyTo = initialMessage[1];
+  try {
+    // TODO(floitsch): If we do it right we shouldn't need to have a try/catch
+    // and a catchError.
+    Isolate.spawnUri(Uri.parse(uri), [], replyTo).catchError((e, stack) {
       replyTo.send(['error', CrossIsolateException.serialize(e, stack)]);
-    }
-  });
+    });
+  } catch (e, stack) {
+    replyTo.send(['error', CrossIsolateException.serialize(e, stack)]);
+  }
 }
 
 /// An exception that was originally raised in another isolate.
diff --git a/sdk/lib/_internal/pub/lib/src/entrypoint.dart b/sdk/lib/_internal/pub/lib/src/entrypoint.dart
index 46367fa..c743b3a 100644
--- a/sdk/lib/_internal/pub/lib/src/entrypoint.dart
+++ b/sdk/lib/_internal/pub/lib/src/entrypoint.dart
@@ -215,7 +215,8 @@
   /// Loads the package graph for the application and all of its transitive
   /// dependencies.
   Future<PackageGraph> loadPackageGraph() {
-    return Future.wait(loadLockFile().packages.values.map((id) {
+    var lockFile = loadLockFile();
+    return Future.wait(lockFile.packages.values.map((id) {
       var source = cache.sources[id.source];
       return source.getDirectory(id)
           .then((dir) => new Package.load(id.name, dir, cache.sources));
@@ -225,7 +226,7 @@
         packageMap[package.name] = package;
       }
       packageMap[root.name] = root;
-      return new PackageGraph(this, packageMap);
+      return new PackageGraph(this, lockFile, packageMap);
     });
   }
 
diff --git a/sdk/lib/_internal/pub/lib/src/io.dart b/sdk/lib/_internal/pub/lib/src/io.dart
index 55827c1..b4f6d91 100644
--- a/sdk/lib/_internal/pub/lib/src/io.dart
+++ b/sdk/lib/_internal/pub/lib/src/io.dart
@@ -216,7 +216,7 @@
 
   try {
     createDir(dirPath);
-  } on DirectoryException catch (ex) {
+  } on FileSystemException catch (ex) {
     // Error 17 means the directory already exists (or 183 on Windows).
     if (ex.osError.errorCode == 17 || ex.osError.errorCode == 183) {
       log.fine("Got 'already exists' error when creating directory.");
diff --git a/sdk/lib/_internal/pub/lib/src/package_graph.dart b/sdk/lib/_internal/pub/lib/src/package_graph.dart
index 634eb5c..0e2b8e0 100644
--- a/sdk/lib/_internal/pub/lib/src/package_graph.dart
+++ b/sdk/lib/_internal/pub/lib/src/package_graph.dart
@@ -14,10 +14,16 @@
   /// The entrypoint.
   final Entrypoint entrypoint;
 
+  /// The entrypoint's lockfile.
+  ///
+  /// This describes the sources and resolved descriptions of everything in
+  /// [packages].
+  final LockFile lockFile;
+
   /// All transitive dependencies of the entrypoint (including itself).
   final Map<String, Package> packages;
 
-  PackageGraph(this.entrypoint, this.packages);
+  PackageGraph(this.entrypoint, this.lockFile, this.packages);
 
   /// Returns the set of transitive dependencies of the package named
   /// [packageName].
diff --git a/sdk/lib/_internal/pub/lib/src/utils.dart b/sdk/lib/_internal/pub/lib/src/utils.dart
index 392310b..8a63d52 100644
--- a/sdk/lib/_internal/pub/lib/src/utils.dart
+++ b/sdk/lib/_internal/pub/lib/src/utils.dart
@@ -12,7 +12,7 @@
 import 'dart:isolate';
 import 'dart:mirrors';
 
-import "package:analyzer_experimental/analyzer.dart";
+import "package:analyzer/analyzer.dart";
 import "package:crypto/crypto.dart";
 import 'package:path/path.dart' as path;
 
@@ -713,9 +713,8 @@
   // invalid import.
   'IsolateSpawnException',
   // TODO(nweiz): clean up the dart:io errors when issue 9955 is fixed.
-  'DirectoryException', 'FileException', 'HttpException', 'HttpException',
-  'LinkException', 'OSError', 'ProcessException', 'SocketException',
-  'WebSocketException'
+  'FileSystemException', 'HttpException', 'HttpException', 'OSError',
+  'ProcessException', 'SocketException', 'WebSocketException'
 ]);
 
 /// Returns whether [error] is a user-facing error object. This includes both
@@ -731,11 +730,9 @@
     error is AnalyzerError ||
     error is AnalyzerErrorGroup ||
     error is IsolateSpawnException ||
-    error is DirectoryException ||
-    error is FileException ||
+    error is FileSystemException ||
     error is HttpException ||
     error is HttpException ||
-    error is LinkException ||
     error is OSError ||
     error is ProcessException ||
     error is SocketException ||
diff --git a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_an_import_error_test.dart b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_an_import_error_test.dart
index fbb4281..2da4b93 100644
--- a/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_an_import_error_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/fails_to_load_a_transform_with_an_import_error_test.dart
@@ -26,7 +26,6 @@
     ]).create();
 
     createLockFile('myapp', pkg: ['barback']);
-
     var pub = startPub(args: ['serve', '--port=0', "--hostname=127.0.0.1"]);
     expect(pub.nextErrLine(), completion(matches(new RegExp(
         r"Error: line 1 pos 1: library handler failed$"))));
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index 89590b9..f15073f 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -6,14 +6,28 @@
  * Support for asynchronous programming,
  * with classes such as Future and Stream.
  *
- * For an introduction to using dart:async, see the
+ * For an introduction to asynchronous programming in Dart, see the
  * [dart:async section of the language tour]
  * (https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-asynchronous-programming).
- * Also see
- * [articles](https://www.dartlang.org/articles/)
- * such as
- * [Using Future Based APIs]
- * (https://www.dartlang.org/articles/using-future-based-apis/).
+ *
+ * ## Other Resources
+ *
+ * * [Using Future Based APIs]
+ * (https://www.dartlang.org/articles/using-future-based-apis/): A first look at
+ * Futures and how to use them to write asynchronous Dart code.
+ *
+ * * [Futures and Error Handling]
+ * (https://www.dartlang.org/articles/futures-and-error-handling/): Everything
+ * you wanted to know about handling errors and exceptions when working with
+ * Futures (but were afraid to ask).
+ *
+ * * [The Event Loop and Dart](https://www.dartlang.org/articles/event-loop/):
+ * Learn how Dart handles the event queue and microtask queue, so you can write
+ * better asynchronous code with fewer surprises.
+ *
+ * * [Asynchronous Unit Testing with Dart]
+ * (https://www.dartlang.org/articles/dart-unit-tests/#asynchronous-tests): How
+ * to test asynchronous code.
  */
 library dart.async;
 
diff --git a/sdk/lib/async/async_error.dart b/sdk/lib/async/async_error.dart
index d28c45b..0990d4d 100644
--- a/sdk/lib/async/async_error.dart
+++ b/sdk/lib/async/async_error.dart
@@ -6,7 +6,7 @@
 
 final Expando _stackTraceExpando = new Expando("asynchronous error");
 
-void _attachStackTrace(o, st) {
+void _attachStackTrace(o, StackTrace st) {
   if (o == null || o is bool || o is num || o is String) return;
   _stackTraceExpando[o] = st;
 }
diff --git a/sdk/lib/async/broadcast_stream_controller.dart b/sdk/lib/async/broadcast_stream_controller.dart
index 0691955..2e43669 100644
--- a/sdk/lib/async/broadcast_stream_controller.dart
+++ b/sdk/lib/async/broadcast_stream_controller.dart
@@ -218,7 +218,7 @@
     _sendData(data);
   }
 
-  void addError(Object error, [Object stackTrace]) {
+  void addError(Object error, [StackTrace stackTrace]) {
     if (!_mayAddEvent) throw _addEventError();
     if (stackTrace != null) _attachStackTrace(error, stackTrace);
     _sendError(error, stackTrace);
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index fd013f1..335714b 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -174,7 +174,7 @@
    *
    * See [Completer] to create a Future and complete it later.
    */
-  factory Future.error(var error, [Object stackTrace]) {
+  factory Future.error(Object error, [StackTrace stackTrace]) {
     return new _Future<T>.immediateError(error, stackTrace);
   }
 
@@ -497,9 +497,9 @@
    * Completing a future with an error indicates that an exception was thrown
    * while trying to produce a value.
    *
-   * The argument [exception] must not be `null`.
+   * The argument [error] must not be `null`.
    */
-  void completeError(Object exception, [Object stackTrace]);
+  void completeError(Object error, [StackTrace stackTrace]);
 
   /**
    * Whether the future has been completed.
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 748a2be..1784458 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -16,7 +16,7 @@
 
   void complete([T value]);
 
-  void completeError(Object error, [Object stackTrace = null]);
+  void completeError(Object error, [StackTrace stackTrace]);
 
   // The future's _isComplete doesn't take into account pending completions.
   // We therefore use _mayComplete.
@@ -30,7 +30,7 @@
     future._asyncComplete(value);
   }
 
-  void completeError(Object error, [Object stackTrace = null]) {
+  void completeError(Object error, [StackTrace stackTrace]) {
     if (!future._mayComplete) throw new StateError("Future already completed");
     future._asyncCompleteError(error, stackTrace);
   }
@@ -43,7 +43,7 @@
     future._complete(value);
   }
 
-  void completeError(Object error, [Object stackTrace = null]) {
+  void completeError(Object error, [StackTrace stackTrace]) {
     if (!future._mayComplete) throw new StateError("Future already completed");
     future._completeError(error, stackTrace);
   }
@@ -151,7 +151,7 @@
     _asyncComplete(value);
   }
 
-  _Future.immediateError(var error, [Object stackTrace])
+  _Future.immediateError(var error, [StackTrace stackTrace])
       : _zone = Zone.current,
         _onValueCallback = null, _errorTestCallback = null,
         _onErrorCallback = null, _whenCompleteActionCallback = null {
@@ -359,7 +359,7 @@
     });
   }
 
-  void _asyncCompleteError(error, [StackTrace stackTrace]) {
+  void _asyncCompleteError(error, StackTrace stackTrace) {
     assert(!_isComplete);
     assert(_onValue == null);
     assert(_onError == null);
diff --git a/sdk/lib/async/schedule_microtask.dart b/sdk/lib/async/schedule_microtask.dart
index c732874..dca72df 100644
--- a/sdk/lib/async/schedule_microtask.dart
+++ b/sdk/lib/async/schedule_microtask.dart
@@ -36,23 +36,29 @@
 }
 
 /**
- * Runs the given [callback] asynchronously.
+ * Runs a function asynchronously.
  *
  * Callbacks registered through this function are always executed in order and
  * are guaranteed to run before other asynchronous events (like [Timer] events,
  * or DOM events).
  *
- * Warning: it is possible to starve the DOM by registering asynchronous
+ * **Warning:** it is possible to starve the DOM by registering asynchronous
  * callbacks through this method. For example the following program runs
  * the callbacks without ever giving the Timer callback a chance to execute:
  *
- *     Timer.run(() { print("executed"); });  // Will never be executed;
+ *     Timer.run(() { print("executed"); });  // Will never be executed,
  *     foo() {
  *       scheduleMicrotask(foo);  // Schedules [foo] in front of other events.
  *     }
  *     main() {
  *       foo();
  *     }
+ *
+ * ## Other Resources
+ *
+ * * [The Event Loop and Dart](https://www.dartlang.org/articles/event-loop/):
+ * Learn how Dart handles the event queue and microtask queue, so you can write
+ * better asynchronous code with fewer surprises.
  */
 void scheduleMicrotask(void callback()) {
   if (Zone.current == Zone.ROOT) {
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index 0d82c72..ba3fd61 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -166,7 +166,7 @@
    * Also allows an objection stack trace object, on top of what [EventSink]
    * allows.
    */
-  void addError(Object error, [Object stackTrace]);
+  void addError(Object error, [StackTrace stackTrace]);
 }
 
 
@@ -375,7 +375,7 @@
   /**
    * Send or enqueue an error event.
    */
-  void addError(Object error, [Object stackTrace]) {
+  void addError(Object error, [StackTrace stackTrace]) {
     if (!_mayAddEvent) throw _badEventState();
     if (stackTrace != null) {
       // Force stack trace overwrite. Even if the error already contained
diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart
index 692deea8..5924084 100644
--- a/sdk/lib/async/stream_pipe.dart
+++ b/sdk/lib/async/stream_pipe.dart
@@ -8,7 +8,7 @@
  * Utility function to attach a stack trace to an [error]  if it doesn't have
  * one already.
  */
-_asyncError(Object error, Object stackTrace) {
+_asyncError(Object error, StackTrace stackTrace) {
   if (stackTrace == null) return error;
   if (getAttachedStackTrace(error) != null) return error;
   _attachStackTrace(error, stackTrace);
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index 2306a6e..d7acc39 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -64,29 +64,29 @@
    */
   const factory ZoneSpecification({
     dynamic handleUncaughtError(Zone self, ZoneDelegate parent, Zone zone,
-                                error, StackTrace stackTrace): null,
-    dynamic run(Zone self, ZoneDelegate parent, Zone zone, f()): null,
+                                error, StackTrace stackTrace),
+    dynamic run(Zone self, ZoneDelegate parent, Zone zone, f()),
     dynamic runUnary(
-        Zone self, ZoneDelegate parent, Zone zone, f(arg), arg): null,
+        Zone self, ZoneDelegate parent, Zone zone, f(arg), arg),
     dynamic runBinary(Zone self, ZoneDelegate parent, Zone zone,
-                      f(arg1, arg2), arg1, arg2): null,
+                      f(arg1, arg2), arg1, arg2),
     ZoneCallback registerCallback(
-        Zone self, ZoneDelegate parent, Zone zone, f()): null,
+        Zone self, ZoneDelegate parent, Zone zone, f()),
     ZoneUnaryCallback registerUnaryCallback(
-        Zone self, ZoneDelegate parent, Zone zone, f(arg)): null,
+        Zone self, ZoneDelegate parent, Zone zone, f(arg)),
     ZoneBinaryCallback registerBinaryCallback(
-        Zone self, ZoneDelegate parent, Zone zone, f(arg1, arg2)): null,
+        Zone self, ZoneDelegate parent, Zone zone, f(arg1, arg2)),
     void scheduleMicrotask(
-        Zone self, ZoneDelegate parent, Zone zone, f()): null,
+        Zone self, ZoneDelegate parent, Zone zone, f()),
     void runAsync(
-        Zone self, ZoneDelegate parent, Zone zone, f()): null,
+        Zone self, ZoneDelegate parent, Zone zone, f()),
     Timer createTimer(Zone self, ZoneDelegate parent, Zone zone,
-                      Duration duration, void f()): null,
+                      Duration duration, void f()),
     Timer createPeriodicTimer(Zone self, ZoneDelegate parent, Zone zone,
-                              Duration period, void f(Timer timer)): null,
-    void print(Zone self, ZoneDelegate parent, Zone zone, String line): null,
+                              Duration period, void f(Timer timer)),
+    void print(Zone self, ZoneDelegate parent, Zone zone, String line),
     Zone fork(Zone self, ZoneDelegate parent, Zone zone,
-              ZoneSpecification specification, Map zoneValues): null
+              ZoneSpecification specification, Map zoneValues)
   }) = _ZoneSpecification;
 
   /**
@@ -701,16 +701,18 @@
 
 void _rootHandleUncaughtError(
     Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) {
-  _scheduleAsyncCallback(() {
-    print("Uncaught Error: ${error}");
-    var trace = stackTrace;
-    if (trace == null) trace = getAttachedStackTrace(error);
-    // Clear the attached stack trace (if any).
-    _attachStackTrace(error, null);
-    if (trace != null) {
-      print("Stack Trace: \n$trace\n");
-    }
-    throw error;
+  self.run(() {
+    _scheduleAsyncCallback(() {
+      print("Uncaught Error: ${error}");
+      var trace = stackTrace;
+      if (trace == null) trace = getAttachedStackTrace(error);
+      // Clear the attached stack trace (if any).
+      _attachStackTrace(error, null);
+      if (trace != null) {
+        print("Stack Trace: \n$trace\n");
+      }
+      throw error;
+    });
   });
 }
 
diff --git a/sdk/lib/convert/convert.dart b/sdk/lib/convert/convert.dart
index e76133b..8cdc936 100644
--- a/sdk/lib/convert/convert.dart
+++ b/sdk/lib/convert/convert.dart
@@ -9,7 +9,7 @@
 library dart.convert;
 
 import 'dart:async';
-import 'dart:json' as OLD_JSON_LIB;
+import "dart:collection" show HashSet;
 
 part 'ascii.dart';
 part 'byte_conversion.dart';
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index 9780200..be503b0 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -17,16 +17,16 @@
 class JsonUnsupportedObjectError extends Error {
   /** The object that could not be serialized. */
   final unsupportedObject;
-  /** The exception thrown by object's [:toJson:] method, if any. */
+  /** The exception thrown when trying to convert the object. */
   final cause;
 
   JsonUnsupportedObjectError(this.unsupportedObject, { this.cause });
 
   String toString() {
     if (cause != null) {
-      return "Calling toJson method on object failed.";
+      return "Converting object to an encodable object failed.";
     } else {
-      return "Object toJson method returns non-serializable value.";
+      return "Converting object did not return an encodable object.";
     }
   }
 }
@@ -86,8 +86,9 @@
    *
    * The default [reviver] (when not provided) is the identity function.
    */
-  Object decode(String str, {reviver(var key, var value)}) {
-    return new JsonDecoder(reviver).convert(str);
+  Object decode(String source, {reviver(var key, var value)}) {
+    if (reviver == null) return decoder.convert(source);
+    return new JsonDecoder(reviver).convert(source);
   }
 
   /**
@@ -102,11 +103,12 @@
    * unencodable object.
    */
   Object encode(Object value, {toEncodable(var object)}) {
+    if (toEncodable == null) return encoder.convert(value);
     return new JsonEncoder(toEncodable).convert(value);
   }
 
-  JsonEncoder get encoder => new JsonEncoder();
-  JsonDecoder get decoder => new JsonDecoder(null);
+  JsonEncoder get encoder => const JsonEncoder();
+  JsonDecoder get decoder => const JsonDecoder(null);
 }
 
 typedef _Reviver(var key, var value);
@@ -115,9 +117,9 @@
   final _Reviver _reviver;
   _ReviverJsonCodec(this._reviver);
 
-  Object decode(String str, {reviver(var key, var value)}) {
+  Object decode(String source, {reviver(var key, var value)}) {
     if (reviver == null) reviver = _reviver;
-    return new JsonDecoder(reviver).convert(str);
+    return new JsonDecoder(reviver).convert(source);
   }
 
   JsonDecoder get decoder => new JsonDecoder(_reviver);
@@ -141,7 +143,7 @@
    * If [toEncodable] is omitted, it defaults to calling `.toJson()` on
    * the object.
    */
-  JsonEncoder([Object toEncodable(Object nonSerializable)])
+  const JsonEncoder([Object toEncodable(Object nonSerializable)])
       : this._toEncodableFunction = toEncodable;
 
   /**
@@ -171,7 +173,8 @@
    * the JSON text for it. I.e., if an object changes after it is first
    * serialized, the new values may or may not be reflected in the result.
    */
-  String convert(Object o) => OLD_JSON_LIB.stringify(o, _toEncodableFunction);
+  String convert(Object o) =>
+      _JsonStringifier.stringify(o, _toEncodableFunction);
 
   /**
    * Starts a chunked conversion.
@@ -219,7 +222,7 @@
     }
     _isDone = true;
     ClosableStringSink stringSink = _sink.asStringSink();
-    OLD_JSON_LIB.printOn(o, stringSink, _toEncodableFunction);
+    _JsonStringifier.printOn(o, stringSink, _toEncodableFunction);
     stringSink.close();
   }
 
@@ -236,7 +239,7 @@
    *
    * The [reviver] may be `null`.
    */
-  JsonDecoder(reviver(var key, var value)) : this._reviver = reviver;
+  const JsonDecoder(reviver(var key, var value)) : this._reviver = reviver;
 
   /**
    * Converts the given JSON-string [input] to its corresponding object.
@@ -297,3 +300,185 @@
 
 // Internal optimized JSON parsing implementation.
 external _parseJson(String source, reviver(key, value));
+
+
+// Implementation of encoder/stringifier.
+
+Object _defaultToEncodable(object) => object.toJson();
+
+class _JsonStringifier {
+  // Character code constants.
+  static const int BACKSPACE       = 0x08;
+  static const int TAB             = 0x09;
+  static const int NEWLINE         = 0x0a;
+  static const int CARRIAGE_RETURN = 0x0d;
+  static const int FORM_FEED       = 0x0c;
+  static const int QUOTE           = 0x22;
+  static const int BACKSLASH       = 0x5c;
+  static const int CHAR_b          = 0x62;
+  static const int CHAR_f          = 0x66;
+  static const int CHAR_n          = 0x6e;
+  static const int CHAR_r          = 0x72;
+  static const int CHAR_t          = 0x74;
+  static const int CHAR_u          = 0x75;
+
+  final Function toEncodable;
+  final StringSink sink;
+  final Set<Object> seen;
+
+  _JsonStringifier(this.sink, this.toEncodable)
+      : this.seen = new HashSet.identity();
+
+  static String stringify(final object, toEncodable(object)) {
+    if (toEncodable == null) toEncodable = _defaultToEncodable;
+    StringBuffer output = new StringBuffer();
+    _JsonStringifier stringifier = new _JsonStringifier(output, toEncodable);
+    stringifier.stringifyValue(object);
+    return output.toString();
+  }
+
+  static void printOn(final object, StringSink output, toEncodable(object)) {
+    _JsonStringifier stringifier = new _JsonStringifier(output, toEncodable);
+    stringifier.stringifyValue(object);
+  }
+
+  static String numberToString(num x) {
+    return x.toString();
+  }
+
+  // ('0' + x) or ('a' + x - 10)
+  static int hexDigit(int x) => x < 10 ? 48 + x : 87 + x;
+
+  static void escape(StringSink sb, String s) {
+    final int length = s.length;
+    bool needsEscape = false;
+    final charCodes = new List<int>();
+    for (int i = 0; i < length; i++) {
+      int charCode = s.codeUnitAt(i);
+      if (charCode < 32) {
+        needsEscape = true;
+        charCodes.add(BACKSLASH);
+        switch (charCode) {
+        case BACKSPACE:
+          charCodes.add(CHAR_b);
+          break;
+        case TAB:
+          charCodes.add(CHAR_t);
+          break;
+        case NEWLINE:
+          charCodes.add(CHAR_n);
+          break;
+        case FORM_FEED:
+          charCodes.add(CHAR_f);
+          break;
+        case CARRIAGE_RETURN:
+          charCodes.add(CHAR_r);
+          break;
+        default:
+          charCodes.add(CHAR_u);
+          charCodes.add(hexDigit((charCode >> 12) & 0xf));
+          charCodes.add(hexDigit((charCode >> 8) & 0xf));
+          charCodes.add(hexDigit((charCode >> 4) & 0xf));
+          charCodes.add(hexDigit(charCode & 0xf));
+          break;
+        }
+      } else if (charCode == QUOTE || charCode == BACKSLASH) {
+        needsEscape = true;
+        charCodes.add(BACKSLASH);
+        charCodes.add(charCode);
+      } else {
+        charCodes.add(charCode);
+      }
+    }
+    sb.write(needsEscape ? new String.fromCharCodes(charCodes) : s);
+  }
+
+  void checkCycle(final object) {
+    if (seen.contains(object)) {
+      throw new JsonCyclicError(object);
+    }
+    seen.add(object);
+  }
+
+  void stringifyValue(final object) {
+    // Tries stringifying object directly. If it's not a simple value, List or
+    // Map, call toJson() to get a custom representation and try serializing
+    // that.
+    if (!stringifyJsonValue(object)) {
+      checkCycle(object);
+      try {
+        var customJson = toEncodable(object);
+        if (!stringifyJsonValue(customJson)) {
+          throw new JsonUnsupportedObjectError(object);
+        }
+        seen.remove(object);
+      } catch (e) {
+        throw new JsonUnsupportedObjectError(object, cause: e);
+      }
+    }
+  }
+
+  /**
+   * Serializes a [num], [String], [bool], [Null], [List] or [Map] value.
+   *
+   * Returns true if the value is one of these types, and false if not.
+   * If a value is both a [List] and a [Map], it's serialized as a [List].
+   */
+  bool stringifyJsonValue(final object) {
+    if (object is num) {
+      // TODO: use writeOn.
+      sink.write(numberToString(object));
+      return true;
+    } else if (identical(object, true)) {
+      sink.write('true');
+      return true;
+    } else if (identical(object, false)) {
+      sink.write('false');
+       return true;
+    } else if (object == null) {
+      sink.write('null');
+      return true;
+    } else if (object is String) {
+      sink.write('"');
+      escape(sink, object);
+      sink.write('"');
+      return true;
+    } else if (object is List) {
+      checkCycle(object);
+      List a = object;
+      sink.write('[');
+      if (a.length > 0) {
+        stringifyValue(a[0]);
+        // TODO: switch to Iterables.
+        for (int i = 1; i < a.length; i++) {
+          sink.write(',');
+          stringifyValue(a[i]);
+        }
+      }
+      sink.write(']');
+      seen.remove(object);
+      return true;
+    } else if (object is Map) {
+      checkCycle(object);
+      Map<String, Object> m = object;
+      sink.write('{');
+      bool first = true;
+      m.forEach((String key, Object value) {
+        if (!first) {
+          sink.write(',"');
+        } else {
+          sink.write('"');
+        }
+        escape(sink, key);
+        sink.write('":');
+        stringifyValue(value);
+        first = false;
+      });
+      sink.write('}');
+      seen.remove(object);
+      return true;
+    } else {
+      return false;
+    }
+  }
+}
diff --git a/sdk/lib/core/annotations.dart b/sdk/lib/core/annotations.dart
new file mode 100644
index 0000000..7bdc5f5
--- /dev/null
+++ b/sdk/lib/core/annotations.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart.core;
+
+/**
+ * The annotation "@Deprecated('expires when')" marks a feature as deprecated.
+ *
+ * The annotation "@deprecated" is a shorthand for deprecating until
+ * to an unspecified "next release".
+ *
+ * The intent of the "@Deprecated" annotation is to inform users of a feature
+ * that they should change their code, even if it is currently still working
+ * correctly.
+ *
+ * A deprecated feature is scheduled to be removed at a later time, possibly
+ * specified as the "expires" field of the annotation.
+ * This means that a deprecated feature should not be used, or code using it
+ * will break at some point in the future. If there is code using the feature,
+ * that code should be rewritten to not use the deprecated feature.
+ *
+ * A deprecated feature should document how the same effect can be achieved,
+ * so the programmer knows how to rewrite the code.
+ *
+ * The "@Deprecated" annotation applies to libraries, top-level declarations
+ * (variables, getters, setters, functions, classes and typedefs),
+ * class-level declarations (variables, getters, setters, methods, operators or
+ * constructors, whether static or not), named optional arguments and
+ * trailing optional positional parameters.
+ *
+ * Deprecation is transitive:
+ *
+ *  - If a library is deprecated, so is every member of it.
+ *  - If a class is deprecated, so is every member of it.
+ *  - If a variable is deprecated, so are its implicit getter and setter.
+ *
+ *
+ * A tool that processes Dart source code may report when:
+ *
+ * - the code imports a deprecated library.
+ * - the code exports a deprecated library, or any deprecated member of
+ *   a non-deprecated library.
+ * - the code refers statically to a deprecated declaration.
+ * - the code dynamically uses a member of an object with a statically known
+ *   type, where the member is deprecated on the static type of the object.
+ * - the code dynamically calls a method with an argument where the
+ *   corresponding optional parameter is deprecated on the object's static type.
+ *
+ *
+ * If the deprecated use is inside a library, class or method which is itself
+ * deprecated, the tool should not bother the user about it.
+ * A deprecated feature is expected to use other deprecated features.
+ */
+class Deprecated {
+  /**
+   * A description of when the deprecated feature is expected to be retired.
+   */
+  final String expires;
+
+  /**
+   * Create a deprecation annotation which specifies the expiration of the
+   * annotated feature.
+   *
+   * The [expires] argument should be readable by programmers, and should state
+   * when an annotated feature is expected to be removed.
+   * This can be specified, for example, as a date, as a release number, or
+   * as relative to some other change (like "when bug 4418 is fixed").
+   */
+  const Deprecated(String expires) : this.expires = expires;
+
+  String toString() => "Deprecated feature. Will be removed $expires";
+}
+
+class _Override {
+  const _Override();
+}
+
+/**
+ * Marks a feature as [Deprecated] until the next release.
+ */
+const deprecated = const Deprecated("next release");
+
+/*
+ * The annotation "@override" marks an instance member as overriding a
+ * superclass member with the same name.
+ *
+ * The annotation applies to instance methods, getters and setters, and to
+ * instance fields, where it means that the implicit getter and setter of the
+ * field is marked as overriding, but the field itself is not.
+ *
+ * A tool may report if no declaration of an annotated member is inherited by
+ * the class from either a superclass or an interface.
+ *
+ * The intent of the "override" notation is to catch situations where a
+ * superclass renames a member, and an independent subclass which used to
+ * override the member, could silently continue working using the
+ * superclass implementation.
+ *
+ * The "@override" annotation is intentionally not used in the core libraries.
+ * It is intended for the editor, or similar tools, to support user written
+ * code.
+ */
+const override = const _Override();
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index 627e6b2..7e84379 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -158,6 +158,7 @@
 import "dart:convert" show UTF8, Encoding;
 import "dart:math" show Random;  // Used by List.shuffle.
 
+part "annotations.dart";
 part "bool.dart";
 part "comparable.dart";
 part "date_time.dart";
diff --git a/sdk/lib/core/corelib_sources.gypi b/sdk/lib/core/corelib_sources.gypi
index 172f2e8..816d8f8 100644
--- a/sdk/lib/core/corelib_sources.gypi
+++ b/sdk/lib/core/corelib_sources.gypi
@@ -6,6 +6,7 @@
   'sources': [
     'core.dart',
     # The above file needs to be first as it lists the parts below.
+    'annotations.dart',
     'bool.dart',
     'comparable.dart',
     'date_time.dart',
diff --git a/sdk/lib/core/regexp.dart b/sdk/lib/core/regexp.dart
index f3b015e..840754e 100644
--- a/sdk/lib/core/regexp.dart
+++ b/sdk/lib/core/regexp.dart
@@ -86,14 +86,6 @@
   String get input;
 
   /**
-   * Deprecated alias for [input].
-   *
-   * Will be removed soon.
-   */
-  @deprecated
-  String get str;
-
-  /**
    * The pattern used to search in [input].
    */
   Pattern get pattern;
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index eef7e97..6ef98dd 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -2309,78 +2309,6 @@
 
 
 @DocsEditable()
-@DomName('WebKitCSSFilterValue')
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-// http://dev.w3.org/csswg/cssom/
-@deprecated // deprecated
-class CssFilterValue extends _CssValueList native "WebKitCSSFilterValue" {
-  // To suppress missing implicit constructor warnings.
-  factory CssFilterValue._() { throw new UnsupportedError("Not supported"); }
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_BLUR')
-  @DocsEditable()
-  static const int CSS_FILTER_BLUR = 10;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS')
-  @DocsEditable()
-  static const int CSS_FILTER_BRIGHTNESS = 8;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_CONTRAST')
-  @DocsEditable()
-  static const int CSS_FILTER_CONTRAST = 9;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_CUSTOM')
-  @DocsEditable()
-  static const int CSS_FILTER_CUSTOM = 12;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_DROP_SHADOW')
-  @DocsEditable()
-  static const int CSS_FILTER_DROP_SHADOW = 11;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_GRAYSCALE')
-  @DocsEditable()
-  static const int CSS_FILTER_GRAYSCALE = 2;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_HUE_ROTATE')
-  @DocsEditable()
-  static const int CSS_FILTER_HUE_ROTATE = 5;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_INVERT')
-  @DocsEditable()
-  static const int CSS_FILTER_INVERT = 6;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_OPACITY')
-  @DocsEditable()
-  static const int CSS_FILTER_OPACITY = 7;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_REFERENCE')
-  @DocsEditable()
-  static const int CSS_FILTER_REFERENCE = 1;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_SATURATE')
-  @DocsEditable()
-  static const int CSS_FILTER_SATURATE = 4;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_SEPIA')
-  @DocsEditable()
-  static const int CSS_FILTER_SEPIA = 3;
-
-  @DomName('WebKitCSSFilterValue.operationType')
-  @DocsEditable()
-  final int operationType;
-
-  @DomName('WebKitCSSFilterValue.__getter__')
-  @DocsEditable()
-  _CSSValue __getter__(int index) native;
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable()
 @DomName('CSSFontFaceLoadEvent')
 // http://www.w3.org/TR/css3-fonts/
 @Experimental()
@@ -2532,164 +2460,6 @@
 
 
 @DocsEditable()
-@DomName('WebKitCSSMatrix')
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-// http://dev.w3.org/csswg/cssom/
-@deprecated // deprecated
-class CssMatrix extends Interceptor native "WebKitCSSMatrix" {
-  // To suppress missing implicit constructor warnings.
-  factory CssMatrix._() { throw new UnsupportedError("Not supported"); }
-
-  @DomName('WebKitCSSMatrix.WebKitCSSMatrix')
-  @DocsEditable()
-  factory CssMatrix([String cssValue]) {
-    if (cssValue != null) {
-      return CssMatrix._create_1(cssValue);
-    }
-    return CssMatrix._create_2();
-  }
-  static CssMatrix _create_1(cssValue) => JS('CssMatrix', 'new WebKitCSSMatrix(#)', cssValue);
-  static CssMatrix _create_2() => JS('CssMatrix', 'new WebKitCSSMatrix()');
-
-  @DomName('WebKitCSSMatrix.a')
-  @DocsEditable()
-  num a;
-
-  @DomName('WebKitCSSMatrix.b')
-  @DocsEditable()
-  num b;
-
-  @DomName('WebKitCSSMatrix.c')
-  @DocsEditable()
-  num c;
-
-  @DomName('WebKitCSSMatrix.d')
-  @DocsEditable()
-  num d;
-
-  @DomName('WebKitCSSMatrix.e')
-  @DocsEditable()
-  num e;
-
-  @DomName('WebKitCSSMatrix.f')
-  @DocsEditable()
-  num f;
-
-  @DomName('WebKitCSSMatrix.m11')
-  @DocsEditable()
-  num m11;
-
-  @DomName('WebKitCSSMatrix.m12')
-  @DocsEditable()
-  num m12;
-
-  @DomName('WebKitCSSMatrix.m13')
-  @DocsEditable()
-  num m13;
-
-  @DomName('WebKitCSSMatrix.m14')
-  @DocsEditable()
-  num m14;
-
-  @DomName('WebKitCSSMatrix.m21')
-  @DocsEditable()
-  num m21;
-
-  @DomName('WebKitCSSMatrix.m22')
-  @DocsEditable()
-  num m22;
-
-  @DomName('WebKitCSSMatrix.m23')
-  @DocsEditable()
-  num m23;
-
-  @DomName('WebKitCSSMatrix.m24')
-  @DocsEditable()
-  num m24;
-
-  @DomName('WebKitCSSMatrix.m31')
-  @DocsEditable()
-  num m31;
-
-  @DomName('WebKitCSSMatrix.m32')
-  @DocsEditable()
-  num m32;
-
-  @DomName('WebKitCSSMatrix.m33')
-  @DocsEditable()
-  num m33;
-
-  @DomName('WebKitCSSMatrix.m34')
-  @DocsEditable()
-  num m34;
-
-  @DomName('WebKitCSSMatrix.m41')
-  @DocsEditable()
-  num m41;
-
-  @DomName('WebKitCSSMatrix.m42')
-  @DocsEditable()
-  num m42;
-
-  @DomName('WebKitCSSMatrix.m43')
-  @DocsEditable()
-  num m43;
-
-  @DomName('WebKitCSSMatrix.m44')
-  @DocsEditable()
-  num m44;
-
-  @DomName('WebKitCSSMatrix.inverse')
-  @DocsEditable()
-  CssMatrix inverse() native;
-
-  @DomName('WebKitCSSMatrix.multiply')
-  @DocsEditable()
-  CssMatrix multiply(CssMatrix secondMatrix) native;
-
-  @DomName('WebKitCSSMatrix.rotate')
-  @DocsEditable()
-  CssMatrix rotate(num rotX, num rotY, num rotZ) native;
-
-  @DomName('WebKitCSSMatrix.rotateAxisAngle')
-  @DocsEditable()
-  CssMatrix rotateAxisAngle(num x, num y, num z, num angle) native;
-
-  @DomName('WebKitCSSMatrix.scale')
-  @DocsEditable()
-  CssMatrix scale(num scaleX, num scaleY, num scaleZ) native;
-
-  @DomName('WebKitCSSMatrix.setMatrixValue')
-  @DocsEditable()
-  void setMatrixValue(String string) native;
-
-  @DomName('WebKitCSSMatrix.skewX')
-  @DocsEditable()
-  CssMatrix skewX(num angle) native;
-
-  @DomName('WebKitCSSMatrix.skewY')
-  @DocsEditable()
-  CssMatrix skewY(num angle) native;
-
-  @DomName('WebKitCSSMatrix.toString')
-  @DocsEditable()
-  String toString() native;
-
-  @DomName('WebKitCSSMatrix.translate')
-  @DocsEditable()
-  CssMatrix translate(num x, num y, num z) native;
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable()
 @DomName('CSSMediaRule')
 class CssMediaRule extends CssRule native "CSSMediaRule" {
   // To suppress missing implicit constructor warnings.
@@ -2719,22 +2489,6 @@
 
 
 @DocsEditable()
-@DomName('WebKitCSSMixFunctionValue')
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-// http://dev.w3.org/csswg/cssom/
-@deprecated // deprecated
-class CssMixFunctionValue extends _CssValueList native "WebKitCSSMixFunctionValue" {
-  // To suppress missing implicit constructor warnings.
-  factory CssMixFunctionValue._() { throw new UnsupportedError("Not supported"); }
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for 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('CSSPageRule')
 class CssPageRule extends CssRule native "CSSPageRule" {
   // To suppress missing implicit constructor warnings.
@@ -6251,127 +6005,6 @@
 
 
 @DocsEditable()
-@DomName('WebKitCSSTransformValue')
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-// http://dev.w3.org/csswg/cssom/
-@deprecated // deprecated
-class CssTransformValue extends _CssValueList native "WebKitCSSTransformValue" {
-  // To suppress missing implicit constructor warnings.
-  factory CssTransformValue._() { throw new UnsupportedError("Not supported"); }
-
-  @DomName('WebKitCSSTransformValue.CSS_MATRIX')
-  @DocsEditable()
-  static const int CSS_MATRIX = 11;
-
-  @DomName('WebKitCSSTransformValue.CSS_MATRIX3D')
-  @DocsEditable()
-  static const int CSS_MATRIX3D = 21;
-
-  @DomName('WebKitCSSTransformValue.CSS_PERSPECTIVE')
-  @DocsEditable()
-  static const int CSS_PERSPECTIVE = 20;
-
-  @DomName('WebKitCSSTransformValue.CSS_ROTATE')
-  @DocsEditable()
-  static const int CSS_ROTATE = 4;
-
-  @DomName('WebKitCSSTransformValue.CSS_ROTATE3D')
-  @DocsEditable()
-  static const int CSS_ROTATE3D = 17;
-
-  @DomName('WebKitCSSTransformValue.CSS_ROTATEX')
-  @DocsEditable()
-  static const int CSS_ROTATEX = 14;
-
-  @DomName('WebKitCSSTransformValue.CSS_ROTATEY')
-  @DocsEditable()
-  static const int CSS_ROTATEY = 15;
-
-  @DomName('WebKitCSSTransformValue.CSS_ROTATEZ')
-  @DocsEditable()
-  static const int CSS_ROTATEZ = 16;
-
-  @DomName('WebKitCSSTransformValue.CSS_SCALE')
-  @DocsEditable()
-  static const int CSS_SCALE = 5;
-
-  @DomName('WebKitCSSTransformValue.CSS_SCALE3D')
-  @DocsEditable()
-  static const int CSS_SCALE3D = 19;
-
-  @DomName('WebKitCSSTransformValue.CSS_SCALEX')
-  @DocsEditable()
-  static const int CSS_SCALEX = 6;
-
-  @DomName('WebKitCSSTransformValue.CSS_SCALEY')
-  @DocsEditable()
-  static const int CSS_SCALEY = 7;
-
-  @DomName('WebKitCSSTransformValue.CSS_SCALEZ')
-  @DocsEditable()
-  static const int CSS_SCALEZ = 18;
-
-  @DomName('WebKitCSSTransformValue.CSS_SKEW')
-  @DocsEditable()
-  static const int CSS_SKEW = 8;
-
-  @DomName('WebKitCSSTransformValue.CSS_SKEWX')
-  @DocsEditable()
-  static const int CSS_SKEWX = 9;
-
-  @DomName('WebKitCSSTransformValue.CSS_SKEWY')
-  @DocsEditable()
-  static const int CSS_SKEWY = 10;
-
-  @DomName('WebKitCSSTransformValue.CSS_TRANSLATE')
-  @DocsEditable()
-  static const int CSS_TRANSLATE = 1;
-
-  @DomName('WebKitCSSTransformValue.CSS_TRANSLATE3D')
-  @DocsEditable()
-  static const int CSS_TRANSLATE3D = 13;
-
-  @DomName('WebKitCSSTransformValue.CSS_TRANSLATEX')
-  @DocsEditable()
-  static const int CSS_TRANSLATEX = 2;
-
-  @DomName('WebKitCSSTransformValue.CSS_TRANSLATEY')
-  @DocsEditable()
-  static const int CSS_TRANSLATEY = 3;
-
-  @DomName('WebKitCSSTransformValue.CSS_TRANSLATEZ')
-  @DocsEditable()
-  static const int CSS_TRANSLATEZ = 12;
-
-  @DomName('WebKitCSSTransformValue.operationType')
-  @DocsEditable()
-  final int operationType;
-
-  @DomName('WebKitCSSTransformValue.__getter__')
-  @DocsEditable()
-  _CSSValue __getter__(int index) native;
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable()
-@DomName('CSSUnknownRule')
-// http://dev.w3.org/csswg/cssom/#the-cssstylesheet-interface
-@deprecated // deprecated
-class CssUnknownRule extends CssRule native "CSSUnknownRule" {
-  // To suppress missing implicit constructor warnings.
-  factory CssUnknownRule._() { throw new UnsupportedError("Not supported"); }
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for 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('CSSVariablesMap')
 @Experimental() // untriaged
 class CssVariablesMap extends Interceptor native "CSSVariablesMap" {
@@ -8257,7 +7890,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-class _ChildrenElementList extends ListBase<Element> {
+class _ChildrenElementList extends ListBase<Element>
+    implements NodeListWrapper {
   // Raw Element.
   final Element _element;
   final HtmlCollection _childElements;
@@ -8410,6 +8044,8 @@
     if (length > 1) throw new StateError("More than one element");
     return first;
   }
+
+  List<Node> get rawList => _childElements;
 }
 
 /**
@@ -8735,7 +8371,8 @@
 // a better option given that we cannot quite force NodeList to be an
 // ElementList as there are valid cases where a NodeList JavaScript object
 // contains Node objects that are not Elements.
-class _FrozenElementList<T extends Element> extends ListBase<T> implements ElementList {
+class _FrozenElementList<T extends Element> extends ListBase<T>
+    implements ElementList, NodeListWrapper {
   final List<Node> _nodeList;
   // The subset of _nodeList that are Elements.
   List<Element> _elementList;
@@ -8787,6 +8424,9 @@
 
   CssRect get marginEdge => _elementList.first.marginEdge;
 
+  List<Node> get rawList => _nodeList;
+
+
   @DomName('Element.onabort')
   @DocsEditable()
   ElementStream<Event> get onAbort => Element.abortEvent._forElementList(this);
@@ -9668,6 +9308,8 @@
       return JS('bool', '#.mozMatchesSelector(#)', this, selectors);
     } else if (JS('bool', '!!#.msMatchesSelector', this)) {
       return JS('bool', '#.msMatchesSelector(#)', this, selectors);
+    } else if (JS('bool', '!!#.oMatchesSelector', this)) {
+      return JS('bool', '#.oMatchesSelector(#)', this, selectors);
     } else {
       throw new UnsupportedError("Not supported on this platform");
     }
@@ -12592,85 +12234,6 @@
 
 
 @DocsEditable()
-@DomName('HTMLAllCollection')
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dom-document-all
-@deprecated // deprecated
-class HtmlAllCollection extends Interceptor with ListMixin<Node>, ImmutableListMixin<Node> implements List native "HTMLAllCollection" {
-  // To suppress missing implicit constructor warnings.
-  factory HtmlAllCollection._() { throw new UnsupportedError("Not supported"); }
-
-  @DomName('HTMLAllCollection.length')
-  @DocsEditable()
-  int get length => JS("int", "#.length", this);
-
-  Node operator[](int index) {
-    if (JS("bool", "# >>> 0 !== # || # >= #", index,
-        index, index, length))
-      throw new RangeError.range(index, 0, length);
-    return this.item(index);
-  }
-  void operator[]=(int index, Node value) {
-    throw new UnsupportedError("Cannot assign element of immutable List.");
-  }
-  // -- start List<Node> mixins.
-  // Node is the element type.
-
-
-  void set length(int value) {
-    throw new UnsupportedError("Cannot resize immutable List.");
-  }
-
-  Node get first {
-    if (this.length > 0) {
-      return JS('Node', '#[0]', this);
-    }
-    throw new StateError("No elements");
-  }
-
-  Node get last {
-    int len = this.length;
-    if (len > 0) {
-      return JS('Node', '#[#]', this, len - 1);
-    }
-    throw new StateError("No elements");
-  }
-
-  Node get single {
-    int len = this.length;
-    if (len == 1) {
-      return JS('Node', '#[0]', this);
-    }
-    if (len == 0) throw new StateError("No elements");
-    throw new StateError("More than one element");
-  }
-
-  Node elementAt(int index) => this[index];
-  // -- end List<Node> mixins.
-
-  @DomName('HTMLAllCollection.__getter__')
-  @DocsEditable()
-  Node __getter__(int index) native;
-
-  @DomName('HTMLAllCollection.item')
-  @DocsEditable()
-  Node item(int index) native;
-
-  @DomName('HTMLAllCollection.namedItem')
-  @DocsEditable()
-  Node namedItem(String name) native;
-
-  @DomName('HTMLAllCollection.tags')
-  @DocsEditable()
-  @Returns('NodeList')
-  @Creates('NodeList')
-  List<Node> tags(String name) native;
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable()
 @DomName('HTMLCollection')
 class HtmlCollection extends Interceptor with ListMixin<Node>, ImmutableListMixin<Node> implements JavaScriptIndexingBehavior, List native "HTMLCollection" {
   // To suppress missing implicit constructor warnings.
@@ -13721,6 +13284,8 @@
 
   @DomName('ImageData.data')
   @DocsEditable()
+  @Creates('Uint8ClampedList')
+  @Returns('Uint8ClampedList')
   final List<int> data;
 
   @DomName('ImageData.height')
@@ -17209,68 +16774,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-@DomName('MutationEvent')
-// http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents
-@deprecated
-class MutationEvent extends Event native "MutationEvent" {
-  factory MutationEvent(String type,
-      {bool canBubble: false, bool cancelable: false, Node relatedNode,
-      String prevValue, String newValue, String attrName, int attrChange: 0}) {
-
-    var event = document._createEvent('MutationEvent');
-    event._initMutationEvent(type, canBubble, cancelable, relatedNode,
-        prevValue, newValue, attrName, attrChange);
-    return event;
-  }
-  // To suppress missing implicit constructor warnings.
-  factory MutationEvent._() { throw new UnsupportedError("Not supported"); }
-
-  @DomName('MutationEvent.ADDITION')
-  @DocsEditable()
-  static const int ADDITION = 2;
-
-  @DomName('MutationEvent.MODIFICATION')
-  @DocsEditable()
-  static const int MODIFICATION = 1;
-
-  @DomName('MutationEvent.REMOVAL')
-  @DocsEditable()
-  static const int REMOVAL = 3;
-
-  @DomName('MutationEvent.attrChange')
-  @DocsEditable()
-  final int attrChange;
-
-  @DomName('MutationEvent.attrName')
-  @DocsEditable()
-  final String attrName;
-
-  @DomName('MutationEvent.newValue')
-  @DocsEditable()
-  final String newValue;
-
-  @DomName('MutationEvent.prevValue')
-  @DocsEditable()
-  final String prevValue;
-
-  @DomName('MutationEvent.relatedNode')
-  @DocsEditable()
-  final Node relatedNode;
-
-  @JSName('initMutationEvent')
-  @DomName('MutationEvent.initMutationEvent')
-  @DocsEditable()
-  void _initMutationEvent(String type, bool canBubble, bool cancelable, Node relatedNode, String prevValue, String newValue, String attrName, int attrChange) native;
-
-}
-
-
-
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
 @DomName('MutationObserver')
 @SupportedBrowser(SupportedBrowser.CHROME)
 @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -17307,6 +16810,16 @@
         '!!(window.MutationObserver || window.WebKitMutationObserver)');
   }
 
+  /**
+   * Observes the target for the specified changes.
+   *
+   * Some requirements for the optional parameters:
+   *
+   * * Either childList, attributes or characterData must be true.
+   * * If attributeOldValue is true then attributes must also be true.
+   * * If attributeFilter is specified then attributes must be true.
+   * * If characterDataOldValue is true then characterData must be true.
+   */
   void observe(Node target,
                {bool childList,
                 bool attributes,
@@ -17802,7 +17315,7 @@
  * the actual child nodes of an element until strictly necessary greatly
  * improving performance for the typical cases where it is not required.
  */
-class _ChildNodeListLazy extends ListBase<Node> {
+class _ChildNodeListLazy extends ListBase<Node> implements NodeListWrapper {
   final Node _this;
 
   _ChildNodeListLazy(this._this);
@@ -17954,6 +17467,8 @@
   }
 
   Node operator[](int index) => _this.childNodes[index];
+
+  List<Node> get rawList => _this.childNodes;
 }
 
 
@@ -18033,13 +17548,6 @@
    * Print out a String representation of this Node.
    */
   String toString() => nodeValue == null ? super.toString() : nodeValue;
-
-  /**
-   * Use ownerDocument instead.
-   */
-  @deprecated
-  Document get document => ownerDocument;
-
   // To suppress missing implicit constructor warnings.
   factory Node._() { throw new UnsupportedError("Not supported"); }
 
@@ -18365,19 +17873,6 @@
   @DocsEditable()
   Node _item(int index) native;
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable()
-@DomName('Notation')
-// http://dom.spec.whatwg.org/#notation
-@deprecated // deprecated
-class Notation extends Node native "Notation" {
-  // To suppress missing implicit constructor warnings.
-  factory Notation._() { throw new UnsupportedError("Not supported"); }
-}
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -18509,48 +18004,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-
-@DocsEditable()
-@DomName('NotificationCenter')
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-// http://www.w3.org/TR/notifications/#showing-a-notification
-@deprecated // deprecated
-class NotificationCenter extends Interceptor native "NotificationCenter" {
-  // To suppress missing implicit constructor warnings.
-  factory NotificationCenter._() { throw new UnsupportedError("Not supported"); }
-
-  /// Checks if this type is supported on the current platform.
-  static bool get supported => JS('bool', '!!(window.webkitNotifications)');
-
-  @DomName('NotificationCenter.checkPermission')
-  @DocsEditable()
-  int checkPermission() native;
-
-  @DomName('NotificationCenter.createNotification')
-  @DocsEditable()
-  Notification createNotification(String iconUrl, String title, String body) native;
-
-  @JSName('requestPermission')
-  @DomName('NotificationCenter.requestPermission')
-  @DocsEditable()
-  void _requestPermission([VoidCallback callback]) native;
-
-  @JSName('requestPermission')
-  @DomName('NotificationCenter.requestPermission')
-  @DocsEditable()
-  Future requestPermission() {
-    var completer = new Completer();
-    _requestPermission(
-        () { completer.complete(); });
-    return completer.future;
-  }
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
 // WARNING: Do not edit - generated code.
 
 
@@ -25957,7 +25410,7 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   @Experimental() // untriaged
-  final NotificationCenter notifications;
+  final _NotificationCenter _webkitNotifications;
 
   @DomName('WorkerGlobalScope.close')
   @DocsEditable()
@@ -26459,6 +25912,19 @@
 
 
 @DocsEditable()
+@DomName('CSSUnknownRule')
+// http://dev.w3.org/csswg/cssom/#the-cssstylesheet-interface
+@deprecated // deprecated
+abstract class _CSSUnknownRule extends CssRule native "CSSUnknownRule" {
+  // To suppress missing implicit constructor warnings.
+  factory _CSSUnknownRule._() { throw new UnsupportedError("Not supported"); }
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('CSSValue')
 // http://dev.w3.org/csswg/cssom/
 @deprecated // deprecated
@@ -26473,7 +25939,7 @@
 
 @DocsEditable()
 @DomName('ClientRect')
-class _ClientRect extends Interceptor implements Rectangle native "ClientRect" {
+class _ClientRect extends Interceptor implements Rectangle native "ClientRect,DOMRect" {
 
   // NOTE! All code below should be common with RectangleBase.
    String toString() {
@@ -26540,7 +26006,7 @@
   /**
    * Tests whether `this` entirely contains [another].
    */
-  bool contains(Rectangle<num> another) {
+  bool containsRectangle(Rectangle<num> another) {
     return left <= another.left &&
            left + width >= another.left + another.width &&
            top <= another.top &&
@@ -27064,6 +26530,24 @@
 
 
 @DocsEditable()
+@DomName('HTMLAllCollection')
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dom-document-all
+@deprecated // deprecated
+abstract class _HTMLAllCollection extends Interceptor native "HTMLAllCollection" {
+  // To suppress missing implicit constructor warnings.
+  factory _HTMLAllCollection._() { throw new UnsupportedError("Not supported"); }
+
+  @JSName('item')
+  @DomName('HTMLAllCollection.item')
+  @DocsEditable()
+  Node _item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable()
 @DomName('HTMLAppletElement')
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-applet-element
 @deprecated // deprecated
@@ -27196,6 +26680,31 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
+@DomName('MutationEvent')
+// http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents
+@deprecated
+abstract class _MutationEvent extends Event native "MutationEvent" {
+  factory _MutationEvent(String type,
+      {bool canBubble: false, bool cancelable: false, Node relatedNode,
+      String prevValue, String newValue, String attrName, int attrChange: 0}) {
+
+    var event = document._createEvent('MutationEvent');
+    event._initMutationEvent(type, canBubble, cancelable, relatedNode,
+        prevValue, newValue, attrName, attrChange);
+    return event;
+  }
+  // To suppress missing implicit constructor warnings.
+  factory _MutationEvent._() { throw new UnsupportedError("Not supported"); }
+
+}
+
+
+
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('NamedNodeMap')
 // http://dom.spec.whatwg.org/#namednodemap
@@ -27290,6 +26799,38 @@
 
 
 @DocsEditable()
+@DomName('Notation')
+// http://dom.spec.whatwg.org/#notation
+@deprecated // deprecated
+abstract class _Notation extends Node native "Notation" {
+  // To suppress missing implicit constructor warnings.
+  factory _Notation._() { throw new UnsupportedError("Not supported"); }
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('NotificationCenter')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
+// http://www.w3.org/TR/notifications/#showing-a-notification
+@deprecated // deprecated
+abstract class _NotificationCenter extends Interceptor native "NotificationCenter" {
+  // To suppress missing implicit constructor warnings.
+  factory _NotificationCenter._() { throw new UnsupportedError("Not supported"); }
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.webkitNotifications)');
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('PagePopupController')
 @deprecated // nonstandard
 abstract class _PagePopupController extends Interceptor native "PagePopupController" {
@@ -27570,6 +27111,72 @@
 
 
 @DocsEditable()
+@DomName('WebKitCSSFilterValue')
+// http://dev.w3.org/csswg/cssom/
+@deprecated // deprecated
+abstract class _WebKitCSSFilterValue extends _CssValueList native "WebKitCSSFilterValue" {
+  // To suppress missing implicit constructor warnings.
+  factory _WebKitCSSFilterValue._() { throw new UnsupportedError("Not supported"); }
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('WebKitCSSMatrix')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
+// http://dev.w3.org/csswg/cssom/
+@deprecated // deprecated
+abstract class _WebKitCSSMatrix extends Interceptor native "WebKitCSSMatrix" {
+  // To suppress missing implicit constructor warnings.
+  factory _WebKitCSSMatrix._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('WebKitCSSMatrix.WebKitCSSMatrix')
+  @DocsEditable()
+  factory _WebKitCSSMatrix([String cssValue]) {
+    if (cssValue != null) {
+      return _WebKitCSSMatrix._create_1(cssValue);
+    }
+    return _WebKitCSSMatrix._create_2();
+  }
+  static _WebKitCSSMatrix _create_1(cssValue) => JS('_WebKitCSSMatrix', 'new WebKitCSSMatrix(#)', cssValue);
+  static _WebKitCSSMatrix _create_2() => JS('_WebKitCSSMatrix', 'new WebKitCSSMatrix()');
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('WebKitCSSMixFunctionValue')
+// http://dev.w3.org/csswg/cssom/
+@deprecated // deprecated
+abstract class _WebKitCSSMixFunctionValue extends _CssValueList native "WebKitCSSMixFunctionValue" {
+  // To suppress missing implicit constructor warnings.
+  factory _WebKitCSSMixFunctionValue._() { throw new UnsupportedError("Not supported"); }
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('WebKitCSSTransformValue')
+// http://dev.w3.org/csswg/cssom/
+@deprecated // deprecated
+abstract class _WebKitCSSTransformValue extends _CssValueList native "WebKitCSSTransformValue" {
+  // To suppress missing implicit constructor warnings.
+  factory _WebKitCSSTransformValue._() { throw new UnsupportedError("Not supported"); }
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('WebKitMediaSource')
 @Experimental() // untriaged
 abstract class _WebKitMediaSource extends EventTarget native "WebKitMediaSource" {
@@ -31694,7 +31301,8 @@
  * A list which just wraps another list, for either intercepting list calls or
  * retyping the list (for example, from List<A> to List<B> where B extends A).
  */
-class _WrappedList<E> extends ListBase<E> {
+class _WrappedList<E extends Node> extends ListBase<E>
+    implements NodeListWrapper {
   final List _list;
 
   _WrappedList(this._list);
@@ -31744,6 +31352,8 @@
   void fillRange(int start, int end, [E fillValue]) {
     _list.fillRange(start, end, fillValue);
   }
+
+  List<Node> get rawList => _list;
 }
 
 /**
@@ -32000,12 +31610,6 @@
   JS('void', '#.attributeChangedCallback = #', properties,
       JS('=Object', '{value: #}', _makeCallbackMethod3(_callAttributeChanged)));
 
-  // TODO(blois): Bug 13220- remove once transition is complete
-  JS('void', '#.enteredDocumentCallback = #', properties,
-      JS('=Object', '{value: #}', _makeCallbackMethod(_callEnteredView)));
-  JS('void', '#.leftDocumentCallback = #', properties,
-      JS('=Object', '{value: #}', _makeCallbackMethod(_callLeftView)));
-
   var baseProto = JS('=Object', '#.prototype', baseConstructor);
   var proto = JS('=Object', 'Object.create(#, #)', baseProto, properties);
 
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index a13b5a7..3af252e 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -2661,81 +2661,6 @@
 
 
 @DocsEditable()
-@DomName('WebKitCSSFilterValue')
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-// http://dev.w3.org/csswg/cssom/
-@deprecated // deprecated
-class CssFilterValue extends _CssValueList {
-  // To suppress missing implicit constructor warnings.
-  factory CssFilterValue._() { throw new UnsupportedError("Not supported"); }
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_BLUR')
-  @DocsEditable()
-  static const int CSS_FILTER_BLUR = 10;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS')
-  @DocsEditable()
-  static const int CSS_FILTER_BRIGHTNESS = 8;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_CONTRAST')
-  @DocsEditable()
-  static const int CSS_FILTER_CONTRAST = 9;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_CUSTOM')
-  @DocsEditable()
-  static const int CSS_FILTER_CUSTOM = 12;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_DROP_SHADOW')
-  @DocsEditable()
-  static const int CSS_FILTER_DROP_SHADOW = 11;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_GRAYSCALE')
-  @DocsEditable()
-  static const int CSS_FILTER_GRAYSCALE = 2;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_HUE_ROTATE')
-  @DocsEditable()
-  static const int CSS_FILTER_HUE_ROTATE = 5;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_INVERT')
-  @DocsEditable()
-  static const int CSS_FILTER_INVERT = 6;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_OPACITY')
-  @DocsEditable()
-  static const int CSS_FILTER_OPACITY = 7;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_REFERENCE')
-  @DocsEditable()
-  static const int CSS_FILTER_REFERENCE = 1;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_SATURATE')
-  @DocsEditable()
-  static const int CSS_FILTER_SATURATE = 4;
-
-  @DomName('WebKitCSSFilterValue.CSS_FILTER_SEPIA')
-  @DocsEditable()
-  static const int CSS_FILTER_SEPIA = 3;
-
-  @DomName('WebKitCSSFilterValue.operationType')
-  @DocsEditable()
-  int get operationType native "WebKitCSSFilterValue_operationType_Getter";
-
-  @DomName('WebKitCSSFilterValue.__getter__')
-  @DocsEditable()
-  _CSSValue __getter__(int index) native "WebKitCSSFilterValue___getter___Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable()
 @DomName('CSSFontFaceLoadEvent')
 // http://www.w3.org/TR/css3-fonts/
 @Experimental()
@@ -2910,253 +2835,6 @@
 
 
 @DocsEditable()
-@DomName('WebKitCSSMatrix')
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-// http://dev.w3.org/csswg/cssom/
-@deprecated // deprecated
-class CssMatrix extends NativeFieldWrapperClass2 {
-  // To suppress missing implicit constructor warnings.
-  factory CssMatrix._() { throw new UnsupportedError("Not supported"); }
-
-  @DomName('WebKitCSSMatrix.WebKitCSSMatrix')
-  @DocsEditable()
-  factory CssMatrix([String cssValue]) {
-    return CssMatrix._create_1(cssValue);
-  }
-
-  @DocsEditable()
-  static CssMatrix _create_1(cssValue) native "WebKitCSSMatrix__create_1constructorCallback";
-
-  @DomName('WebKitCSSMatrix.a')
-  @DocsEditable()
-  num get a native "WebKitCSSMatrix_a_Getter";
-
-  @DomName('WebKitCSSMatrix.a')
-  @DocsEditable()
-  void set a(num value) native "WebKitCSSMatrix_a_Setter";
-
-  @DomName('WebKitCSSMatrix.b')
-  @DocsEditable()
-  num get b native "WebKitCSSMatrix_b_Getter";
-
-  @DomName('WebKitCSSMatrix.b')
-  @DocsEditable()
-  void set b(num value) native "WebKitCSSMatrix_b_Setter";
-
-  @DomName('WebKitCSSMatrix.c')
-  @DocsEditable()
-  num get c native "WebKitCSSMatrix_c_Getter";
-
-  @DomName('WebKitCSSMatrix.c')
-  @DocsEditable()
-  void set c(num value) native "WebKitCSSMatrix_c_Setter";
-
-  @DomName('WebKitCSSMatrix.d')
-  @DocsEditable()
-  num get d native "WebKitCSSMatrix_d_Getter";
-
-  @DomName('WebKitCSSMatrix.d')
-  @DocsEditable()
-  void set d(num value) native "WebKitCSSMatrix_d_Setter";
-
-  @DomName('WebKitCSSMatrix.e')
-  @DocsEditable()
-  num get e native "WebKitCSSMatrix_e_Getter";
-
-  @DomName('WebKitCSSMatrix.e')
-  @DocsEditable()
-  void set e(num value) native "WebKitCSSMatrix_e_Setter";
-
-  @DomName('WebKitCSSMatrix.f')
-  @DocsEditable()
-  num get f native "WebKitCSSMatrix_f_Getter";
-
-  @DomName('WebKitCSSMatrix.f')
-  @DocsEditable()
-  void set f(num value) native "WebKitCSSMatrix_f_Setter";
-
-  @DomName('WebKitCSSMatrix.m11')
-  @DocsEditable()
-  num get m11 native "WebKitCSSMatrix_m11_Getter";
-
-  @DomName('WebKitCSSMatrix.m11')
-  @DocsEditable()
-  void set m11(num value) native "WebKitCSSMatrix_m11_Setter";
-
-  @DomName('WebKitCSSMatrix.m12')
-  @DocsEditable()
-  num get m12 native "WebKitCSSMatrix_m12_Getter";
-
-  @DomName('WebKitCSSMatrix.m12')
-  @DocsEditable()
-  void set m12(num value) native "WebKitCSSMatrix_m12_Setter";
-
-  @DomName('WebKitCSSMatrix.m13')
-  @DocsEditable()
-  num get m13 native "WebKitCSSMatrix_m13_Getter";
-
-  @DomName('WebKitCSSMatrix.m13')
-  @DocsEditable()
-  void set m13(num value) native "WebKitCSSMatrix_m13_Setter";
-
-  @DomName('WebKitCSSMatrix.m14')
-  @DocsEditable()
-  num get m14 native "WebKitCSSMatrix_m14_Getter";
-
-  @DomName('WebKitCSSMatrix.m14')
-  @DocsEditable()
-  void set m14(num value) native "WebKitCSSMatrix_m14_Setter";
-
-  @DomName('WebKitCSSMatrix.m21')
-  @DocsEditable()
-  num get m21 native "WebKitCSSMatrix_m21_Getter";
-
-  @DomName('WebKitCSSMatrix.m21')
-  @DocsEditable()
-  void set m21(num value) native "WebKitCSSMatrix_m21_Setter";
-
-  @DomName('WebKitCSSMatrix.m22')
-  @DocsEditable()
-  num get m22 native "WebKitCSSMatrix_m22_Getter";
-
-  @DomName('WebKitCSSMatrix.m22')
-  @DocsEditable()
-  void set m22(num value) native "WebKitCSSMatrix_m22_Setter";
-
-  @DomName('WebKitCSSMatrix.m23')
-  @DocsEditable()
-  num get m23 native "WebKitCSSMatrix_m23_Getter";
-
-  @DomName('WebKitCSSMatrix.m23')
-  @DocsEditable()
-  void set m23(num value) native "WebKitCSSMatrix_m23_Setter";
-
-  @DomName('WebKitCSSMatrix.m24')
-  @DocsEditable()
-  num get m24 native "WebKitCSSMatrix_m24_Getter";
-
-  @DomName('WebKitCSSMatrix.m24')
-  @DocsEditable()
-  void set m24(num value) native "WebKitCSSMatrix_m24_Setter";
-
-  @DomName('WebKitCSSMatrix.m31')
-  @DocsEditable()
-  num get m31 native "WebKitCSSMatrix_m31_Getter";
-
-  @DomName('WebKitCSSMatrix.m31')
-  @DocsEditable()
-  void set m31(num value) native "WebKitCSSMatrix_m31_Setter";
-
-  @DomName('WebKitCSSMatrix.m32')
-  @DocsEditable()
-  num get m32 native "WebKitCSSMatrix_m32_Getter";
-
-  @DomName('WebKitCSSMatrix.m32')
-  @DocsEditable()
-  void set m32(num value) native "WebKitCSSMatrix_m32_Setter";
-
-  @DomName('WebKitCSSMatrix.m33')
-  @DocsEditable()
-  num get m33 native "WebKitCSSMatrix_m33_Getter";
-
-  @DomName('WebKitCSSMatrix.m33')
-  @DocsEditable()
-  void set m33(num value) native "WebKitCSSMatrix_m33_Setter";
-
-  @DomName('WebKitCSSMatrix.m34')
-  @DocsEditable()
-  num get m34 native "WebKitCSSMatrix_m34_Getter";
-
-  @DomName('WebKitCSSMatrix.m34')
-  @DocsEditable()
-  void set m34(num value) native "WebKitCSSMatrix_m34_Setter";
-
-  @DomName('WebKitCSSMatrix.m41')
-  @DocsEditable()
-  num get m41 native "WebKitCSSMatrix_m41_Getter";
-
-  @DomName('WebKitCSSMatrix.m41')
-  @DocsEditable()
-  void set m41(num value) native "WebKitCSSMatrix_m41_Setter";
-
-  @DomName('WebKitCSSMatrix.m42')
-  @DocsEditable()
-  num get m42 native "WebKitCSSMatrix_m42_Getter";
-
-  @DomName('WebKitCSSMatrix.m42')
-  @DocsEditable()
-  void set m42(num value) native "WebKitCSSMatrix_m42_Setter";
-
-  @DomName('WebKitCSSMatrix.m43')
-  @DocsEditable()
-  num get m43 native "WebKitCSSMatrix_m43_Getter";
-
-  @DomName('WebKitCSSMatrix.m43')
-  @DocsEditable()
-  void set m43(num value) native "WebKitCSSMatrix_m43_Setter";
-
-  @DomName('WebKitCSSMatrix.m44')
-  @DocsEditable()
-  num get m44 native "WebKitCSSMatrix_m44_Getter";
-
-  @DomName('WebKitCSSMatrix.m44')
-  @DocsEditable()
-  void set m44(num value) native "WebKitCSSMatrix_m44_Setter";
-
-  @DomName('WebKitCSSMatrix.inverse')
-  @DocsEditable()
-  CssMatrix inverse() native "WebKitCSSMatrix_inverse_Callback";
-
-  @DomName('WebKitCSSMatrix.multiply')
-  @DocsEditable()
-  CssMatrix multiply(CssMatrix secondMatrix) native "WebKitCSSMatrix_multiply_Callback";
-
-  @DomName('WebKitCSSMatrix.rotate')
-  @DocsEditable()
-  CssMatrix rotate(num rotX, num rotY, num rotZ) native "WebKitCSSMatrix_rotate_Callback";
-
-  @DomName('WebKitCSSMatrix.rotateAxisAngle')
-  @DocsEditable()
-  CssMatrix rotateAxisAngle(num x, num y, num z, num angle) native "WebKitCSSMatrix_rotateAxisAngle_Callback";
-
-  @DomName('WebKitCSSMatrix.scale')
-  @DocsEditable()
-  CssMatrix scale(num scaleX, num scaleY, num scaleZ) native "WebKitCSSMatrix_scale_Callback";
-
-  @DomName('WebKitCSSMatrix.setMatrixValue')
-  @DocsEditable()
-  void setMatrixValue(String string) native "WebKitCSSMatrix_setMatrixValue_Callback";
-
-  @DomName('WebKitCSSMatrix.skewX')
-  @DocsEditable()
-  CssMatrix skewX(num angle) native "WebKitCSSMatrix_skewX_Callback";
-
-  @DomName('WebKitCSSMatrix.skewY')
-  @DocsEditable()
-  CssMatrix skewY(num angle) native "WebKitCSSMatrix_skewY_Callback";
-
-  @DomName('WebKitCSSMatrix.toString')
-  @DocsEditable()
-  String toString() native "WebKitCSSMatrix_toString_Callback";
-
-  @DomName('WebKitCSSMatrix.translate')
-  @DocsEditable()
-  CssMatrix translate(num x, num y, num z) native "WebKitCSSMatrix_translate_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable()
 @DomName('CSSMediaRule')
 class CssMediaRule extends CssRule {
   // To suppress missing implicit constructor warnings.
@@ -3187,25 +2865,6 @@
 
 
 @DocsEditable()
-@DomName('WebKitCSSMixFunctionValue')
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-// http://dev.w3.org/csswg/cssom/
-@deprecated // deprecated
-class CssMixFunctionValue extends _CssValueList {
-  // To suppress missing implicit constructor warnings.
-  factory CssMixFunctionValue._() { throw new UnsupportedError("Not supported"); }
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for 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('CSSPageRule')
 class CssPageRule extends CssRule {
   // To suppress missing implicit constructor warnings.
@@ -6743,133 +6402,6 @@
 
 
 @DocsEditable()
-@DomName('WebKitCSSTransformValue')
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-// http://dev.w3.org/csswg/cssom/
-@deprecated // deprecated
-class CssTransformValue extends _CssValueList {
-  // To suppress missing implicit constructor warnings.
-  factory CssTransformValue._() { throw new UnsupportedError("Not supported"); }
-
-  @DomName('WebKitCSSTransformValue.CSS_MATRIX')
-  @DocsEditable()
-  static const int CSS_MATRIX = 11;
-
-  @DomName('WebKitCSSTransformValue.CSS_MATRIX3D')
-  @DocsEditable()
-  static const int CSS_MATRIX3D = 21;
-
-  @DomName('WebKitCSSTransformValue.CSS_PERSPECTIVE')
-  @DocsEditable()
-  static const int CSS_PERSPECTIVE = 20;
-
-  @DomName('WebKitCSSTransformValue.CSS_ROTATE')
-  @DocsEditable()
-  static const int CSS_ROTATE = 4;
-
-  @DomName('WebKitCSSTransformValue.CSS_ROTATE3D')
-  @DocsEditable()
-  static const int CSS_ROTATE3D = 17;
-
-  @DomName('WebKitCSSTransformValue.CSS_ROTATEX')
-  @DocsEditable()
-  static const int CSS_ROTATEX = 14;
-
-  @DomName('WebKitCSSTransformValue.CSS_ROTATEY')
-  @DocsEditable()
-  static const int CSS_ROTATEY = 15;
-
-  @DomName('WebKitCSSTransformValue.CSS_ROTATEZ')
-  @DocsEditable()
-  static const int CSS_ROTATEZ = 16;
-
-  @DomName('WebKitCSSTransformValue.CSS_SCALE')
-  @DocsEditable()
-  static const int CSS_SCALE = 5;
-
-  @DomName('WebKitCSSTransformValue.CSS_SCALE3D')
-  @DocsEditable()
-  static const int CSS_SCALE3D = 19;
-
-  @DomName('WebKitCSSTransformValue.CSS_SCALEX')
-  @DocsEditable()
-  static const int CSS_SCALEX = 6;
-
-  @DomName('WebKitCSSTransformValue.CSS_SCALEY')
-  @DocsEditable()
-  static const int CSS_SCALEY = 7;
-
-  @DomName('WebKitCSSTransformValue.CSS_SCALEZ')
-  @DocsEditable()
-  static const int CSS_SCALEZ = 18;
-
-  @DomName('WebKitCSSTransformValue.CSS_SKEW')
-  @DocsEditable()
-  static const int CSS_SKEW = 8;
-
-  @DomName('WebKitCSSTransformValue.CSS_SKEWX')
-  @DocsEditable()
-  static const int CSS_SKEWX = 9;
-
-  @DomName('WebKitCSSTransformValue.CSS_SKEWY')
-  @DocsEditable()
-  static const int CSS_SKEWY = 10;
-
-  @DomName('WebKitCSSTransformValue.CSS_TRANSLATE')
-  @DocsEditable()
-  static const int CSS_TRANSLATE = 1;
-
-  @DomName('WebKitCSSTransformValue.CSS_TRANSLATE3D')
-  @DocsEditable()
-  static const int CSS_TRANSLATE3D = 13;
-
-  @DomName('WebKitCSSTransformValue.CSS_TRANSLATEX')
-  @DocsEditable()
-  static const int CSS_TRANSLATEX = 2;
-
-  @DomName('WebKitCSSTransformValue.CSS_TRANSLATEY')
-  @DocsEditable()
-  static const int CSS_TRANSLATEY = 3;
-
-  @DomName('WebKitCSSTransformValue.CSS_TRANSLATEZ')
-  @DocsEditable()
-  static const int CSS_TRANSLATEZ = 12;
-
-  @DomName('WebKitCSSTransformValue.operationType')
-  @DocsEditable()
-  int get operationType native "WebKitCSSTransformValue_operationType_Getter";
-
-  @DomName('WebKitCSSTransformValue.__getter__')
-  @DocsEditable()
-  _CSSValue __getter__(int index) native "WebKitCSSTransformValue___getter___Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable()
-@DomName('CSSUnknownRule')
-// http://dev.w3.org/csswg/cssom/#the-cssstylesheet-interface
-@deprecated // deprecated
-class CssUnknownRule extends CssRule {
-  // To suppress missing implicit constructor warnings.
-  factory CssUnknownRule._() { throw new UnsupportedError("Not supported"); }
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for 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('CSSVariablesMap')
 @Experimental() // untriaged
 class CssVariablesMap extends NativeFieldWrapperClass2 {
@@ -8751,7 +8283,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-class _ChildrenElementList extends ListBase<Element> {
+class _ChildrenElementList extends ListBase<Element>
+    implements NodeListWrapper {
   // Raw Element.
   final Element _element;
   final HtmlCollection _childElements;
@@ -8904,6 +8437,8 @@
     if (length > 1) throw new StateError("More than one element");
     return first;
   }
+
+  List<Node> get rawList => _childElements;
 }
 
 /**
@@ -9229,7 +8764,8 @@
 // a better option given that we cannot quite force NodeList to be an
 // ElementList as there are valid cases where a NodeList JavaScript object
 // contains Node objects that are not Elements.
-class _FrozenElementList<T extends Element> extends ListBase<T> implements ElementList {
+class _FrozenElementList<T extends Element> extends ListBase<T>
+    implements ElementList, NodeListWrapper {
   final List<Node> _nodeList;
   // The subset of _nodeList that are Elements.
   List<Element> _elementList;
@@ -9281,6 +8817,9 @@
 
   CssRect get marginEdge => _elementList.first.marginEdge;
 
+  List<Node> get rawList => _nodeList;
+
+
   @DomName('Element.onabort')
   @DocsEditable()
   ElementStream<Event> get onAbort => Element.abortEvent._forElementList(this);
@@ -13079,87 +12618,6 @@
 
 
 @DocsEditable()
-@DomName('HTMLAllCollection')
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dom-document-all
-@deprecated // deprecated
-class HtmlAllCollection extends NativeFieldWrapperClass2 with ListMixin<Node>, ImmutableListMixin<Node> implements List {
-  // To suppress missing implicit constructor warnings.
-  factory HtmlAllCollection._() { throw new UnsupportedError("Not supported"); }
-
-  @DomName('HTMLAllCollection.length')
-  @DocsEditable()
-  int get length native "HTMLAllCollection_length_Getter";
-
-  Node operator[](int index) {
-    if (index < 0 || index >= length)
-      throw new RangeError.range(index, 0, length);
-    return _nativeIndexedGetter(index);
-  }
-  Node _nativeIndexedGetter(int index) native "HTMLAllCollection_item_Callback";
-
-  void operator[]=(int index, Node value) {
-    throw new UnsupportedError("Cannot assign element of immutable List.");
-  }
-  // -- start List<Node> mixins.
-  // Node is the element type.
-
-
-  void set length(int value) {
-    throw new UnsupportedError("Cannot resize immutable List.");
-  }
-
-  Node get first {
-    if (this.length > 0) {
-      return _nativeIndexedGetter(0);
-    }
-    throw new StateError("No elements");
-  }
-
-  Node get last {
-    int len = this.length;
-    if (len > 0) {
-      return _nativeIndexedGetter(len - 1);
-    }
-    throw new StateError("No elements");
-  }
-
-  Node get single {
-    int len = this.length;
-    if (len == 1) {
-      return _nativeIndexedGetter(0);
-    }
-    if (len == 0) throw new StateError("No elements");
-    throw new StateError("More than one element");
-  }
-
-  Node elementAt(int index) => this[index];
-  // -- end List<Node> mixins.
-
-  @DomName('HTMLAllCollection.__getter__')
-  @DocsEditable()
-  Node __getter__(int index) native "HTMLAllCollection___getter___Callback";
-
-  @DomName('HTMLAllCollection.item')
-  @DocsEditable()
-  Node item(int index) native "HTMLAllCollection_item_Callback";
-
-  @DomName('HTMLAllCollection.namedItem')
-  @DocsEditable()
-  Node namedItem(String name) native "HTMLAllCollection_namedItem_Callback";
-
-  @DomName('HTMLAllCollection.tags')
-  @DocsEditable()
-  List<Node> tags(String name) native "HTMLAllCollection_tags_Callback";
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable()
 @DomName('HTMLCollection')
 class HtmlCollection extends NativeFieldWrapperClass2 with ListMixin<Node>, ImmutableListMixin<Node> implements List {
   // To suppress missing implicit constructor warnings.
@@ -18503,67 +17961,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-@DomName('MutationEvent')
-// http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents
-@deprecated
-class MutationEvent extends Event {
-  factory MutationEvent(String type,
-      {bool canBubble: false, bool cancelable: false, Node relatedNode,
-      String prevValue, String newValue, String attrName, int attrChange: 0}) {
-
-    var event = document._createEvent('MutationEvent');
-    event._initMutationEvent(type, canBubble, cancelable, relatedNode,
-        prevValue, newValue, attrName, attrChange);
-    return event;
-  }
-  // To suppress missing implicit constructor warnings.
-  factory MutationEvent._() { throw new UnsupportedError("Not supported"); }
-
-  @DomName('MutationEvent.ADDITION')
-  @DocsEditable()
-  static const int ADDITION = 2;
-
-  @DomName('MutationEvent.MODIFICATION')
-  @DocsEditable()
-  static const int MODIFICATION = 1;
-
-  @DomName('MutationEvent.REMOVAL')
-  @DocsEditable()
-  static const int REMOVAL = 3;
-
-  @DomName('MutationEvent.attrChange')
-  @DocsEditable()
-  int get attrChange native "MutationEvent_attrChange_Getter";
-
-  @DomName('MutationEvent.attrName')
-  @DocsEditable()
-  String get attrName native "MutationEvent_attrName_Getter";
-
-  @DomName('MutationEvent.newValue')
-  @DocsEditable()
-  String get newValue native "MutationEvent_newValue_Getter";
-
-  @DomName('MutationEvent.prevValue')
-  @DocsEditable()
-  String get prevValue native "MutationEvent_prevValue_Getter";
-
-  @DomName('MutationEvent.relatedNode')
-  @DocsEditable()
-  Node get relatedNode native "MutationEvent_relatedNode_Getter";
-
-  @DomName('MutationEvent.initMutationEvent')
-  @DocsEditable()
-  void _initMutationEvent(String type, bool canBubble, bool cancelable, Node relatedNode, String prevValue, String newValue, String attrName, int attrChange) native "MutationEvent_initMutationEvent_Callback";
-
-}
-
-
-
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
 @DomName('MutationObserver')
 @SupportedBrowser(SupportedBrowser.CHROME)
 @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -18598,6 +17995,16 @@
     return true;
   }
 
+  /**
+   * Observes the target for the specified changes.
+   *
+   * Some requirements for the optional parameters:
+   *
+   * * Either childList, attributes or characterData must be true.
+   * * If attributeOldValue is true then attributes must also be true.
+   * * If attributeFilter is specified then attributes must be true.
+   * * If characterDataOldValue is true then characterData must be true.
+   */
   void observe(Node target,
                {bool childList,
                 bool attributes,
@@ -19096,7 +18503,7 @@
  * the actual child nodes of an element until strictly necessary greatly
  * improving performance for the typical cases where it is not required.
  */
-class _ChildNodeListLazy extends ListBase<Node> {
+class _ChildNodeListLazy extends ListBase<Node> implements NodeListWrapper {
   final Node _this;
 
   _ChildNodeListLazy(this._this);
@@ -19248,6 +18655,8 @@
   }
 
   Node operator[](int index) => _this.childNodes[index];
+
+  List<Node> get rawList => _this.childNodes;
 }
 
 
@@ -19327,13 +18736,6 @@
    * Print out a String representation of this Node.
    */
   String toString() => nodeValue == null ? super.toString() : nodeValue;
-
-  /**
-   * Use ownerDocument instead.
-   */
-  @deprecated
-  Document get document => ownerDocument;
-
   // To suppress missing implicit constructor warnings.
   factory Node._() { throw new UnsupportedError("Not supported"); }
 
@@ -19668,22 +19070,6 @@
   Node _item(int index) native "NodeList_item_Callback";
 
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable()
-@DomName('Notation')
-// http://dom.spec.whatwg.org/#notation
-@deprecated // deprecated
-class Notation extends Node {
-  // To suppress missing implicit constructor warnings.
-  factory Notation._() { throw new UnsupportedError("Not supported"); }
-
-}
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
@@ -19839,47 +19225,6 @@
 // WARNING: Do not edit - generated code.
 
 
-@DocsEditable()
-@DomName('NotificationCenter')
-@SupportedBrowser(SupportedBrowser.CHROME)
-@SupportedBrowser(SupportedBrowser.SAFARI)
-@Experimental()
-// http://www.w3.org/TR/notifications/#showing-a-notification
-@deprecated // deprecated
-class NotificationCenter extends NativeFieldWrapperClass2 {
-  // To suppress missing implicit constructor warnings.
-  factory NotificationCenter._() { throw new UnsupportedError("Not supported"); }
-
-  /// Checks if this type is supported on the current platform.
-  static bool get supported => true;
-
-  @DomName('NotificationCenter.checkPermission')
-  @DocsEditable()
-  int checkPermission() native "NotificationCenter_checkPermission_Callback";
-
-  @DomName('NotificationCenter.createNotification')
-  @DocsEditable()
-  Notification createNotification(String iconUrl, String title, String body) native "NotificationCenter_createNotification_Callback";
-
-  @DomName('NotificationCenter.requestPermission')
-  @DocsEditable()
-  void _requestPermission([VoidCallback callback]) native "NotificationCenter_requestPermission_Callback";
-
-  Future requestPermission() {
-    var completer = new Completer();
-    _requestPermission(
-        () { completer.complete(); });
-    return completer.future;
-  }
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
 @DomName('NotificationPermissionCallback')
 // http://www.w3.org/TR/notifications/#notificationpermissioncallback
 @Experimental()
@@ -26154,13 +25499,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");
@@ -27787,7 +27132,7 @@
   @SupportedBrowser(SupportedBrowser.SAFARI)
   @Experimental()
   @Experimental() // untriaged
-  NotificationCenter get notifications native "WorkerGlobalScope_webkitNotifications_Getter";
+  _NotificationCenter get _webkitNotifications native "WorkerGlobalScope_webkitNotifications_Getter";
 
   @DomName('WorkerGlobalScope.close')
   @DocsEditable()
@@ -28349,6 +27694,22 @@
 
 
 @DocsEditable()
+@DomName('CSSUnknownRule')
+// http://dev.w3.org/csswg/cssom/#the-cssstylesheet-interface
+@deprecated // deprecated
+abstract class _CSSUnknownRule extends CssRule {
+  // To suppress missing implicit constructor warnings.
+  factory _CSSUnknownRule._() { throw new UnsupportedError("Not supported"); }
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('CSSValue')
 // http://dev.w3.org/csswg/cssom/
 @deprecated // deprecated
@@ -28431,7 +27792,7 @@
   /**
    * Tests whether `this` entirely contains [another].
    */
-  bool contains(Rectangle<num> another) {
+  bool containsRectangle(Rectangle<num> another) {
     return left <= another.left &&
            left + width >= another.left + another.width &&
            top <= another.top &&
@@ -29016,6 +28377,26 @@
 
 
 @DocsEditable()
+@DomName('HTMLAllCollection')
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#dom-document-all
+@deprecated // deprecated
+abstract class _HTMLAllCollection extends NativeFieldWrapperClass2 {
+  // To suppress missing implicit constructor warnings.
+  factory _HTMLAllCollection._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('HTMLAllCollection.item')
+  @DocsEditable()
+  Node _item(int index) native "HTMLAllCollection_item_Callback";
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable()
 @DomName('HTMLAppletElement')
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/obsolete.html#the-applet-element
 @deprecated // deprecated
@@ -29166,6 +28547,31 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+
+@DomName('MutationEvent')
+// http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents
+@deprecated
+abstract class _MutationEvent extends Event {
+  factory _MutationEvent(String type,
+      {bool canBubble: false, bool cancelable: false, Node relatedNode,
+      String prevValue, String newValue, String attrName, int attrChange: 0}) {
+
+    var event = document._createEvent('MutationEvent');
+    event._initMutationEvent(type, canBubble, cancelable, relatedNode,
+        prevValue, newValue, attrName, attrChange);
+    return event;
+  }
+  // To suppress missing implicit constructor warnings.
+  factory _MutationEvent._() { throw new UnsupportedError("Not supported"); }
+
+}
+
+
+
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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.
 
 
@@ -29267,6 +28673,44 @@
 
 
 @DocsEditable()
+@DomName('Notation')
+// http://dom.spec.whatwg.org/#notation
+@deprecated // deprecated
+abstract class _Notation extends Node {
+  // To suppress missing implicit constructor warnings.
+  factory _Notation._() { throw new UnsupportedError("Not supported"); }
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('NotificationCenter')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
+// http://www.w3.org/TR/notifications/#showing-a-notification
+@deprecated // deprecated
+abstract class _NotificationCenter extends NativeFieldWrapperClass2 {
+  // To suppress missing implicit constructor warnings.
+  factory _NotificationCenter._() { throw new UnsupportedError("Not supported"); }
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable()
 @DomName('PagePopupController')
 @deprecated // nonstandard
 abstract class _PagePopupController extends NativeFieldWrapperClass2 {
@@ -29574,6 +29018,82 @@
 
 
 @DocsEditable()
+@DomName('WebKitCSSFilterValue')
+// http://dev.w3.org/csswg/cssom/
+@deprecated // deprecated
+abstract class _WebKitCSSFilterValue extends _CssValueList {
+  // To suppress missing implicit constructor warnings.
+  factory _WebKitCSSFilterValue._() { throw new UnsupportedError("Not supported"); }
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('WebKitCSSMatrix')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental()
+// http://dev.w3.org/csswg/cssom/
+@deprecated // deprecated
+abstract class _WebKitCSSMatrix extends NativeFieldWrapperClass2 {
+  // To suppress missing implicit constructor warnings.
+  factory _WebKitCSSMatrix._() { throw new UnsupportedError("Not supported"); }
+
+  @DomName('WebKitCSSMatrix.WebKitCSSMatrix')
+  @DocsEditable()
+  factory _WebKitCSSMatrix([String cssValue]) {
+    return _WebKitCSSMatrix._create_1(cssValue);
+  }
+
+  @DocsEditable()
+  static _WebKitCSSMatrix _create_1(cssValue) native "WebKitCSSMatrix__create_1constructorCallback";
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('WebKitCSSMixFunctionValue')
+// http://dev.w3.org/csswg/cssom/
+@deprecated // deprecated
+abstract class _WebKitCSSMixFunctionValue extends _CssValueList {
+  // To suppress missing implicit constructor warnings.
+  factory _WebKitCSSMixFunctionValue._() { throw new UnsupportedError("Not supported"); }
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('WebKitCSSTransformValue')
+// http://dev.w3.org/csswg/cssom/
+@deprecated // deprecated
+abstract class _WebKitCSSTransformValue extends _CssValueList {
+  // To suppress missing implicit constructor warnings.
+  factory _WebKitCSSTransformValue._() { throw new UnsupportedError("Not supported"); }
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for 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('WebKitMediaSource')
 @Experimental() // untriaged
 abstract class _WebKitMediaSource extends EventTarget {
@@ -33936,7 +33456,8 @@
  * A list which just wraps another list, for either intercepting list calls or
  * retyping the list (for example, from List<A> to List<B> where B extends A).
  */
-class _WrappedList<E> extends ListBase<E> {
+class _WrappedList<E extends Node> extends ListBase<E>
+    implements NodeListWrapper {
   final List _list;
 
   _WrappedList(this._list);
@@ -33986,6 +33507,8 @@
   void fillRange(int start, int end, [E fillValue]) {
     _list.fillRange(start, end, fillValue);
   }
+
+  List<Node> get rawList => _list;
 }
 
 /**
diff --git a/sdk/lib/html/html_common/conversions.dart b/sdk/lib/html/html_common/conversions.dart
index 5d60866..3bd2973 100644
--- a/sdk/lib/html/html_common/conversions.dart
+++ b/sdk/lib/html/html_common/conversions.dart
@@ -294,6 +294,39 @@
   return copy;
 }
 
+// Conversions for ContextAttributes.
+//
+// On Firefox, the returned ContextAttributes is a plain object.
+class _TypedContextAttributes implements gl.ContextAttributes {
+  bool alpha;
+  bool antialias;
+  bool depth;
+  bool premultipliedAlpha;
+  bool preserveDrawingBuffer;
+  bool stencil;
+
+  _TypedContextAttributes(this.alpha, this.antialias, this.depth,
+      this.premultipliedAlpha, this.preserveDrawingBuffer, this.stencil);
+}
+
+gl.ContextAttributes convertNativeToDart_ContextAttributes(
+    nativeContextAttributes) {
+  if (nativeContextAttributes is gl.ContextAttributes) {
+    return nativeContextAttributes;
+  }
+
+  // On Firefox the above test fails because ContextAttributes is a plain
+  // object so we create a _TypedContextAttributes.
+
+  return new _TypedContextAttributes(
+      JS('var', '#.alpha', nativeContextAttributes),
+      JS('var', '#.antialias', nativeContextAttributes),
+      JS('var', '#.depth', nativeContextAttributes),
+      JS('var', '#.premultipliedAlpha', nativeContextAttributes),
+      JS('var', '#.preserveDrawingBuffer', nativeContextAttributes),
+      JS('var', '#.stencil', nativeContextAttributes));
+}
+
 // Conversions for ImageData
 //
 // On Firefox, the returned ImageData is a plain object.
@@ -318,11 +351,11 @@
 
   if (nativeImageData is ImageData) return nativeImageData;
 
-  // On Firefox the above test fails because imagedata is a plain object.
-  // So we create a _TypedImageData.
+  // On Firefox the above test fails because [nativeImageData] is a plain
+  // object.  So we create a _TypedImageData.
 
   return new _TypedImageData(
-      JS('var', '#.data', nativeImageData),
+      JS('Uint8ClampedList', '#.data', nativeImageData),
       JS('var', '#.height', nativeImageData),
       JS('var', '#.width', nativeImageData));
 }
diff --git a/sdk/lib/html/html_common/filtered_element_list.dart b/sdk/lib/html/html_common/filtered_element_list.dart
index 64326a4..c44ad56 100644
--- a/sdk/lib/html/html_common/filtered_element_list.dart
+++ b/sdk/lib/html/html_common/filtered_element_list.dart
@@ -8,7 +8,8 @@
  * An indexable collection of a node's descendants in the document tree,
  * filtered so that only elements are in the collection.
  */
-class FilteredElementList<T extends Element> extends ListBase<T> {
+class FilteredElementList<T extends Element> extends ListBase<T>
+    implements NodeListWrapper{
   final Node _node;
   final List<Node> _childNodes;
 
@@ -131,4 +132,6 @@
   int get length => _filtered.length;
   Element operator [](int index) => _filtered[index];
   Iterator<Element> get iterator => _filtered.iterator;
+
+  List<Node> get rawList => _node.childNodes;
 }
diff --git a/sdk/lib/html/html_common/html_common.dart b/sdk/lib/html/html_common/html_common.dart
index 72d5dab..c504a37 100644
--- a/sdk/lib/html/html_common/html_common.dart
+++ b/sdk/lib/html/html_common/html_common.dart
@@ -14,7 +14,3 @@
 part 'device.dart';
 part 'filtered_element_list.dart';
 part 'lists.dart';
-
-// For annotating deprecated APIs.
-// TODO: remove once @deprecated is added to dart core.
-const deprecated = 0;
diff --git a/sdk/lib/html/html_common/html_common_dart2js.dart b/sdk/lib/html/html_common/html_common_dart2js.dart
index 3afd514..f35a65e 100644
--- a/sdk/lib/html/html_common/html_common_dart2js.dart
+++ b/sdk/lib/html/html_common/html_common_dart2js.dart
@@ -6,6 +6,7 @@
 
 import 'dart:collection';
 import 'dart:html';
+import 'dart:web_gl' as gl;
 import 'dart:typed_data';
 import 'dart:_js_helper' show Creates, Returns;
 import 'dart:_foreign_helper' show JS;
@@ -19,7 +20,3 @@
 part 'device.dart';
 part 'filtered_element_list.dart';
 part 'lists.dart';
-
-// For annotating deprecated APIs.
-// TODO: remove once @deprecated is added to dart core.
-const deprecated = 0;
diff --git a/sdk/lib/html/html_common/lists.dart b/sdk/lib/html/html_common/lists.dart
index b565aba..5c230a9 100644
--- a/sdk/lib/html/html_common/lists.dart
+++ b/sdk/lib/html/html_common/lists.dart
@@ -66,3 +66,10 @@
     return accumulator;
   }
 }
+
+/**
+ * For accessing underlying node lists, for dart:js interop.
+ */
+class NodeListWrapper {
+  List<Node> get rawList;
+}
diff --git a/sdk/lib/io/common.dart b/sdk/lib/io/common.dart
index 5f1700f..94b932a 100644
--- a/sdk/lib/io/common.dart
+++ b/sdk/lib/io/common.dart
@@ -31,9 +31,9 @@
     case _OSERROR_RESPONSE:
       var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE],
                             response[_OSERROR_RESPONSE_ERROR_CODE]);
-      return new FileException(message, path, err);
+      return new FileSystemException(message, path, err);
     case _FILE_CLOSED_RESPONSE:
-      return new FileException("File closed", path);
+      return new FileSystemException("File closed", path);
     default:
       return new Exception("Unknown error");
   }
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 95e6aa8..8f54a39 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -86,7 +86,7 @@
    * Returns a [:Future<Directory>:] that completes with the newly
    * created temporary directory.
    */
-  Future<Directory> createTemp([String template]);
+  Future<Directory> createTemp([String prefix]);
 
   /**
    * Synchronously creates a temporary directory in this directory.
@@ -96,7 +96,7 @@
    *
    * Returns the newly created temporary directory.
    */
-  Directory createTempSync([String template]);
+  Directory createTempSync([String prefix]);
 
   Future<String> resolveSymbolicLinks();
 
@@ -187,32 +187,3 @@
    */
   final String path;
 }
-
-
-class DirectoryException implements IOException {
-  const DirectoryException([String this.message = "",
-                            String this.path = "",
-                            OSError this.osError = null]);
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write("DirectoryException");
-    if (!message.isEmpty) {
-      sb.write(": $message");
-      if (path != null) {
-        sb.write(", path = $path");
-      }
-      if (osError != null) {
-        sb.write(" ($osError)");
-      }
-    } else if (osError != null) {
-      sb.write(": $osError");
-      if (path != null) {
-        sb.write(", path = $path");
-      }
-    }
-    return sb.toString();
-  }
-  final String message;
-  final String path;
-  final OSError osError;
-}
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index 662107f..af7fe54 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -27,7 +27,7 @@
   static Directory get current {
     var result = _current();
     if (result is OSError) {
-      throw new DirectoryException(
+      throw new FileSystemException(
           "Getting current working directory failed", "", result);
     }
     return new _Directory(result);
@@ -38,7 +38,7 @@
     var result = _setCurrent(path);
     if (result is ArgumentError) throw result;
     if (result is OSError) {
-      throw new DirectoryException(
+      throw new FileSystemException(
           "Setting current working directory failed", path, result);
     }
   }
@@ -55,7 +55,7 @@
   bool existsSync() {
     var result = _exists(path);
     if (result is OSError) {
-      throw new DirectoryException("Exists failed", path, result);
+      throw new FileSystemException("Exists failed", path, result);
     }
     return (result == 1);
   }
@@ -143,7 +143,7 @@
     if (recursive) return createRecursivelySync();
     var result = _create(path);
     if (result is OSError) {
-      throw new DirectoryException("Creation failed", path, result);
+      throw new FileSystemException("Creation failed", path, result);
     }
   }
 
@@ -187,7 +187,7 @@
     }
     var result = _createTemp(fullPrefix);
     if (result is OSError) {
-      throw new DirectoryException("Creation of temporary directory failed",
+      throw new FileSystemException("Creation of temporary directory failed",
                                    fullPrefix,
                                    result);
     }
@@ -207,7 +207,7 @@
   void _deleteSync({bool recursive: false}) {
     var result = _deleteNative(path, recursive);
     if (result is OSError) {
-      throw new DirectoryException("Deletion failed", path, result);
+      throw new FileSystemException("Deletion failed", path, result);
     }
   }
 
@@ -227,7 +227,7 @@
     }
     var result = _rename(path, newPath);
     if (result is OSError) {
-      throw new DirectoryException("Rename failed", path, result);
+      throw new FileSystemException("Rename failed", path, result);
     }
     return new Directory(newPath);
   }
@@ -264,7 +264,7 @@
       case _OSERROR_RESPONSE:
         var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE],
                               response[_OSERROR_RESPONSE_ERROR_CODE]);
-        return new DirectoryException(message, path, err);
+        return new FileSystemException(message, path, err);
       default:
         return new Exception("Unknown error");
     }
@@ -362,7 +362,7 @@
           }
         }
       } else {
-        controller.addError(new DirectoryException("Internal error"));
+        controller.addError(new FileSystemException("Internal error"));
       }
       nextRunning = false;
       next();
@@ -391,12 +391,12 @@
       var errorPath = message[RESPONSE_PATH];
       if (errorPath == null) errorPath = path;
       controller.addError(
-          new DirectoryException("Directory listing failed",
+          new FileSystemException("Directory listing failed",
                                  errorPath,
                                  err));
     } else {
       controller.addError(
-          new DirectoryException("Internal error"));
+          new FileSystemException("Internal error"));
     }
   }
 }
diff --git a/sdk/lib/io/eventhandler.dart b/sdk/lib/io/eventhandler.dart
index 376b799..4e3ee93 100644
--- a/sdk/lib/io/eventhandler.dart
+++ b/sdk/lib/io/eventhandler.dart
@@ -6,6 +6,6 @@
 
 class _EventHandler {
   external static void _sendData(Object sender,
-                                 ReceivePort receivePort,
+                                 RawReceivePort receivePort,
                                  int data);
 }
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index b7bfea2..174ca41 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -55,7 +55,7 @@
    * by [createSync]. Calling [createSync] on an existing file might fail
    * if there are restrictive permissions on the file.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   void createSync();
 
@@ -96,7 +96,7 @@
   /**
    * Synchronously get the length of the file.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   int lengthSync();
 
@@ -120,7 +120,7 @@
    * Get the last-modified time of the file. Throws an exception
    * if the file does not exist.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   DateTime lastModifiedSync();
 
@@ -151,7 +151,7 @@
    *
    * See [open] for information on the [mode] argument.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   RandomAccessFile openSync({FileMode mode: FileMode.READ});
 
@@ -168,7 +168,7 @@
   /**
    * Synchronously get the canonical full path corresponding to the file path.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    *
    * *FullPathSync is deprecated.  Use absolutePathSync or
    * resolveSymbolicLinksSync instead.  FullPathSync will be removed
@@ -221,7 +221,7 @@
   /**
    * Synchronously read the entire file contents as a list of bytes.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   List<int> readAsBytesSync();
 
@@ -238,7 +238,7 @@
    * Synchronously read the entire file contents as a string using the
    * given [Encoding].
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   String readAsStringSync({Encoding encoding: UTF8});
 
@@ -255,7 +255,7 @@
    * Synchronously read the entire file contents as lines of text
    * using the given [Encoding].
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   List<String> readAsLinesSync({Encoding encoding: UTF8});
 
@@ -281,7 +281,7 @@
    * the file if it already exists. In order to append the bytes to an existing
    * file, pass [FileMode.APPEND] as the optional mode parameter.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   void writeAsBytesSync(List<int> bytes, {FileMode mode: FileMode.WRITE});
 
@@ -311,7 +311,7 @@
    * to an existing file, pass [FileMode.APPEND] as the optional mode
    * parameter.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   void writeAsStringSync(String contents,
                          {FileMode mode: FileMode.WRITE,
@@ -339,7 +339,7 @@
   /**
    * Synchronously closes the file.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   void closeSync();
 
@@ -353,7 +353,7 @@
    * Synchronously reads a single byte from the file. If end-of-file
    * has been reached -1 is returned.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   int readByteSync();
 
@@ -366,7 +366,7 @@
    * Synchronously reads a maximum of [bytes] bytes from a file and
    * returns the result in a list of bytes.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   List<int> readSync(int bytes);
 
@@ -388,7 +388,7 @@
    * read into [buffer], otherwise up to [buffer.length]. If [end] == [start]
    * nothing happends.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   int readIntoSync(List<int> buffer, [int start, int end]);
 
@@ -403,7 +403,7 @@
    * Synchronously writes a single byte to the file. Returns the
    * number of bytes successfully written.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   int writeByteSync(int value);
 
@@ -423,7 +423,7 @@
    * start from index 0. If [end] is omitted, it will write to the end of
    * [buffer].
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   void writeFromSync(List<int> buffer, [int start, int end]);
 
@@ -439,7 +439,7 @@
    * Synchronously writes a single string to the file using the given
    * [Encoding].
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   void writeStringSync(String string,
                        {Encoding encoding: UTF8});
@@ -453,7 +453,7 @@
   /**
    * Synchronously gets the current byte position in the file.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   int positionSync();
 
@@ -467,7 +467,7 @@
   /**
    * Synchronously sets the byte position in the file.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   void setPositionSync(int position);
 
@@ -481,7 +481,7 @@
   /**
    * Synchronously truncates (or extends) the file to [length] bytes.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   void truncateSync(int length);
 
@@ -494,7 +494,7 @@
   /**
    * Synchronously gets the length of the file.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   int lengthSync();
 
@@ -508,7 +508,7 @@
   /**
    * Synchronously flushes the contents of the file to disk.
    *
-   * Throws a [FileException] if the operation fails.
+   * Throws a [FileSystemException] if the operation fails.
    */
   void flushSync();
 
@@ -524,17 +524,17 @@
 }
 
 
-class FileException implements IOException {
+class FileSystemException implements IOException {
   final String message;
   final String path;
   final OSError osError;
-  const FileException([String this.message = "",
-                       String this.path = "",
-                       OSError this.osError]);
+  const FileSystemException([String this.message = "",
+                             String this.path = "",
+                             OSError this.osError]);
 
   String toString() {
     StringBuffer sb = new StringBuffer();
-    sb.write("FileException");
+    sb.write("FileSystemException");
     if (!message.isEmpty) {
       sb.write(": $message");
       if (path != null) {
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 5249f9f..71dca70 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -369,7 +369,7 @@
     if (mode != FileMode.READ &&
         mode != FileMode.WRITE &&
         mode != FileMode.APPEND) {
-      throw new FileException("Unknown file mode. Use FileMode.READ, "
+      throw new FileSystemException("Unknown file mode. Use FileMode.READ, "
                               "FileMode.WRITE or FileMode.APPEND.",
                               path);
     }
@@ -383,7 +383,7 @@
   static RandomAccessFile _openStdioSync(int fd) {
     var id = _openStdio(fd);
     if (id == 0) {
-      throw new FileException("Cannot open stdio file for: $fd");
+      throw new FileSystemException("Cannot open stdio file for: $fd");
     }
     return new _RandomAccessFile(id, "");
   }
@@ -437,7 +437,7 @@
     try {
       return encoding.decode(bytes);
     } catch (_) {
-      throw new FileException(
+      throw new FileSystemException(
           "Failed to decode data using encoding '${encoding.name}'", path);
     }
   }
@@ -465,7 +465,7 @@
     controller.add(bytes);
     controller.close();
     if (error != null) {
-      throw new FileException(
+      throw new FileSystemException(
           "Failed to decode data using encoding '${encoding.name}'", path);
     }
     return list;
@@ -519,7 +519,7 @@
 
   static throwIfError(Object result, String msg, String path) {
     if (result is OSError) {
-      throw new FileException(msg, path, result);
+      throw new FileSystemException(msg, path, result);
     }
   }
 }
@@ -539,7 +539,7 @@
         _id = result;
         return this;
       } else {
-        throw new FileException("Cannot close file", path);
+        throw new FileSystemException("Cannot close file", path);
       }
     });
   }
@@ -550,7 +550,7 @@
     _checkAvailable();
     var id = _close(_id);
     if (id == -1) {
-      throw new FileException("Cannot close file", path);
+      throw new FileSystemException("Cannot close file", path);
     }
     _id = id;
   }
@@ -570,7 +570,7 @@
     _checkAvailable();
     var result = _readByte(_id);
     if (result is OSError) {
-      throw new FileException("readByte failed", path, result);
+      throw new FileSystemException("readByte failed", path, result);
     }
     return result;
   }
@@ -596,7 +596,7 @@
     }
     var result = _read(_id, bytes);
     if (result is OSError) {
-      throw new FileException("readSync failed", path, result);
+      throw new FileSystemException("readSync failed", path, result);
     }
     return result;
   }
@@ -644,7 +644,7 @@
     _checkReadWriteListArguments(buffer.length, start, end);
     var result = _readInto(_id, buffer, start, end);
     if (result is OSError) {
-      throw new FileException("readInto failed", path, result);
+      throw new FileSystemException("readInto failed", path, result);
     }
     return result;
   }
@@ -670,7 +670,7 @@
     }
     var result = _writeByte(_id, value);
     if (result is OSError) {
-      throw new FileException("writeByte failed", path, result);
+      throw new FileSystemException("writeByte failed", path, result);
     }
     return result;
   }
@@ -722,7 +722,7 @@
                             bufferAndStart.start,
                             end - (start - bufferAndStart.start));
     if (result is OSError) {
-      throw new FileException("writeFrom failed", path, result);
+      throw new FileSystemException("writeFrom failed", path, result);
     }
   }
 
@@ -758,7 +758,7 @@
     _checkAvailable();
     var result = _position(_id);
     if (result is OSError) {
-      throw new FileException("position failed", path, result);
+      throw new FileSystemException("position failed", path, result);
     }
     return result;
   }
@@ -779,7 +779,7 @@
     _checkAvailable();
     var result = _setPosition(_id, position);
     if (result is OSError) {
-      throw new FileException("setPosition failed", path, result);
+      throw new FileSystemException("setPosition failed", path, result);
     }
   }
 
@@ -798,7 +798,7 @@
     _checkAvailable();
     var result = _truncate(_id, length);
     if (result is OSError) {
-      throw new FileException("truncate failed", path, result);
+      throw new FileSystemException("truncate failed", path, result);
     }
   }
 
@@ -817,7 +817,7 @@
     _checkAvailable();
     var result = _length(_id);
     if (result is OSError) {
-      throw new FileException("length failed", path, result);
+      throw new FileSystemException("length failed", path, result);
     }
     return result;
   }
@@ -839,7 +839,7 @@
     _checkAvailable();
     var result = _flush(_id);
     if (result is OSError) {
-      throw new FileException("flush failed", path, result);
+      throw new FileSystemException("flush failed", path, result);
     }
   }
 
@@ -847,11 +847,11 @@
 
   Future _dispatch(int request, List data, { bool markClosed: false }) {
     if (closed) {
-      return new Future.error(new FileException("File closed", path));
+      return new Future.error(new FileSystemException("File closed", path));
     }
     if (_asyncDispatched) {
       var msg = "An async operation is currently pending";
-      return new Future.error(new FileException(msg, path));
+      return new Future.error(new FileSystemException(msg, path));
     }
     if (markClosed) {
       // Set the id_ to 0 (NULL) to ensure the no more async requests
@@ -867,10 +867,10 @@
 
   void _checkAvailable() {
     if (_asyncDispatched) {
-      throw new FileException("An async operation is currently pending", path);
+      throw new FileSystemException("An async operation is currently pending", path);
     }
     if (closed) {
-      throw new FileException("File closed", path);
+      throw new FileSystemException("File closed", path);
     }
   }
 }
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index 2594ff5..16fb764 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -225,7 +225,7 @@
    * to resolve the path, using the realpath function on linux and
    * Mac OS, and the GetFinalPathNameByHandle function on Windows.
    * If the path does not point to an existing file system object,
-   * [resolveSymbolicLinks] completes the returned Future with an FileException.
+   * [resolveSymbolicLinks] completes the returned Future with an FileSystemException.
    *
    * On Windows, symbolic links are resolved to their target before applying
    * a '..' that follows, and on other platforms, the '..' is applied to the
@@ -256,7 +256,7 @@
    * filesystem api to resolve the path, using the realpath function
    * on linux and Mac OS, and the GetFinalPathNameByHandle function on Windows.
    * If the path does not point to an existing file system object,
-   * [resolveSymbolicLinksSync] throws a FileException.
+   * [resolveSymbolicLinksSync] throws a FileSystemException.
    *
    * On Windows, symbolic links are resolved to their target before applying
    * a '..' that follows, and on other platforms, the '..' is applied to the
@@ -340,24 +340,33 @@
 
 
   /**
-   * Start watch the [FileSystemEntity] for changes.
+   * Start watching the [FileSystemEntity] for changes.
    *
-   * The implementation uses platform-depending event-based APIs for receiving
-   * file-system notifixations, thus behvaiour depends on the platform.
+   * The implementation uses platform-dependent event-based APIs for receiving
+   * file-system notifications, thus behavior depends on the platform.
    *
-   *   * `Windows`: Uses `ReadDirectoryChangesW`. The implementation supports
-   *     only watching dirctories but supports recursive watching.
+   *   * `Windows`: Uses `ReadDirectoryChangesW`. The implementation only
+   *     supports watching directories. Recursive watching is supported.
    *   * `Linux`: Uses `inotify`. The implementation supports watching both
-   *     files and dirctories, but doesn't support recursive watching.
+   *     files and directories. Recursive watching is not supported.
    *   * `Mac OS`: Uses `FSEvents`. The implementation supports watching both
-   *     files and dirctories, and also recursive watching. Note that FSEvents
-   *     always use recursion internally, so when disabled, some events are
-   *     ignored.
+   *     files and directories. Recursive watching is supported.
+   *     Note: events happened slightly before calling [watch], may be part of
+   *     the returned stream, on Mac OS.
    *
-   * The system will start listen for events once the returned [Stream] is
-   * being listened to, not when the call to [watch] is issued. Note that the
-   * returned [Stream] is endless. To stop the [Stream], simply cancel the
-   * subscription.
+   * The system will start listening for events once the returned [Stream] is
+   * being listened to, not when the call to [watch] is issued.
+   *
+   * The returned value is an endless broadcast [Stream], that only stops when
+   * one of the following happends:
+   *
+   *   * The [Stream] is canceled, e.g. by calling `cancel` on the
+   *      [StreamSubscription].
+   *   * The [FileSystemEntity] being watches, is deleted.
+   *
+   * Use `events` to specify what events to listen for. The constants in
+   * [FileSystemEvent] can be or'ed together to mix events. Default is
+   * [FileSystemEvent.ALL].
    */
   Stream<FileSystemEvent> watch({int events: FileSystemEvent.ALL,
                                  bool recursive: false})
@@ -590,7 +599,7 @@
 
   static _throwIfError(Object result, String msg, [String path]) {
     if (result is OSError) {
-      throw new FileException(msg, path, result);
+      throw new FileSystemException(msg, path, result);
     } else if (result is ArgumentError) {
       throw result;
     }
@@ -616,16 +625,37 @@
 
 
 /**
- * Base event class emitted by FileSystemWatcher.
+ * Base event class emitted by [FileSystemEntity.watch].
  */
 class FileSystemEvent {
+  /**
+   * Bitfield for [FileSystemEntity.watch], to enable [FileSystemCreateEvent]s.
+   */
   static const int CREATE = 1 << 0;
+
+  /**
+   * Bitfield for [FileSystemEntity.watch], to enable [FileSystemModifyEvent]s.
+   */
   static const int MODIFY = 1 << 1;
+
+  /**
+   * Bitfield for [FileSystemEntity.watch], to enable [FileSystemDeleteEvent]s.
+   */
   static const int DELETE = 1 << 2;
+
+  /**
+   * Bitfield for [FileSystemEntity.watch], to enable [FileSystemMoveEvent]s.
+   */
   static const int MOVE = 1 << 3;
+
+  /**
+   * Bitfield for [FileSystemEntity.watch], for enabling all of [CREATE],
+   * [MODIFY], [DELETE] and [MOVE].
+   */
   static const int ALL = CREATE | MODIFY | DELETE | MOVE;
 
   static const int _MODIFY_ATTRIBUTES = 1 << 4;
+  static const int _DELETE_SELF = 1 << 5;
 
   /**
    * The type of event. See [FileSystemEvent] for a list of events.
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index ab3ba64..d830e38 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -106,7 +106,7 @@
    * directory containing the link.
    *
    * If the link does not exist, or is not a link, the future completes with
-   * a LinkException.
+   * a FileSystemException.
    */
   Future<String> target();
 
@@ -116,7 +116,7 @@
    * If the returned target is a relative path, it is relative to the
    * directory containing the link.
    *
-   * If the link does not exist, or is not a link, throws a LinkException.
+   * If the link does not exist, or is not a link, throws a FileSystemException.
    */
   String targetSync();
 }
@@ -176,7 +176,7 @@
     if (result.length > 3 && result[1] == ':' && result[2] == '\\') {
       return '\\??\\$result';
     } else {
-      throw new LinkException(
+      throw new FileSystemException(
           'Target $result of Link.create on Windows cannot be converted' +
           ' to start with a drive letter.  Unexpected error.');
     }
@@ -254,7 +254,7 @@
 
   static throwIfError(Object result, String msg, [String path = ""]) {
     if (result is OSError) {
-      throw new LinkException(msg, path, result);
+      throw new FileSystemException(msg, path, result);
     }
   }
 
@@ -270,38 +270,9 @@
       case _OSERROR_RESPONSE:
         var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE],
                               response[_OSERROR_RESPONSE_ERROR_CODE]);
-        return new LinkException(message, path, err);
+        return new FileSystemException(message, path, err);
       default:
         return new Exception("Unknown error");
     }
   }
 }
-
-
-class LinkException implements IOException {
-  const LinkException([String this.message = "",
-                       String this.path = "",
-                       OSError this.osError = null]);
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.write("LinkException");
-    if (!message.isEmpty) {
-      sb.write(": $message");
-      if (path != null) {
-        sb.write(", path = $path");
-      }
-      if (osError != null) {
-        sb.write(" ($osError)");
-      }
-    } else if (osError != null) {
-      sb.write(": $osError");
-      if (path != null) {
-        sb.write(", path = $path");
-      }
-    }
-    return sb.toString();
-  }
-  final String message;
-  final String path;
-  final OSError osError;
-}
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index 30a9a9f..1053d37 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -5,9 +5,21 @@
 part of dart.io;
 
 /**
- * The [Platform] class exposes details of the machine and operating
+ * Deprecated: the [Platform] class exposes details of the machine and operating
  * system.
+ *
+ * This class has been replaced by adding the dart:platform library to Dart.
+ * dart:platform is available on all browser and standalone platforms,
+ * including Dart code that has been compiled to javascript.
+ *
+ * The dart:platform class has
+ * the same top-level getters as the members of [Platform], except that the
+ * [isWindows], [isLinux], [isAndroid], and [isMacOS] getters
+ * have been removed. On platforms supporting dart:io, the getters of
+ * dart:platform have the same values as the Platform class members, except
+ * that [script] has been changed from a [String] to a file [Uri].
  */
+@deprecated
 class Platform {
   static final _numberOfProcessors = _Platform.numberOfProcessors;
   static final _pathSeparator = _Platform.pathSeparator;
diff --git a/sdk/lib/io/timer_impl.dart b/sdk/lib/io/timer_impl.dart
index 4939a629b..49c0b43 100644
--- a/sdk/lib/io/timer_impl.dart
+++ b/sdk/lib/io/timer_impl.dart
@@ -11,7 +11,7 @@
   // Timers are ordered by wakeup time.
   static LinkedList<_Timer> _timers = new LinkedList<_Timer>();
 
-  static ReceivePort _receivePort;
+  static RawReceivePort _receivePort;
   static bool _handling_callbacks = false;
 
   Function _callback;
@@ -163,10 +163,7 @@
     }
 
     if(_receivePort == null) {
-      _receivePort = new ReceivePort();
-      _receivePort.receive((var message, ignored) {
-        _handleTimeout();
-      });
+      _receivePort = new RawReceivePort((_) { _handleTimeout(); });
     }
   }
 
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index 3cfc4fc..fef7ff4 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -15,62 +15,67 @@
 library dart.isolate;
 
 import "dart:async";
+import "dart:collection" show HashMap;
 
-part "isolate_stream.dart";
-
+/**
+ * Thrown when an isolate cannot be created.
+ */
 class IsolateSpawnException implements Exception {
+  // TODO(floitsch): clean up spawn exception.
   const IsolateSpawnException(String this._s);
   String toString() => "IsolateSpawnException: '$_s'";
   final String _s;
 }
 
-/**
- * The initial ReceivePort available by default for this isolate.
- *
- * This ReceivePort is created automatically
- * and is commonly used to establish
- * the first communication between isolates.
- * (See [spawnFunction] and [spawnUri].)
- */
-ReceivePort get port => _Isolate.port;
+class Isolate {
+
+  final SendPort _controlPort;
+
+  Isolate._fromControlPort(SendPort controlPort)
+      : this._controlPort = controlPort;
+
+  /**
+   * Creates and spawns an isolate that shares the same code as the current
+   * isolate.
+   *
+   * The argument [entryPoint] specifies the entry point of the spawned
+   * isolate. It must be a static top-level function or a static method that
+   * takes no arguments. It is not allowed to pass a function closure.
+   *
+   * The entry-point function is invoked with the initial [message].
+   * Usually the initial [message] contains a [SendPort] so
+   * that the spawner and spawnee can communicate with each other.
+   *
+   * Returns a future that will complete with an [Isolate] instance. The
+   * isolate instance can be used to control the spawned isolate.
+   */
+  external static Future<Isolate> spawn(void entryPoint(message), var message);
+
+  /**
+   * Creates and spawns an isolate that runs the code from the library with
+   * the specified URI.
+   *
+   * The isolate starts executing the top-level `main` function of the library
+   * with the given URI.
+   *
+   * The target `main` may have one of the four following signatures:
+   *
+   * * `main()`
+   * * `main(args)`
+   * * `main(args, message)`
+   *
+   * When present, the argument `message` is set to the initial [message].
+   * When present, the argument `args` is set to the provided [args] list.
+   *
+   * Returns a future that will complete with an [Isolate] instance. The
+   * isolate instance can be used to control the spawned isolate.
+   */
+  external static Future<Isolate> spawnUri(
+      Uri uri, List<String> args, var message);
+}
 
 /**
- * Creates and spawns an isolate
- * that shares the same code as the current isolate,
- * but that starts from the specified function.
- *
- * The [topLevelFunction] argument must be
- * a static top-level function or a static method that takes no
- * arguments. It is illegal to pass a function closure.
- *
- * When any isolate starts (even the main script of the application), a default
- * [ReceivePort] is created for it. This port is available from the top-level
- * getter [port] defined in this library.
- *
- * This function returns a [SendPort] derived from
- * the child isolate's default port.
- *
- * The optional [unhandledExceptionCallback] argument is invoked whenever an
- * exception inside the isolate is unhandled. It can be seen as a big
- * `try/catch` around everything that is executed inside the isolate. The
- * callback should return `true` if it was able to handle the exception.
- */
-SendPort spawnFunction(void topLevelFunction(),
-    [bool unhandledExceptionCallback(IsolateUnhandledException e)])
-    => _Isolate.spawnFunction(topLevelFunction, unhandledExceptionCallback);
-
-/**
- * Creates and spawns an isolate that runs the code from the specified URI.
- *
- * As with [spawnFunction],
- * the child isolate has a default [ReceivePort],
- * and this function returns a [SendPort] derived from it.
- */
-SendPort spawnUri(String uri) => _Isolate.spawnUri(uri);
-
-/**
- * Together with [ReceivePort],
- * the only means of communication between isolates.
+ * Sends messages to its [ReceivePort]s.
  *
  * [SendPort]s are created from [ReceivePort]s. Any message sent through
  * a [SendPort] is delivered to its respective [ReceivePort]. There might be
@@ -82,8 +87,7 @@
 
   /**
    * Sends an asynchronous [message] to this send port. The message is copied to
-   * the receiving isolate. If specified, the [replyTo] port will be provided to
-   * the receiver to facilitate exchanging sequences of messages.
+   * the receiving isolate.
    *
    * The content of [message] can be: primitive values (null, num, bool, double,
    * String), instances of [SendPort], and lists and maps whose elements are any
@@ -95,22 +99,11 @@
    * process). This is currently only supported by the dartvm.  For now, the
    * dart2js compiler only supports the restricted messages described above.
    *
-   * Deprecation note: it is no longer valid to transmit a [ReceivePort] in a
-   * message. Previously they were translated to the corresponding send port
-   * before being transmitted.
+   * The second argument [replyTo] is deprecated and its value is ignored.
    */
   void send(var message, [SendPort replyTo]);
 
   /**
-   * Sends a message to this send port and returns a [Future] of the reply.
-   * Basically, this internally creates a new receive port, sends a
-   * message to this send port with replyTo set to such receive port, and, when
-   * a reply is received, it closes the receive port and completes the returned
-   * future.
-   */
-  Future call(var message);
-
-  /**
    * Tests whether [other] is a [SendPort] pointing to the same
    * [ReceivePort] as this one.
    */
@@ -121,49 +114,95 @@
    * consistent with the == operator.
    */
   int get hashCode;
-
 }
 
 /**
- * Together with [SendPort], the only means of
- * communication between isolates.
+ * Together with [SendPort], the only means of communication between isolates.
  *
- * [ReceivePort]s have a [:toSendPort:] method
- * which returns a [SendPort]. Any message that is sent through this [SendPort]
- * is delivered to the [ReceivePort] it has been created from. There, they are
- * dispatched to the callback that has been registered on the receive port.
+ * [ReceivePort]s have a `sendport` getter which returns a [SendPort].
+ * Any message that is sent through this [SendPort]
+ * is delivered to the [ReceivePort] it has been created from. There, the
+ * message is dispatched to its listener.
+ *
+ * A [ReceivePort] is a non-broadcast stream. This means that it buffers
+ * incoming messages until a listener is registered. Only one listener can
+ * receive messages. See [Stream.asBroadcastStream] for transforming the port
+ * to a broadcast stream.
  *
  * A [ReceivePort] may have many [SendPort]s.
  */
-abstract class ReceivePort {
+abstract class ReceivePort implements Stream {
 
   /**
-   * Opens a long-lived port for receiving messages. The returned port
-   * must be explicitly closed through [ReceivePort.close].
+   * Opens a long-lived port for receiving messages.
+   *
+   * A [ReceivePort] is a non-broadcast stream. This means that it buffers
+   * incoming messages until a listener is registered. Only one listener can
+   * receive messages. See [Stream.asBroadcastStream] for transforming the port
+   * to a broadcast stream.
+   *
+   * A receive port is closed by canceling its subscription.
    */
   external factory ReceivePort();
 
   /**
-   * Sets up a callback function for receiving pending or future
-   * messages on this receive port.
+   * Creates a [ReceivePort] from a [RawReceivePort].
+   *
+   * The handler of the given [rawPort] is overwritten during the construction
+   * of the result.
    */
-  void receive(void callback(var message, SendPort replyTo));
+  external factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort);
 
   /**
-   * Closes this receive port immediately. Pending messages will not
-   * be processed and it is impossible to re-open the port. Single-shot
-   * reply ports, such as those created through [SendPort.call], are
-   * automatically closed when the reply has been received. Multiple
-   * invocations of [close] are allowed but ignored.
+   * Inherited from [Stream].
+   *
+   * Note that all named arguments are ignored since a ReceivePort will never
+   * receive an error, or done message.
+   */
+  StreamSubscription listen(void onData(var message),
+                            { Function onError,
+                              void onDone(),
+                              bool cancelOnError });
+
+  /**
+   * Closes `this`.
+   *
+   * If the stream has not been canceled yet, adds a close-event to the event
+   * queue and discards any further incoming messages.
+   *
+   * If the stream has already been canceled this method has no effect.
    */
   void close();
 
   /**
-   * Creates a new send port that sends to this receive port. It is legal to
-   * create several [SendPort]s from the same [ReceivePort].
+   * Returns a send port that sends to this receive port.
    */
-  SendPort toSendPort();
+  SendPort get sendPort;
+}
 
+abstract class RawReceivePort {
+  /**
+   * Opens a long-lived port for receiving messages.
+   *
+   * A [RawReceivePort] is low level and does not work with [Zone]s. It
+   * can not be paused. The data-handler must be set before the first
+   * event is received.
+   */
+  external factory RawReceivePort([void handler(event)]);
+
+  /**
+   * Sets the handler that is invoked for every incoming message.
+   *
+   * The handler is invoked in the root-zone ([Zone.ROOT]).
+   */
+  void set handler(Function newHandler);
+
+  /**
+   * Closes the port.
+   *
+   * After a call to this method any incoming message is silently dropped.
+   */
+  void close();
 }
 
 /**
@@ -172,7 +211,10 @@
  * might be many [SendPortSync]s for the same [ReceivePortSync].
  *
  * [SendPortSync]s can be transmitted to other isolates.
+ *
+ * *DEPRECATED*.
  */
+@deprecated
 abstract class SendPortSync {
   /**
    * Sends a synchronous message to this send port and returns the result.
@@ -192,22 +234,13 @@
   int get hashCode;
 }
 
-// The VM doesn't support accessing external globals in the same library. We
-// therefore create this wrapper class.
-// TODO(6997): Don't go through static class for external variables.
-abstract class _Isolate {
-  external static ReceivePort get port;
-  external static SendPort spawnFunction(void topLevelFunction(),
-    [bool unhandledExceptionCallback(IsolateUnhandledException e)]);
-  external static SendPort spawnUri(String uri);
-}
-
 /**
  * Wraps unhandled exceptions thrown during isolate execution. It is
  * used to show both the error message and the stack trace for unhandled
  * exceptions.
  */
-class IsolateUnhandledException implements Exception {
+// TODO(floitsch): probably going to remove and replace with something else.
+class _IsolateUnhandledException implements Exception {
   /** Message being handled when exception occurred. */
   final message;
 
@@ -215,9 +248,9 @@
   final source;
 
   /** Trace for the wrapped exception. */
-  final Object stackTrace;
+  final StackTrace stackTrace;
 
-  const IsolateUnhandledException(this.message, this.source, this.stackTrace);
+  const _IsolateUnhandledException(this.message, this.source, this.stackTrace);
 
   String toString() {
     return 'IsolateUnhandledException: exception while handling message: '
diff --git a/sdk/lib/isolate/isolate_sources.gypi b/sdk/lib/isolate/isolate_sources.gypi
index fdc0f95..e1c4825 100644
--- a/sdk/lib/isolate/isolate_sources.gypi
+++ b/sdk/lib/isolate/isolate_sources.gypi
@@ -6,6 +6,5 @@
   'sources': [
     'isolate.dart',
     # The above file needs to be first as it lists the parts below.
-    'isolate_stream.dart',
   ],
 }
diff --git a/sdk/lib/isolate/isolate_stream.dart b/sdk/lib/isolate/isolate_stream.dart
deleted file mode 100644
index 922f6f9..0000000
--- a/sdk/lib/isolate/isolate_stream.dart
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart.isolate;
-
-/**
- * The initial IsolateStream available by default for this isolate.
- *
- * This IsolateStream is created automatically and is commonly used
- * to establish the first communication between isolates.
- * (See [streamSpawnFunction].)
- */
-final IsolateStream stream = new IsolateStream._fromOriginalReceivePort(port);
-
-/**
- * The creator of the [IsolateStream] and [IsolateSink]
- * that allow an isolate to exchange messages with other isolates.
- *
- * Any message that is written into the [sink] (independent of the isolate) is
- * sent to the [stream] where its subscribers can react to the messages.
- */
-class MessageBox {
-  final IsolateStream stream;
-  final IsolateSink sink;
-
-  external MessageBox.oneShot();
-  external MessageBox();
-}
-
-external bool _isCloseToken(var object);
-
-/**
- * Together with [IsolateSink], the only means of
- * communication between isolates.
- *
- * Each IsolateStream has a corresponding
- * [IsolateSink]. Any message written into that sink will be delivered to
- * the stream and then dispatched to the stream's subscribers.
- */
-class IsolateStream extends Stream<dynamic> {
-  bool _isClosed = false;
-  final ReceivePort _port;
-  StreamController _controller = new StreamController(sync: true);
-
-  IsolateStream._fromOriginalReceivePort(this._port) {
-    _port.receive((message, replyTo) {
-      assert(replyTo == null);
-      _add(message);
-    });
-  }
-
-  IsolateStream._fromOriginalReceivePortOneShot(this._port) {
-    _port.receive((message, replyTo) {
-      assert(replyTo == null);
-      _add(message);
-      close();
-    });
-  }
-
-  void _add(var message) {
-    if (_isCloseToken(message)) {
-      close();
-    } else {
-      _controller.sink.add(message);
-    }
-  }
-
-  /**
-   * Closes the stream from the receiving end.
-   *
-   * Closing an already closed port has no effect.
-   */
-  void close() {
-    if (!_isClosed) {
-      _isClosed = true;
-      _port.close();
-      _controller.close();
-    }
-  }
-
-  StreamSubscription listen(void onData(event),
-                            { void onError(error),
-                              void onDone(),
-                              bool cancelOnError}) {
-      return _controller.stream.listen(onData,
-                                       onError: onError,
-                                       onDone: onDone,
-                                       cancelOnError: cancelOnError);
-  }
-}
-
-/**
- * The feed for an [IsolateStream].
- * 
- * Any message written to [this] is delivered
- * to its respective [IsolateStream].
- * [IsolateSink]s are created by [MessageBox]es.
- *
- * [IsolateSink]s can be transmitted to other isolates.
- */
-abstract class IsolateSink extends EventSink<dynamic> {
-  // TODO(floitsch): Actually it should be a StreamSink (being able to flow-
-  // control).
-
-  /**
-   * Sends an asynchronous [message] to the linked [IsolateStream];
-   * the message is copied to the receiving isolate.
-   *
-   * The content of [message] can be: primitive values (null, num, bool, double,
-   * String), instances of [IsolateSink]s, and lists and maps whose elements are
-   * any of these. List and maps are also allowed to be cyclic.
-   *
-   * In the special circumstances when two isolates share the same code and are
-   * running in the same process (e.g. isolates created via [spawnFunction]), it
-   * is also possible to send object instances (which would be copied in the
-   * process). This is currently only supported by the dartvm.  For now, the
-   * dart2js compiler only supports the restricted messages described above.
-   */
-  void add(dynamic message);
-
-  void addError(errorEvent);
-
-  /** Closing multiple times is allowed. */
-  void close();
-
-  /**
-   * Tests whether [other] is an [IsolateSink] feeding into the same
-   * [IsolateStream] as this one.
-   */
-  bool operator==(var other);
-}
-
-
-/**
- * Creates and spawns an isolate that shares the same code as the current
- * isolate, but that starts from the specified function.
- * 
- * The [topLevelFunction] argument must be
- * a static top-level function or a static method that takes no arguments.
- *
- * When any isolate starts (even the main script of the application), a default
- * [IsolateStream] is created for it. This sink is available from the top-level
- * getter [stream] defined in this library.
- *
- * [spawnFunction] returns an [IsolateSink] feeding into the child isolate's
- * default stream.
- *
- * The optional [unhandledExceptionCallback] argument is invoked whenever an
- * exception inside the isolate is unhandled. It can be seen as a big
- * `try/catch` around everything that is executed inside the isolate. The
- * callback should return `true` if it was able to handle the exception.
- */
-external IsolateSink streamSpawnFunction(
-    void topLevelFunction(),
-    [bool unhandledExceptionCallback(IsolateUnhandledException e)]);
diff --git a/sdk/lib/js/dart2js/js_dart2js.dart b/sdk/lib/js/dart2js/js_dart2js.dart
index 852b0db..9dbc193 100644
--- a/sdk/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/js/dart2js/js_dart2js.dart
@@ -2,6 +2,85 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+/**
+ * Support for interoperating with JavaScript.
+ * 
+ * This library provides access to JavaScript objects from Dart, allowing
+ * Dart code to get and set properties, and call methods of JavaScript objects
+ * and invoke JavaScript functions. The library takes care of converting
+ * between Dart and JavaScript objects where possible, or providing proxies if
+ * conversion isn't possible.
+ *
+ * This library does not yet make Dart objects usable from JavaScript, their
+ * methods and proeprties are not accessible, though it does allow Dart
+ * functions to be passed into and called from JavaScript.
+ *
+ * [JsObject] is the core type and represents a proxy of a JavaScript object.
+ * JsObject gives access to the underlying JavaScript objects properties and
+ * methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
+ * created from proxies to JavaScript constructors.
+ *
+ * The top-level getter [context] provides a [JsObject] that represents the
+ * global object in JavaScript, usually `window`.
+ *
+ * The following example shows an alert dialog via a JavaScript call to the
+ * global function `alert()`:
+ *
+ *     import 'dart:js';
+ *     
+ *     main() => context.callMethod('alert', ['Hello from Dart!']);
+ *
+ * This example shows how to create a [JsObject] from a JavaScript constructor
+ * and access its properties:
+ *
+ *     import 'dart:js';
+ *     
+ *     main() {
+ *       var object = new JsObject(context['Object']);
+ *       object['greeting'] = 'Hello';
+ *       object['greet'] = (name) => "${object['greeting']} $name";
+ *       var message = object.callMethod('greet', ['JavaScript']);
+ *       context['console'].callMethod('log', [message]);
+ *     }
+ *
+ * ## Proxying and Automatic Conversion
+ * 
+ * When setting properties on a JsObject or passing arguments to a Javascript
+ * method or function, Dart objects are automatically converted or proxied to
+ * JavaScript objects. When accessing JavaScript properties, or when a Dart
+ * closure is invoked from JavaScript, the JavaScript objects are also
+ * converted to Dart.
+ *
+ * Functions and closures are proxied in such a way that they are callable. A
+ * Dart closure assigned to a JavaScript property is proxied by a function in
+ * JavaScript. A JavaScript function accessed from Dart is proxied by a
+ * [JsFunction], which has a [apply] method to invoke it.
+ *
+ * The following types are transferred directly and not proxied:
+ *
+ * * "Basic" types: `null`, `bool`, `num`, `String`, `DateTime`
+ * * `Blob`
+ * * `KeyRange`
+ * * `ImageData`
+ * * `TypedData`, including its subclasses like `Int32List`, but _not_
+ *   `ByteBuffer`
+ * * `Node`
+ *
+ * ## Converting collections with JsObject.jsify()
+ *
+ * To create a JavaScript collection from a Dart collection use the
+ * [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
+ * into JavaScript Objects and Arrays.
+ *
+ * The following expression creats a new JavaScript object with the properties
+ * `a` and `b` defined:
+ *
+ *     var jsMap = new JsObject.jsify({'a': 1, 'b': 2});
+ * 
+ * This expression creates a JavaScript array:
+ *
+ *     var jsArray = new JsObject.jsify([1, 2, 3]);
+ */
 library dart.js;
 
 import 'dart:html' show Blob, ImageData, Node;
@@ -33,7 +112,12 @@
   return _convertToJS(Function.apply(callback, dartArgs));
 }
 
-
+/**
+ * Proxies a JavaScript object to Dart.
+ *
+ * The properties of the JavaScript object are accessible via the `[]` and
+ * `[]=` operators. Methods are callable via [callMethod].
+ */
 class JsObject {
   // The wrapped JS object.
   final dynamic _jsObject;
@@ -45,34 +129,9 @@
   }
 
   /**
-   * Expert use only:
-   *
-   * Use this constructor only if you wish to get access to JS properties
-   * attached to a browser host object such as a Node or Blob. This constructor
-   * will return a JsObject proxy on [object], even though the object would
-   * normally be returned as a native Dart object.
-   * 
-   * An exception will be thrown if [object] is a primitive type or null.
+   * Constructs a new JavaScript object from [constructor] and returns a proxy
+   * to it.
    */
-  factory JsObject.fromBrowserObject(Object object) {
-    if (object is num || object is String || object is bool || object == null) {
-      throw new ArgumentError(
-        "object cannot be a num, string, bool, or null");
-    }
-    return new JsObject._fromJs(_convertToJS(object));
-  }
-
-  /**
-   * Converts a json-like [data] to a JavaScript map or array and return a
-   * [JsObject] to it.
-   */
-  factory JsObject.jsify(Object object) {
-    if ((object is! Map) && (object is! Iterable)) {
-      throw new ArgumentError("object must be a Map or Iterable");
-    }
-    return new JsObject._fromJs(_convertDataTree(object));
-  }
-
   factory JsObject(JsFunction constructor, [List arguments]) {
     var constr = _convertToJS(constructor);
     if (arguments == null) {
@@ -95,7 +154,41 @@
     return new JsObject._fromJs(jsObj);
   }
 
-  // TODO: handle cycles
+  /**
+   * Constructs a [JsObject] that proxies a native Dart object; _for expert use
+   * only_.
+   *
+   * Use this constructor only if you wish to get access to JavaScript
+   * properties attached to a browser host object, such as a Node or Blob, that
+   * is normally automatically converted into a native Dart object.
+   * 
+   * An exception will be thrown if [object] either is `null` or has the type
+   * `bool`, `num`, or `String`.
+   */
+  factory JsObject.fromBrowserObject(object) {
+    if (object is num || object is String || object is bool || object == null) {
+      throw new ArgumentError(
+        "object cannot be a num, string, bool, or null");
+    }
+    return new JsObject._fromJs(_convertToJS(object));
+  }
+
+  /**
+   * Recursively converts a JSON-like collection of Dart objects to a
+   * collection of JavaScript objects and returns a [JsObject] proxy to it.
+   *
+   * [object] must be a [Map] or [Iterable], the contents of which are also
+   * converted. Maps and Iterables are copied to a new JavaScript object.
+   * Primitives and other transferrable values are directly converted to their
+   * JavaScript type, and all other objects are proxied.
+   */
+  factory JsObject.jsify(object) {
+    if ((object is! Map) && (object is! Iterable)) {
+      throw new ArgumentError("object must be a Map or Iterable");
+    }
+    return new JsObject._fromJs(_convertDataTree(object));
+  }
+
   static _convertDataTree(data) {
     var _convertedObjects = new HashMap.identity();
 
@@ -124,30 +217,29 @@
   }
 
   /**
-   * Returns the value associated with [key] from the proxied JavaScript
+   * Returns the value associated with [property] from the proxied JavaScript
    * object.
    *
-   * [key] must either be a [String] or [num].
+   * The type of [property] must be either [String] or [num].
    */
-  // TODO(justinfagnani): rename key/name to property
-  dynamic operator[](key) {
-    if (key is! String && key is! num) {
-      throw new ArgumentError("key is not a String or num");
+  dynamic operator[](property) {
+    if (property is! String && property is! num) {
+      throw new ArgumentError("property is not a String or num");
     }
-    return _convertToDart(JS('', '#[#]', _jsObject, key));
+    return _convertToDart(JS('', '#[#]', _jsObject, property));
   }
   
   /**
-   * Sets the value associated with [key] from the proxied JavaScript
+   * Sets the value associated with [property] on the proxied JavaScript
    * object.
    *
-   * [key] must either be a [String] or [num].
+   * The type of [property] must be either [String] or [num].
    */
-  operator[]=(key, value) {
-    if (key is! String && key is! num) {
-      throw new ArgumentError("key is not a String or num");
+  operator[]=(property, value) {
+    if (property is! String && property is! num) {
+      throw new ArgumentError("property is not a String or num");
     }
-    JS('', '#[#]=#', _jsObject, key, _convertToJS(value));
+    JS('', '#[#]=#', _jsObject, property, _convertToJS(value));
   }
 
   int get hashCode => 0;
@@ -155,24 +247,43 @@
   bool operator==(other) => other is JsObject &&
       JS('bool', '# === #', _jsObject, other._jsObject);
 
-  bool hasProperty(name) {
-    if (name is! String && name is! num) {
-      throw new ArgumentError("name is not a String or num");
+  /**
+   * Returns `true` if the JavaScript object contains the specified property
+   * either directly or though its prototype chain.
+   *
+   * This is the equivalent of the `in` operator in JavaScript.
+   */
+  bool hasProperty(property) {
+    if (property is! String && property is! num) {
+      throw new ArgumentError("property is not a String or num");
     }
-    return JS('bool', '# in #', name, _jsObject);
+    return JS('bool', '# in #', property, _jsObject);
   }
 
-  void deleteProperty(name) {
-    if (name is! String && name is! num) {
-      throw new ArgumentError("name is not a String or num");
+  /**
+   * Removes [property] from the JavaScript object.
+   *
+   * This is the equivalent of the `delete` operator in JavaScript.
+   */
+  void deleteProperty(property) {
+    if (property is! String && property is! num) {
+      throw new ArgumentError("property is not a String or num");
     }
-    JS('bool', 'delete #[#]', _jsObject, name);
+    JS('bool', 'delete #[#]', _jsObject, property);
   }
 
-  bool instanceof(type) {
+  /**
+   * Returns `true` if the JavaScript object has [type] in its prototype chain.
+   *
+   * This is the equivalent of the `instanceof` operator in JavaScript.
+   */
+  bool instanceof(JsFunction type) {
     return JS('bool', '# instanceof #', _jsObject, _convertToJS(type));
   }
 
+  /**
+   * Returns the result of the JavaScript objects `toString` method.
+   */
   String toString() {
     try {
       return JS('String', 'String(#)', _jsObject);
@@ -181,16 +292,25 @@
     }
   }
 
-  dynamic callMethod(name, [List args]) {
-    if (name is! String && name is! num) {
-      throw new ArgumentError("name is not a String or num");
+  /**
+   * Calls [method] on the JavaScript object with the arguments [args] and
+   * returns the result.
+   *
+   * The type of [method] must be either [String] or [num].
+   */
+  dynamic callMethod(method, [List args]) {
+    if (method is! String && method is! num) {
+      throw new ArgumentError("method is not a String or num");
     }
-    return _convertToDart(JS('', '#[#].apply(#, #)', _jsObject, name,
+    return _convertToDart(JS('', '#[#].apply(#, #)', _jsObject, method,
         _jsObject,
         args == null ? null : args.map(_convertToJS).toList()));
   }
 }
 
+/**
+ * Proxies a JavaScript Function object.
+ */
 class JsFunction extends JsObject {
 
   /**
@@ -204,6 +324,10 @@
 
   JsFunction._fromJs(jsObject) : super._fromJs(jsObject);
 
+  /**
+   * Invokes the JavaScript function with arguments [args]. If [thisArg] is
+   * supplied it is the value of `this` for the invocation.
+   */
   dynamic apply(List args, { thisArg }) =>
       _convertToDart(JS('', '#.apply(#, #)', _jsObject,
           _convertToJS(thisArg),
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index 5fcb5ce..af3df6c 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -2,6 +2,85 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+/**
+ * Support for interoperating with JavaScript.
+ * 
+ * This library provides access to JavaScript objects from Dart, allowing
+ * Dart code to get and set properties, and call methods of JavaScript objects
+ * and invoke JavaScript functions. The library takes care of converting
+ * between Dart and JavaScript objects where possible, or providing proxies if
+ * conversion isn't possible.
+ *
+ * This library does not yet make Dart objects usable from JavaScript, their
+ * methods and proeprties are not accessible, though it does allow Dart
+ * functions to be passed into and called from JavaScript.
+ *
+ * [JsObject] is the core type and represents a proxy of a JavaScript object.
+ * JsObject gives access to the underlying JavaScript objects properties and
+ * methods. `JsObject`s can be acquired by calls to JavaScript, or they can be
+ * created from proxies to JavaScript constructors.
+ *
+ * The top-level getter [context] provides a [JsObject] that represents the
+ * global object in JavaScript, usually `window`.
+ *
+ * The following example shows an alert dialog via a JavaScript call to the
+ * global function `alert()`:
+ *
+ *     import 'dart:js';
+ *     
+ *     main() => context.callMethod('alert', ['Hello from Dart!']);
+ *
+ * This example shows how to create a [JsObject] from a JavaScript constructor
+ * and access its properties:
+ *
+ *     import 'dart:js';
+ *     
+ *     main() {
+ *       var object = new JsObject(context['Object']);
+ *       object['greeting'] = 'Hello';
+ *       object['greet'] = (name) => "${object['greeting']} $name";
+ *       var message = object.callMethod('greet', ['JavaScript']);
+ *       context['console'].callMethod('log', [message]);
+ *     }
+ *
+ * ## Proxying and Automatic Conversion
+ * 
+ * When setting properties on a JsObject or passing arguments to a Javascript
+ * method or function, Dart objects are automatically converted or proxied to
+ * JavaScript objects. When accessing JavaScript properties, or when a Dart
+ * closure is invoked from JavaScript, the JavaScript objects are also
+ * converted to Dart.
+ *
+ * Functions and closures are proxied in such a way that they are callable. A
+ * Dart closure assigned to a JavaScript property is proxied by a function in
+ * JavaScript. A JavaScript function accessed from Dart is proxied by a
+ * [JsFunction], which has a [apply] method to invoke it.
+ *
+ * The following types are transferred directly and not proxied:
+ *
+ * * "Basic" types: `null`, `bool`, `num`, `String`, `DateTime`
+ * * `Blob`
+ * * `KeyRange`
+ * * `ImageData`
+ * * `TypedData`, including its subclasses like `Int32List`, but _not_
+ *   `ByteBuffer`
+ * * `Node`
+ *
+ * ## Converting collections with JsObject.jsify()
+ *
+ * To create a JavaScript collection from a Dart collection use the
+ * [JsObject.jsify] constructor, which converts Dart [Map]s and [Iterable]s
+ * into JavaScript Objects and Arrays.
+ *
+ * The following expression creats a new JavaScript object with the properties
+ * `a` and `b` defined:
+ *
+ *     var jsMap = new JsObject.jsify({'a': 1, 'b': 2});
+ * 
+ * This expression creates a JavaScript array:
+ *
+ *     var jsArray = new JsObject.jsify([1, 2, 3]);
+ */
 library dart.js;
 
 import 'dart:nativewrappers';
@@ -17,27 +96,35 @@
   return _cachedContext;
 }
 
+/**
+ * Proxies a JavaScript object to Dart.
+ *
+ * The properties of the JavaScript object are accessible via the `[]` and
+ * `[]=` operators. Methods are callable via [callMethod].
+ */
 class JsObject extends NativeFieldWrapperClass2 {
   JsObject.internal();
 
+  /**
+   * Constructs a new JavaScript object from [constructor] and returns a proxy
+   * to it.
+   */
   factory JsObject(JsFunction constructor, [List arguments]) => _create(constructor, arguments);
 
   static JsObject _create(JsFunction constructor, arguments) native "JsObject_constructorCallback";
 
-   /**
-    * Expert users only:
-    * Use this constructor only if you want to gain access to JS expandos
-    * attached to a browser native object such as a Node.
-    * Not all native browser objects can be converted using fromBrowserObject.
-    * Currently the following types are supported:
-    * * Node
-    * * ArrayBuffer
-    * * Blob
-    * * ImageData
-    * * IDBKeyRange
-    * TODO(jacobr): support Event, Window and NodeList as well.
-    */
-  factory JsObject.fromBrowserObject(var object) {
+  /**
+   * Constructs a [JsObject] that proxies a native Dart object; _for expert use
+   * only_.
+   *
+   * Use this constructor only if you wish to get access to JavaScript
+   * properties attached to a browser host object, such as a Node or Blob, that
+   * is normally automatically converted into a native Dart object.
+   * 
+   * An exception will be thrown if [object] either is `null` or has the type
+   * `bool`, `num`, or `String`.
+   */
+  factory JsObject.fromBrowserObject(object) {
     if (object is num || object is String || object is bool || object == null) {
       throw new ArgumentError(
         "object cannot be a num, string, bool, or null");
@@ -46,8 +133,13 @@
   }
 
   /**
-   * Converts a json-like [object] to a JavaScript map or array and return a
-   * [JsObject] to it.
+   * Recursively converts a JSON-like collection of Dart objects to a
+   * collection of JavaScript objects and returns a [JsObject] proxy to it.
+   *
+   * [object] must be a [Map] or [Iterable], the contents of which are also
+   * converted. Maps and Iterables are copied to a new JavaScript object.
+   * Primitives and other transferrable values are directly converted to their
+   * JavaScript type, and all other objects are proxied.
    */
   factory JsObject.jsify(object) {
     if ((object is! Map) && (object is! Iterable)) {
@@ -60,8 +152,21 @@
 
   static JsObject _fromBrowserObject(object) native "JsObject_fromBrowserObject";
 
-  operator[](key) native "JsObject_[]";
-  operator[]=(key, value) native "JsObject_[]=";
+  /**
+   * Returns the value associated with [property] from the proxied JavaScript
+   * object.
+   *
+   * The type of [property] must be either [String] or [num].
+   */
+  operator[](property) native "JsObject_[]";
+
+  /**
+   * Sets the value associated with [property] on the proxied JavaScript
+   * object.
+   *
+   * The type of [property] must be either [String] or [num].
+   */
+  operator[]=(property, value) native "JsObject_[]=";
 
   int get hashCode native "JsObject_hashCode";
 
@@ -69,12 +174,31 @@
 
   static bool _identityEquality(JsObject a, JsObject b) native "JsObject_identityEquality";
 
+  /**
+   * Returns `true` if the JavaScript object contains the specified property
+   * either directly or though its prototype chain.
+   *
+   * This is the equivalent of the `in` operator in JavaScript.
+   */
   bool hasProperty(String property) native "JsObject_hasProperty";
 
-  void deleteProperty(String name) native "JsObject_deleteProperty";
+  /**
+   * Removes [property] from the JavaScript object.
+   *
+   * This is the equivalent of the `delete` operator in JavaScript.
+   */
+  void deleteProperty(String property) native "JsObject_deleteProperty";
 
+  /**
+   * Returns `true` if the JavaScript object has [type] in its prototype chain.
+   *
+   * This is the equivalent of the `instanceof` operator in JavaScript.
+   */
   bool instanceof(JsFunction type) native "JsObject_instanceof";
 
+  /**
+   * Returns the result of the JavaScript objects `toString` method.
+   */
   String toString() {
     try {
       return _toString();
@@ -85,14 +209,20 @@
 
   String _toString() native "JsObject_toString";
 
-  callMethod(String name, [List args]) {
+  /**
+   * Calls [method] on the JavaScript object with the arguments [args] and
+   * returns the result.
+   *
+   * The type of [method] must be either [String] or [num].
+   */
+  callMethod(String method, [List args]) {
     try {
-      return _callMethod(name, args);
+      return _callMethod(method, args);
     } catch(e) {
-      if (hasProperty(name)) {
+      if (hasProperty(method)) {
         rethrow;
       } else {
-        throw new NoSuchMethodError(this, new Symbol(name), args, null);
+        throw new NoSuchMethodError(this, new Symbol(method), args, null);
       }
     }
   }
@@ -100,6 +230,9 @@
   _callMethod(String name, List args) native "JsObject_callMethod";
 }
 
+/**
+ * Proxies a JavaScript Function object.
+ */
 class JsFunction extends JsObject {
   JsFunction.internal();
 
@@ -109,7 +242,11 @@
    */
   factory JsFunction.withThis(Function f) => _withThis(f);
 
-  apply(List args, {thisArg}) native "JsFunction_apply";
+  /**
+   * Invokes the JavaScript function with arguments [args]. If [thisArg] is
+   * supplied it is the value of `this` for the invocation.
+   */
+  dynamic apply(List args, {thisArg}) native "JsFunction_apply";
 
   /**
    * Internal only version of apply which uses debugger proxies of Dart objects
diff --git a/sdk/lib/json/json.dart b/sdk/lib/json/json.dart
deleted file mode 100644
index ba9b7ac..0000000
--- a/sdk/lib/json/json.dart
+++ /dev/null
@@ -1,813 +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.
-
-/**
- * Utilities for encoding and decoding JSON (JavaScript Object Notation) data.
- */
-
-@deprecated
-library dart.json;
-
-import "dart:convert";
-import "dart:_collection-dev" show deprecated;
-import "dart:collection" show HashSet;
-export "dart:convert" show JsonUnsupportedObjectError, JsonCyclicError;
-
-// JSON parsing and serialization.
-
-/**
- * *DEPRECATED* Use `dart:convert JSON.decode` instead.
- *
- * Parses [json] and build the corresponding parsed JSON value.
- *
- * Parsed JSON values are of the types [num], [String], [bool], [Null],
- * [List]s of parsed JSON values or [Map]s from [String] to parsed
- * JSON values.
- *
- * The optional [reviver] function, if provided, is called once for each
- * object or list property parsed. The arguments are the property name
- * ([String]) or list index ([int]), and the value is the parsed value.
- * The return value of the reviver will be used as the value of that property
- * instead the parsed value.
- *
- * Throws [FormatException] if the input is not valid JSON text.
- */
-@deprecated
-parse(String json, [reviver(var key, var value)]) {
-  if (reviver != null) {
-    var original = reviver;
-    reviver = (key, value) => original(key == null ? "" : key, value);
-  }
-  return JSON.decode(json, reviver: reviver);
-}
-
-/**
- * *DEPRECATED* Use `dart:convert JSON.encode` instead.
- *
- * Serializes [object] into a JSON string.
- *
- * Directly serializable values are [num], [String], [bool], and [Null], as well
- * as some [List] and [Map] values.
- * For [List], the elements must all be serializable.
- * For [Map], the keys must be [String] and the values must be serializable.
- *
- * If a value is any other type is attempted serialized, the [toEncodable]
- * method is called with the object as argument, and the result, which must be a
- * directly serializable value, is serialized instead of the original value.
- * If [toEncodable] is omitted, the default is to call `object.toJson()` on the
- * object.
- *
- * If the conversion throws, or returns a value that is not directly
- * serializable, a [JsonUnsupportedObjectError] exception is thrown.
- * If the call throws (including the case where there
- * is no nullary "toJson" method), the error is caught and stored in the
- * [JsonUnsupportedObjectError]'s [:cause:] field.
- *
- * If a [List] or [Map] contains a reference to itself, directly or through
- * other lists or maps, it cannot be serialized and a [JsonCyclicError] is
- * thrown.
- *
- * The objects being serialized should not change during serialization.
- * If an object is serialized more than once, [stringify] is allowed to cache
- * the JSON text for it. I.e., if an object changes after it is first
- * serialized, the new values may or may not be reflected in the result.
- */
-@deprecated
-String stringify(Object object, [toEncodable(object)]) {
-  if (toEncodable == null) toEncodable = _defaultToEncodable;
-  return _JsonStringifier.stringify(object, toEncodable);
-}
-
-/**
- * *DEPRECATED* Use `package:json/json.dart` or `dart:convert` instead.
- *
- * Serializes [object] into [output] stream.
- *
- * Performs the same operations as [stringify] but outputs the resulting
- * string to an existing [StringSink] instead of creating a new [String].
- *
- * If serialization fails by throwing, some data might have been added to
- * [output], but it won't contain valid JSON text.
- */
-@deprecated
-void printOn(Object object, StringSink output, [ toEncodable(object) ]) {
-  if (toEncodable == null) toEncodable = _defaultToEncodable;
-  return _JsonStringifier.printOn(object, output, toEncodable);
-}
-
-//// Implementation ///////////////////////////////////////////////////////////
-
-// Simple API for JSON parsing.
-
-/// *DEPRECATED* Use `package:json/json.dart` instead.
-@deprecated
-abstract class JsonListener {
-  void handleString(String value) {}
-  void handleNumber(num value) {}
-  void handleBool(bool value) {}
-  void handleNull() {}
-  void beginObject() {}
-  void propertyName() {}
-  void propertyValue() {}
-  void endObject() {}
-  void beginArray() {}
-  void arrayElement() {}
-  void endArray() {}
-  /** Called on failure to parse [source]. */
-  void fail(String source, int position, String message) {}
-}
-
-/**
- * *DEPRECATED* Use `package:json/json.dart` instead.
- *
- * A [JsonListener] that builds data objects from the parser events.
- *
- * This is a simple stack-based object builder. It keeps the most recently
- * seen value in a variable, and uses it depending on the following event.
- */
-@deprecated
-class BuildJsonListener extends JsonListener {
-  /**
-   * Stack used to handle nested containers.
-   *
-   * The current container is pushed on the stack when a new one is
-   * started. If the container is a [Map], there is also a current [key]
-   * which is also stored on the stack.
-   */
-  List stack = [];
-  /** The current [Map] or [List] being built. */
-  var currentContainer;
-  /** The most recently read property key. */
-  String key;
-  /** The most recently read value. */
-  var value;
-
-  /** Pushes the currently active container (and key, if a [Map]). */
-  void pushContainer() {
-    if (currentContainer is Map) stack.add(key);
-    stack.add(currentContainer);
-  }
-
-  /** Pops the top container from the [stack], including a key if applicable. */
-  void popContainer() {
-    value = currentContainer;
-    currentContainer = stack.removeLast();
-    if (currentContainer is Map) key = stack.removeLast();
-  }
-
-  void handleString(String value) { this.value = value; }
-  void handleNumber(num value) { this.value = value; }
-  void handleBool(bool value) { this.value = value; }
-  void handleNull() { this.value = null; }
-
-  void beginObject() {
-    pushContainer();
-    currentContainer = {};
-  }
-
-  void propertyName() {
-    key = value;
-    value = null;
-  }
-
-  void propertyValue() {
-    Map map = currentContainer;
-    map[key] = value;
-    key = value = null;
-  }
-
-  void endObject() {
-    popContainer();
-  }
-
-  void beginArray() {
-    pushContainer();
-    currentContainer = [];
-  }
-
-  void arrayElement() {
-    List list = currentContainer;
-    currentContainer.add(value);
-    value = null;
-  }
-
-  void endArray() {
-    popContainer();
-  }
-
-  /** Read out the final result of parsing a JSON string. */
-  get result {
-    assert(currentContainer == null);
-    return value;
-  }
-}
-
-typedef _Reviver(var key, var value);
-
-/// *DEPRECATED* Use `package:json/json.dart` instead.
-@deprecated
-class ReviverJsonListener extends BuildJsonListener {
-  final _Reviver reviver;
-  ReviverJsonListener(reviver(key, value)) : this.reviver = reviver;
-
-  void arrayElement() {
-    List list = currentContainer;
-    value = reviver(list.length, value);
-    super.arrayElement();
-  }
-
-  void propertyValue() {
-    value = reviver(key, value);
-    super.propertyValue();
-  }
-
-  get result {
-    return reviver("", value);
-  }
-}
-
-/// *DEPRECATED* Use `package:json/json.dart` instead.
-@deprecated
-class JsonParser {
-  // A simple non-recursive state-based parser for JSON.
-  //
-  // Literal values accepted in states ARRAY_EMPTY, ARRAY_COMMA, OBJECT_COLON
-  // and strings also in OBJECT_EMPTY, OBJECT_COMMA.
-  //               VALUE  STRING  :  ,  }  ]        Transitions to
-  // EMPTY            X      X                   -> END
-  // ARRAY_EMPTY      X      X             @     -> ARRAY_VALUE / pop
-  // ARRAY_VALUE                     @     @     -> ARRAY_COMMA / pop
-  // ARRAY_COMMA      X      X                   -> ARRAY_VALUE
-  // OBJECT_EMPTY            X          @        -> OBJECT_KEY / pop
-  // OBJECT_KEY                   @              -> OBJECT_COLON
-  // OBJECT_COLON     X      X                   -> OBJECT_VALUE
-  // OBJECT_VALUE                    @  @        -> OBJECT_COMMA / pop
-  // OBJECT_COMMA            X                   -> OBJECT_KEY
-  // END
-  // Starting a new array or object will push the current state. The "pop"
-  // above means restoring this state and then marking it as an ended value.
-  // X means generic handling, @ means special handling for just that
-  // state - that is, values are handled generically, only punctuation
-  // cares about the current state.
-  // Values for states are chosen so bits 0 and 1 tell whether
-  // a string/value is allowed, and setting bits 0 through 2 after a value
-  // gets to the next state (not empty, doesn't allow a value).
-
-  // State building-block constants.
-  static const int INSIDE_ARRAY = 1;
-  static const int INSIDE_OBJECT = 2;
-  static const int AFTER_COLON = 3;  // Always inside object.
-
-  static const int ALLOW_STRING_MASK = 8;  // Allowed if zero.
-  static const int ALLOW_VALUE_MASK = 4;  // Allowed if zero.
-  static const int ALLOW_VALUE = 0;
-  static const int STRING_ONLY = 4;
-  static const int NO_VALUES = 12;
-
-  // Objects and arrays are "empty" until their first property/element.
-  static const int EMPTY = 0;
-  static const int NON_EMPTY = 16;
-  static const int EMPTY_MASK = 16;  // Empty if zero.
-
-
-  static const int VALUE_READ_BITS = NO_VALUES | NON_EMPTY;
-
-  // Actual states.
-  static const int STATE_INITIAL      = EMPTY | ALLOW_VALUE;
-  static const int STATE_END          = NON_EMPTY | NO_VALUES;
-
-  static const int STATE_ARRAY_EMPTY  = INSIDE_ARRAY | EMPTY | ALLOW_VALUE;
-  static const int STATE_ARRAY_VALUE  = INSIDE_ARRAY | NON_EMPTY | NO_VALUES;
-  static const int STATE_ARRAY_COMMA  = INSIDE_ARRAY | NON_EMPTY | ALLOW_VALUE;
-
-  static const int STATE_OBJECT_EMPTY = INSIDE_OBJECT | EMPTY | STRING_ONLY;
-  static const int STATE_OBJECT_KEY   = INSIDE_OBJECT | NON_EMPTY | NO_VALUES;
-  static const int STATE_OBJECT_COLON = AFTER_COLON | NON_EMPTY | ALLOW_VALUE;
-  static const int STATE_OBJECT_VALUE = AFTER_COLON | NON_EMPTY | NO_VALUES;
-  static const int STATE_OBJECT_COMMA = INSIDE_OBJECT | NON_EMPTY | STRING_ONLY;
-
-  // Character code constants.
-  static const int BACKSPACE       = 0x08;
-  static const int TAB             = 0x09;
-  static const int NEWLINE         = 0x0a;
-  static const int CARRIAGE_RETURN = 0x0d;
-  static const int FORM_FEED       = 0x0c;
-  static const int SPACE           = 0x20;
-  static const int QUOTE           = 0x22;
-  static const int PLUS            = 0x2b;
-  static const int COMMA           = 0x2c;
-  static const int MINUS           = 0x2d;
-  static const int DECIMALPOINT    = 0x2e;
-  static const int SLASH           = 0x2f;
-  static const int CHAR_0          = 0x30;
-  static const int CHAR_9          = 0x39;
-  static const int COLON           = 0x3a;
-  static const int CHAR_E          = 0x45;
-  static const int LBRACKET        = 0x5b;
-  static const int BACKSLASH       = 0x5c;
-  static const int RBRACKET        = 0x5d;
-  static const int CHAR_a          = 0x61;
-  static const int CHAR_b          = 0x62;
-  static const int CHAR_e          = 0x65;
-  static const int CHAR_f          = 0x66;
-  static const int CHAR_l          = 0x6c;
-  static const int CHAR_n          = 0x6e;
-  static const int CHAR_r          = 0x72;
-  static const int CHAR_s          = 0x73;
-  static const int CHAR_t          = 0x74;
-  static const int CHAR_u          = 0x75;
-  static const int LBRACE          = 0x7b;
-  static const int RBRACE          = 0x7d;
-
-  final String source;
-  final JsonListener listener;
-  JsonParser(this.source, this.listener);
-
-  /** Parses [source], or throws if it fails. */
-  void parse() {
-    final List<int> states = <int>[];
-    int state = STATE_INITIAL;
-    int position = 0;
-    int length = source.length;
-    while (position < length) {
-      int char = source.codeUnitAt(position);
-      switch (char) {
-        case SPACE:
-        case CARRIAGE_RETURN:
-        case NEWLINE:
-        case TAB:
-          position++;
-          break;
-        case QUOTE:
-          if ((state & ALLOW_STRING_MASK) != 0) fail(position);
-          position = parseString(position + 1);
-          state |= VALUE_READ_BITS;
-          break;
-        case LBRACKET:
-          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
-          listener.beginArray();
-          states.add(state);
-          state = STATE_ARRAY_EMPTY;
-          position++;
-          break;
-        case LBRACE:
-          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
-          listener.beginObject();
-          states.add(state);
-          state = STATE_OBJECT_EMPTY;
-          position++;
-          break;
-        case CHAR_n:
-          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
-          position = parseNull(position);
-          state |= VALUE_READ_BITS;
-          break;
-        case CHAR_f:
-          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
-          position = parseFalse(position);
-          state |= VALUE_READ_BITS;
-          break;
-        case CHAR_t:
-          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
-          position = parseTrue(position);
-          state |= VALUE_READ_BITS;
-          break;
-        case COLON:
-          if (state != STATE_OBJECT_KEY) fail(position);
-          listener.propertyName();
-          state = STATE_OBJECT_COLON;
-          position++;
-          break;
-        case COMMA:
-          if (state == STATE_OBJECT_VALUE) {
-            listener.propertyValue();
-            state = STATE_OBJECT_COMMA;
-            position++;
-          } else if (state == STATE_ARRAY_VALUE) {
-            listener.arrayElement();
-            state = STATE_ARRAY_COMMA;
-            position++;
-          } else {
-            fail(position);
-          }
-          break;
-        case RBRACKET:
-          if (state == STATE_ARRAY_EMPTY) {
-            listener.endArray();
-          } else if (state == STATE_ARRAY_VALUE) {
-            listener.arrayElement();
-            listener.endArray();
-          } else {
-            fail(position);
-          }
-          state = states.removeLast() | VALUE_READ_BITS;
-          position++;
-          break;
-        case RBRACE:
-          if (state == STATE_OBJECT_EMPTY) {
-            listener.endObject();
-          } else if (state == STATE_OBJECT_VALUE) {
-            listener.propertyValue();
-            listener.endObject();
-          } else {
-            fail(position);
-          }
-          state = states.removeLast() | VALUE_READ_BITS;
-          position++;
-          break;
-        default:
-          if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
-          position = parseNumber(char, position);
-          state |= VALUE_READ_BITS;
-          break;
-      }
-    }
-    if (state != STATE_END) fail(position);
-  }
-
-  /**
-   * Parses a "true" literal starting at [position].
-   *
-   * [:source[position]:] must be "t".
-   */
-  int parseTrue(int position) {
-    assert(source.codeUnitAt(position) == CHAR_t);
-    if (source.length < position + 4) fail(position, "Unexpected identifier");
-    if (source.codeUnitAt(position + 1) != CHAR_r ||
-        source.codeUnitAt(position + 2) != CHAR_u ||
-        source.codeUnitAt(position + 3) != CHAR_e) {
-      fail(position);
-    }
-    listener.handleBool(true);
-    return position + 4;
-  }
-
-  /**
-   * Parses a "false" literal starting at [position].
-   *
-   * [:source[position]:] must be "f".
-   */
-  int parseFalse(int position) {
-    assert(source.codeUnitAt(position) == CHAR_f);
-    if (source.length < position + 5) fail(position, "Unexpected identifier");
-    if (source.codeUnitAt(position + 1) != CHAR_a ||
-        source.codeUnitAt(position + 2) != CHAR_l ||
-        source.codeUnitAt(position + 3) != CHAR_s ||
-        source.codeUnitAt(position + 4) != CHAR_e) {
-      fail(position);
-    }
-    listener.handleBool(false);
-    return position + 5;
-  }
-
-  /** Parses a "null" literal starting at [position].
-   *
-   * [:source[position]:] must be "n".
-   */
-  int parseNull(int position) {
-    assert(source.codeUnitAt(position) == CHAR_n);
-    if (source.length < position + 4) fail(position, "Unexpected identifier");
-    if (source.codeUnitAt(position + 1) != CHAR_u ||
-        source.codeUnitAt(position + 2) != CHAR_l ||
-        source.codeUnitAt(position + 3) != CHAR_l) {
-      fail(position);
-    }
-    listener.handleNull();
-    return position + 4;
-  }
-
-  int parseString(int position) {
-    // Format: '"'([^\x00-\x1f\\\"]|'\\'[bfnrt/\\"])*'"'
-    // Initial position is right after first '"'.
-    int start = position;
-    int char;
-    do {
-      if (position == source.length) {
-        fail(start - 1, "Unterminated string");
-      }
-      char = source.codeUnitAt(position);
-      if (char == QUOTE) {
-        String result = source.substring(start, position);
-        listener.handleString(result);
-        return position + 1;
-      }
-      if (char < SPACE) {
-        fail(position, "Control character in string");
-      }
-      position++;
-    } while (char != BACKSLASH);
-    // Backslash escape detected. Collect character codes for rest of string.
-    int firstEscape = position - 1;
-    List<int> chars = <int>[];
-    while (true) {
-      if (position == source.length) {
-        fail(start - 1, "Unterminated string");
-      }
-      char = source.codeUnitAt(position);
-      switch (char) {
-        case CHAR_b: char = BACKSPACE; break;
-        case CHAR_f: char = FORM_FEED; break;
-        case CHAR_n: char = NEWLINE; break;
-        case CHAR_r: char = CARRIAGE_RETURN; break;
-        case CHAR_t: char = TAB; break;
-        case SLASH:
-        case BACKSLASH:
-        case QUOTE:
-          break;
-        case CHAR_u:
-          int hexStart = position - 1;
-          int value = 0;
-          for (int i = 0; i < 4; i++) {
-            position++;
-            if (position == source.length) {
-              fail(start - 1, "Unterminated string");
-            }
-            char = source.codeUnitAt(position);
-            char -= 0x30;
-            if (char < 0) fail(hexStart, "Invalid unicode escape");
-            if (char < 10) {
-              value = value * 16 + char;
-            } else {
-              char = (char | 0x20) - 0x31;
-              if (char < 0 || char > 5) {
-                fail(hexStart, "Invalid unicode escape");
-              }
-              value = value * 16 + char + 10;
-            }
-          }
-          char = value;
-          break;
-        default:
-          if (char < SPACE) fail(position, "Control character in string");
-          fail(position, "Unrecognized string escape");
-      }
-      do {
-        chars.add(char);
-        position++;
-        if (position == source.length) fail(start - 1, "Unterminated string");
-        char = source.codeUnitAt(position);
-        if (char == QUOTE) {
-          String result = new String.fromCharCodes(chars);
-          if (start < firstEscape) {
-            result = "${source.substring(start, firstEscape)}$result";
-          }
-          listener.handleString(result);
-          return position + 1;
-        }
-        if (char < SPACE) {
-          fail(position, "Control character in string");
-        }
-      } while (char != BACKSLASH);
-      position++;
-    }
-  }
-
-  int _handleLiteral(start, position, isDouble) {
-    String literal = source.substring(start, position);
-    // This correctly creates -0 for doubles.
-    num value = (isDouble ? double.parse(literal) : int.parse(literal));
-    listener.handleNumber(value);
-    return position;
-  }
-
-  int parseNumber(int char, int position) {
-    // Format:
-    //  '-'?('0'|[1-9][0-9]*)('.'[0-9]+)?([eE][+-]?[0-9]+)?
-    int start = position;
-    int length = source.length;
-    bool isDouble = false;
-    if (char == MINUS) {
-      position++;
-      if (position == length) fail(position, "Missing expected digit");
-      char = source.codeUnitAt(position);
-    }
-    if (char < CHAR_0 || char > CHAR_9) {
-      fail(position, "Missing expected digit");
-    }
-    if (char == CHAR_0) {
-      position++;
-      if (position == length) return _handleLiteral(start, position, false);
-      char = source.codeUnitAt(position);
-      if (CHAR_0 <= char && char <= CHAR_9) {
-        fail(position);
-      }
-    } else {
-      do {
-        position++;
-        if (position == length) return _handleLiteral(start, position, false);
-        char = source.codeUnitAt(position);
-      } while (CHAR_0 <= char && char <= CHAR_9);
-    }
-    if (char == DECIMALPOINT) {
-      isDouble = true;
-      position++;
-      if (position == length) fail(position, "Missing expected digit");
-      char = source.codeUnitAt(position);
-      if (char < CHAR_0 || char > CHAR_9) fail(position);
-      do {
-        position++;
-        if (position == length) return _handleLiteral(start, position, true);
-        char = source.codeUnitAt(position);
-      } while (CHAR_0 <= char && char <= CHAR_9);
-    }
-    if (char == CHAR_e || char == CHAR_E) {
-      isDouble = true;
-      position++;
-      if (position == length) fail(position, "Missing expected digit");
-      char = source.codeUnitAt(position);
-      if (char == PLUS || char == MINUS) {
-        position++;
-        if (position == length) fail(position, "Missing expected digit");
-        char = source.codeUnitAt(position);
-      }
-      if (char < CHAR_0 || char > CHAR_9) {
-        fail(position, "Missing expected digit");
-      }
-      do {
-        position++;
-        if (position == length) return _handleLiteral(start, position, true);
-        char = source.codeUnitAt(position);
-      } while (CHAR_0 <= char && char <= CHAR_9);
-    }
-    return _handleLiteral(start, position, isDouble);
-  }
-
-  void fail(int position, [String message]) {
-    if (message == null) message = "Unexpected character";
-    listener.fail(source, position, message);
-    // If the listener didn't throw, do it here.
-    String slice;
-    int sliceEnd = position + 20;
-    if (sliceEnd > source.length) {
-      slice = "'${source.substring(position)}'";
-    } else {
-      slice = "'${source.substring(position, sliceEnd)}...'";
-    }
-    throw new FormatException("Unexpected character at $position: $slice");
-  }
-}
-
-Object _defaultToEncodable(object) => object.toJson();
-
-class _JsonStringifier {
-  final Function toEncodable;
-  final StringSink sink;
-  final Set<Object> seen;
-
-  _JsonStringifier(this.sink, this.toEncodable)
-      : this.seen = new HashSet.identity();
-
-  static String stringify(final object, toEncodable(object)) {
-    StringBuffer output = new StringBuffer();
-    _JsonStringifier stringifier = new _JsonStringifier(output, toEncodable);
-    stringifier.stringifyValue(object);
-    return output.toString();
-  }
-
-  static void printOn(final object, StringSink output, toEncodable(object)) {
-    _JsonStringifier stringifier = new _JsonStringifier(output, toEncodable);
-    stringifier.stringifyValue(object);
-  }
-
-  static String numberToString(num x) {
-    return x.toString();
-  }
-
-  // ('0' + x) or ('a' + x - 10)
-  static int hexDigit(int x) => x < 10 ? 48 + x : 87 + x;
-
-  static void escape(StringSink sb, String s) {
-    final int length = s.length;
-    bool needsEscape = false;
-    final charCodes = new List<int>();
-    for (int i = 0; i < length; i++) {
-      int charCode = s.codeUnitAt(i);
-      if (charCode < 32) {
-        needsEscape = true;
-        charCodes.add(JsonParser.BACKSLASH);
-        switch (charCode) {
-        case JsonParser.BACKSPACE:
-          charCodes.add(JsonParser.CHAR_b);
-          break;
-        case JsonParser.TAB:
-          charCodes.add(JsonParser.CHAR_t);
-          break;
-        case JsonParser.NEWLINE:
-          charCodes.add(JsonParser.CHAR_n);
-          break;
-        case JsonParser.FORM_FEED:
-          charCodes.add(JsonParser.CHAR_f);
-          break;
-        case JsonParser.CARRIAGE_RETURN:
-          charCodes.add(JsonParser.CHAR_r);
-          break;
-        default:
-          charCodes.add(JsonParser.CHAR_u);
-          charCodes.add(hexDigit((charCode >> 12) & 0xf));
-          charCodes.add(hexDigit((charCode >> 8) & 0xf));
-          charCodes.add(hexDigit((charCode >> 4) & 0xf));
-          charCodes.add(hexDigit(charCode & 0xf));
-          break;
-        }
-      } else if (charCode == JsonParser.QUOTE ||
-          charCode == JsonParser.BACKSLASH) {
-        needsEscape = true;
-        charCodes.add(JsonParser.BACKSLASH);
-        charCodes.add(charCode);
-      } else {
-        charCodes.add(charCode);
-      }
-    }
-    sb.write(needsEscape ? new String.fromCharCodes(charCodes) : s);
-  }
-
-  void checkCycle(final object) {
-    if (seen.contains(object)) {
-      throw new JsonCyclicError(object);
-    }
-    seen.add(object);
-  }
-
-  void stringifyValue(final object) {
-    // Tries stringifying object directly. If it's not a simple value, List or
-    // Map, call toJson() to get a custom representation and try serializing
-    // that.
-    if (!stringifyJsonValue(object)) {
-      checkCycle(object);
-      try {
-        var customJson = toEncodable(object);
-        if (!stringifyJsonValue(customJson)) {
-          throw new JsonUnsupportedObjectError(object);
-        }
-        seen.remove(object);
-      } catch (e) {
-        throw new JsonUnsupportedObjectError(object, cause: e);
-      }
-    }
-  }
-
-  /**
-   * Serializes a [num], [String], [bool], [Null], [List] or [Map] value.
-   *
-   * Returns true if the value is one of these types, and false if not.
-   * If a value is both a [List] and a [Map], it's serialized as a [List].
-   */
-  bool stringifyJsonValue(final object) {
-    if (object is num) {
-      // TODO: use writeOn.
-      sink.write(numberToString(object));
-      return true;
-    } else if (identical(object, true)) {
-      sink.write('true');
-      return true;
-    } else if (identical(object, false)) {
-      sink.write('false');
-       return true;
-    } else if (object == null) {
-      sink.write('null');
-      return true;
-    } else if (object is String) {
-      sink.write('"');
-      escape(sink, object);
-      sink.write('"');
-      return true;
-    } else if (object is List) {
-      checkCycle(object);
-      List a = object;
-      sink.write('[');
-      if (a.length > 0) {
-        stringifyValue(a[0]);
-        // TODO: switch to Iterables.
-        for (int i = 1; i < a.length; i++) {
-          sink.write(',');
-          stringifyValue(a[i]);
-        }
-      }
-      sink.write(']');
-      seen.remove(object);
-      return true;
-    } else if (object is Map) {
-      checkCycle(object);
-      Map<String, Object> m = object;
-      sink.write('{');
-      bool first = true;
-      m.forEach((String key, Object value) {
-        if (!first) {
-          sink.write(',"');
-        } else {
-          sink.write('"');
-        }
-        escape(sink, key);
-        sink.write('":');
-        stringifyValue(value);
-        first = false;
-      });
-      sink.write('}');
-      seen.remove(object);
-      return true;
-    } else {
-      return false;
-    }
-  }
-}
diff --git a/sdk/lib/json/json_sources.gypi b/sdk/lib/json/json_sources.gypi
deleted file mode 100644
index 407c5de..0000000
--- a/sdk/lib/json/json_sources.gypi
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# This file contains all sources for the dart:json library.
-{
-  'sources': [
-    'json.dart',
-    # The above file needs to be first if additional parts are added to the lib.
-  ],
-}
diff --git a/sdk/lib/math/rectangle.dart b/sdk/lib/math/rectangle.dart
index 763a251..0aa52ff 100644
--- a/sdk/lib/math/rectangle.dart
+++ b/sdk/lib/math/rectangle.dart
@@ -87,7 +87,7 @@
   /**
    * Tests whether `this` entirely contains [another].
    */
-  bool contains(Rectangle<num> another) {
+  bool containsRectangle(Rectangle<num> another) {
     return left <= another.left &&
            left + width >= another.left + another.width &&
            top <= another.top &&
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index eddaa77..109f832 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -676,6 +676,15 @@
   Uri get uri;
 
   /**
+   * Returns an immutable map of the declarations actually given in the library.
+   * 
+   * This map includes all regular methods, getters, setters, fields, classes
+   * and typedefs actually declared in the library. The map is keyed by the
+   * simple names of the declarations.
+   */
+  Map<Symbol, DeclarationMirror> get declarations;
+
+  /**
    * An immutable map from from names to mirrors for all members in
    * this library.
    *
@@ -732,7 +741,7 @@
    * are
    * the same library in the same isolate.
    */
-   bool operator == (other);
+   bool operator ==(other);
 }
 
 /**
@@ -751,6 +760,43 @@
    * This list preserves the order of declaration of the type variables.
    */
   List<TypeVariableMirror> get typeVariables;
+
+  /**
+   * An immutable list with mirrors for all type arguments for
+   * this type.
+   *
+   * If the reflectee is an invocation of a generic class,
+   * the type arguments are the bindings of its type parameters.
+   * If the reflectee is the original declaration of a generic,
+   * it has no type arguments and this method returns an empty list.
+   * If the reflectee is not generic, then
+   * it has no type arguments and this method returns an empty list.
+   *
+   * This list preserves the order of declaration of the type variables.
+   */
+  List<TypeMirror> get typeArguments;
+
+  /**
+   * Is this the original declaration of this type?
+   *
+   * For most classes, they are their own original declaration.  For
+   * generic classes, however, there is a distinction between the
+   * original class declaration, which has unbound type variables, and
+   * the instantiations of generic classes, which have bound type
+   * variables.
+   */
+  bool get isOriginalDeclaration;
+
+  /**
+   * A mirror on the original declaration of this type.
+   *
+   * For most classes, they are their own original declaration.  For
+   * generic classes, however, there is a distinction between the
+   * original class declaration, which has unbound type variables, and
+   * the instantiations of generic classes, which have bound type
+   * variables.
+   */
+  TypeMirror get originalDeclaration;
 }
 
 /**
@@ -781,6 +827,17 @@
    */
   List<ClassMirror> get superinterfaces;
 
+  /** 
+   * Returns an immutable map of the declarations actually given in the class
+   * declaration.
+   *
+   * This map includes all regular methods, getters, setters, fields,
+   * constructors and type variables actually declared in the class. Both
+   * static and instance members are included, but no inherited members are
+   * included. The map is keyed by the simple names of the declarations.
+   */
+  Map<Symbol, DeclarationMirror> get declarations;
+
   /**
    * The mixin of this class.
    * If this class is the result of a mixin application of the
@@ -832,43 +889,6 @@
    */
   Map<Symbol, MethodMirror> get constructors;
 
-  /**
-   * An immutable list with mirrors for all type arguments for
-   * this type.
-   *
-   * If the reflectee is an invocation of a generic class,
-   * the type arguments are the bindings of its type parameters.
-   * If the reflectee is the original declaration of a generic,
-   * it has no type arguments and this method returns an empty list.
-   * If the reflectee is not generic, then
-   * it has no type arguments and this method returns an empty list.
-   *
-   * This list preserves the order of declaration of the type variables.
-   */
-  List<TypeMirror> get typeArguments;
-
-  /**
-   * Is this the original declaration of this type?
-   *
-   * For most classes, they are their own original declaration.  For
-   * generic classes, however, there is a distinction between the
-   * original class declaration, which has unbound type variables, and
-   * the instantiations of generic classes, which have bound type
-   * variables.
-   */
-  bool get isOriginalDeclaration;
-
-  /**
-   * A mirror on the original declaration of this type.
-   *
-   * For most classes, they are their own original declaration.  For
-   * generic classes, however, there is a distinction between the
-   * original class declaration, which has unbound type variables, and
-   * the instantiations of generic classes, which have bound type
-   * variables.
-   */
-  ClassMirror get originalDeclaration;
-
    /**
    * Invokes the named constructor and returns a mirror on the result.
    *
diff --git a/sdk/lib/platform/platform.dart b/sdk/lib/platform/platform.dart
new file mode 100644
index 0000000..ee8658e
--- /dev/null
+++ b/sdk/lib/platform/platform.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Runtime information about the current platform.
+ */
+library dart.platform;
+
+/**
+ * The number of processors of the platform.
+ *
+ * Returns null if no information is available.
+ *
+ * Supported on the standalone Dart executable.
+ */
+external int get numberOfProcessors;
+
+/**
+ * The path separator used on the platform to separate
+ * components in file paths.
+ *
+ * Returns null if the path separator is unknown or not valid.
+ *
+ * Supported on the standalone Dart executable and on dart2js.
+ */
+external String get pathSeparator;
+
+/**
+ * A string (`linux`, `macos`, `windows` or `android`)
+ * representing the operating system.
+ *
+ * Returns null if the operating system could not be determined.
+ */
+external String get operatingSystem;
+
+/**
+ * The local hostname for the system.
+ *
+ * Returns null if the local hostname is not available.
+ *
+ * Supported on the standalone Dart executable.
+ */
+external String get localHostname;
+
+/**
+ * The version of the current Dart runtime.
+ *
+ * Returns null if not running a Dart runtime.
+ *
+ * Supported on the standalone Dart executable.
+ */
+external String get version;
+
+/**
+ * The environment for this instance of the platform.
+ *
+ * If environment variables are not supported on this platform, or not
+ * available, null is returned.
+ *
+ * Environment variables on Windows are case-insensitive. The map
+ * returned on Windows is therefore case-insensitive and converts
+ * all keys and key arguments to its methods to upper case.
+ * On other platforms the returned map is
+ * a standard case-sensitive map.
+ *
+ * Supported on the standalone Dart executable.
+ */
+external Map<String, String> get environment;
+
+/**
+ * The path of the executable this Dart isolate is running on.
+ *
+ * Returns null if the execution environment does not make the information
+ * available.
+ *
+ * Supported on the standalone Dart executable.
+ */
+external String get executable;
+
+/**
+ * The URI of the script being run in this isolate.
+ *
+ * If the URI is relative it is relative to the file URI of
+ * the working directory of the VM when it was started.
+ *
+ * Returns null if the executable environment does not make the information
+ * available.
+ *
+ * Supported on the standalone Dart executable.
+ */
+external Uri get script;
+
+/**
+ * The flags passed to the executable used to run the script in this
+ * isolate. These are the command-line flags between the executable name
+ * and the script name.
+ *
+ * Returns the empty list if [executableArguments] is not supported.
+ *
+ * Supported on the standalone Dart executable.
+ */
+external List<String> get executableArguments;
+
+/**
+ * The value of the --package-root flag passed to the executable
+ * used to run the script in this isolate.  This is the directory in which
+ * Dart packages are looked up.
+ *
+ * If there is no --package-root flag, then the empty string is returned.
+ *
+ * Returns null if the information is not available on this platform.
+ *
+ * Supported on the standalone Dart executable.
+ */
+external String get packageRoot;
diff --git a/sdk/lib/platform/platform_sources.gypi b/sdk/lib/platform/platform_sources.gypi
new file mode 100644
index 0000000..6bca2b3
--- /dev/null
+++ b/sdk/lib/platform/platform_sources.gypi
@@ -0,0 +1,11 @@
+# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# This file contains all sources for the dart:platform library.
+{
+  'sources': [
+    'platform.dart',
+    # The above file needs to be first as it lists the parts below.
+  ],
+}
diff --git a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
index 14e3fee..4416a72 100644
--- a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
+++ b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
@@ -480,6 +480,28 @@
 
 
 @DocsEditable()
+/**
+ * The properties of a WebGL rendering context.
+ *
+ * If [alpha] is `true`, then the context has an alpha channel.
+ *
+ * If [antialias] is `true`, then antialiasing is performed by the browser, but
+ * only if the browser's implementation of WebGL supports antialiasing.
+ *
+ * If [depth] is `true`, then the context has a depth buffer of at least 16
+ * bits.
+ *
+ * If [premultipliedAlpha] is `true`, then the context's colors are assumed to
+ * be premultiplied. This means that color values are assumed to have  been
+ * multiplied by their alpha values. If [alpha] is `false`, then this flag is
+ * ignored.
+ *
+ * If [preserveDrawingBuffer] is `false`, then all contents of the context are
+ * cleared. If `true`, then all values will remain until changed or cleared.
+ *
+ * If [stencil] is `true`, then the context has a stencil buffer of at least 8
+ * bits.
+ */
 @DomName('WebGLContextAttributes')
 @Unstable()
 class ContextAttributes extends Interceptor native "WebGLContextAttributes" {
@@ -2456,7 +2478,15 @@
 
   @DomName('WebGLRenderingContext.getContextAttributes')
   @DocsEditable()
-  ContextAttributes getContextAttributes() native;
+  @Creates('ContextAttributes|=Object')
+  ContextAttributes getContextAttributes() {
+    return convertNativeToDart_ContextAttributes(_getContextAttributes_1());
+  }
+  @JSName('getContextAttributes')
+  @DomName('WebGLRenderingContext.getContextAttributes')
+  @DocsEditable()
+  @Creates('ContextAttributes|=Object')
+  _getContextAttributes_1() native;
 
   @DomName('WebGLRenderingContext.getError')
   @DocsEditable()
diff --git a/sdk/lib/web_gl/dartium/web_gl_dartium.dart b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
index e09051c..a3c4286 100644
--- a/sdk/lib/web_gl/dartium/web_gl_dartium.dart
+++ b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
@@ -492,6 +492,28 @@
 
 
 @DocsEditable()
+/**
+ * The properties of a WebGL rendering context.
+ *
+ * If [alpha] is `true`, then the context has an alpha channel.
+ *
+ * If [antialias] is `true`, then antialiasing is performed by the browser, but
+ * only if the browser's implementation of WebGL supports antialiasing.
+ *
+ * If [depth] is `true`, then the context has a depth buffer of at least 16
+ * bits.
+ *
+ * If [premultipliedAlpha] is `true`, then the context's colors are assumed to
+ * be premultiplied. This means that color values are assumed to have  been
+ * multiplied by their alpha values. If [alpha] is `false`, then this flag is
+ * ignored.
+ *
+ * If [preserveDrawingBuffer] is `false`, then all contents of the context are
+ * cleared. If `true`, then all values will remain until changed or cleared.
+ *
+ * If [stencil] is `true`, then the context has a stencil buffer of at least 8
+ * bits.
+ */
 @DomName('WebGLContextAttributes')
 @Unstable()
 class ContextAttributes extends NativeFieldWrapperClass2 {
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
index 4b8925e..426e16e 100644
--- a/tests/co19/co19-analyzer.status
+++ b/tests/co19/co19-analyzer.status
@@ -48,7 +48,6 @@
 Language/12_Expressions/12_Instance_Creation/1_New_A01_t04: fail, OK
 
 # co19 issue #528, Const: wrong number of type arguments
-Language/12_Expressions/12_Instance_Creation_A01_t02: fail, OK
 Language/12_Expressions/12_Instance_Creation_A01_t05: fail, OK
 Language/12_Expressions/12_Instance_Creation_A01_t06: fail, OK
 
@@ -142,15 +141,86 @@
 LibTest/async/EventTransformStream/transform_A01_t01: Fail
 LibTest/async/EventTransformStream/where_A01_t01: Fail
 LibTest/async/EventTransformStream/where_A01_t02: Fail
-LibTest/async/Stream/asBroadcastStream_A02_t01: Fail
-LibTest/async/Stream/transform_A01_t01: Fail
 LibTest/async/StreamEventTransformer/bind_A01_t01: Fail
 LibTest/async/StreamEventTransformer/handleData_A01_t01: Fail
 LibTest/async/StreamEventTransformer/handleDone_A01_t01: Fail
 LibTest/async/StreamEventTransformer/handleError_A01_t01: Fail
 
+# co19 issue 639.
+Language/12_Expressions/12_Spawning_an_Isolate_A01_t01: Fail
+LibTest/isolate/IsolateSink/add_A01_t01: Fail
+LibTest/isolate/IsolateSink/add_A01_t02: Fail
+LibTest/isolate/IsolateSink/add_A02_t01: Fail
+LibTest/isolate/IsolateSink/close_A01_t01: Fail
+LibTest/isolate/IsolateSink/close_A01_t02: Fail
+LibTest/isolate/IsolateSink/close_A01_t03: Fail
+LibTest/isolate/IsolateSink/close_A01_t04: Fail
+LibTest/isolate/IsolateSink/operator_equality_A01_t01: Fail
+LibTest/isolate/IsolateStream/any_A01_t01: Fail
+LibTest/isolate/IsolateStream/asBroadcastStream_A01_t01: Fail
+LibTest/isolate/IsolateStream/contains_A01_t01: Fail
+LibTest/isolate/IsolateStream/first_A01_t01: Fail
+LibTest/isolate/IsolateStream/first_A02_t01: Fail
+LibTest/isolate/IsolateStream/first_A02_t02: Fail
+LibTest/isolate/IsolateStream/isBroadcast_A01_t01: Fail
+LibTest/isolate/IsolateStream/isBroadcast_A01_t02: Fail
+LibTest/isolate/IsolateStream/isEmpty_A01_t01: Fail
+LibTest/isolate/IsolateStream/last_A01_t01: Fail
+LibTest/isolate/IsolateStream/last_A02_t01: Fail
+LibTest/isolate/IsolateStream/length_A01_t01: Fail
+LibTest/isolate/IsolateStream/single_A01_t01: Fail
+LibTest/isolate/IsolateStream/single_A02_t01: Fail
+LibTest/isolate/ReceivePort/close_A01_t01: Fail
+LibTest/isolate/ReceivePort/close_A02_t01: Fail
+LibTest/isolate/ReceivePort/receive_A01_t01: Fail
+LibTest/isolate/ReceivePort/receive_A01_t03: Fail
+LibTest/isolate/ReceivePort/toSendPort_A01_t01: Fail
+LibTest/isolate/ReceivePort/toSendPort_A01_t03: Fail
+LibTest/isolate/SendPort/call_A01_t01: Fail
+LibTest/isolate/SendPort/hashCode_A01_t01: Fail
+LibTest/isolate/SendPort/operator_equality_A01_t01: Fail
+LibTest/isolate/SendPort/send_A01_t01: Pass
+LibTest/isolate/SendPort/send_A02_t01: Fail
+LibTest/isolate/SendPort/send_A02_t04: Fail
+LibTest/isolate/SendPort/send_A02_t05: Fail
+LibTest/isolate/SendPort/send_A02_t06: Fail
+LibTest/isolate/SendPort/send_A03_t01: Fail
+LibTest/isolate/SendPort/send_A03_t02: Fail
+LibTest/isolate/isolate_api/spawnFunction_A01_t01: Fail
+LibTest/isolate/isolate_api/spawnFunction_A01_t02: Fail
+LibTest/isolate/isolate_api/spawnFunction_A01_t03: Fail
+LibTest/isolate/isolate_api/spawnFunction_A01_t04: Fail
+LibTest/isolate/isolate_api/spawnFunction_A01_t05: Fail
+LibTest/isolate/isolate_api/spawnFunction_A02_t01: Fail
+LibTest/isolate/isolate_api/spawnFunction_A03_t01: Fail
+LibTest/isolate/isolate_api/spawnFunction_A04_t02: Fail
+LibTest/isolate/isolate_api/spawnFunction_A04_t03: Fail
+LibTest/isolate/isolate_api/spawnUri_A01_t01: Fail
+LibTest/isolate/isolate_api/spawnUri_A01_t02: Fail
+LibTest/isolate/isolate_api/spawnUri_A01_t03: Fail
+LibTest/isolate/isolate_api/spawnUri_A01_t04: Fail
+LibTest/isolate/isolate_api/spawnUri_A01_t05: Fail
+LibTest/isolate/isolate_api/streamSpawnFunction_A01_t01: Fail
+LibTest/isolate/isolate_api/stream_A01_t01: Fail
+LibTest/isolate/isolate_api/port_A01_t01: Fail
+LibTest/isolate/IsolateSink/addError_A01_t01: Fail
+LibTest/isolate/IsolateSink/addError_A01_t02: Fail
+LibTest/isolate/IsolateStream/any_A02_t01: Fail
+LibTest/isolate/IsolateStream/contains_A02_t01: Fail
+LibTest/isolate/ReceivePort/receive_A01_t02: Fail
+LibTest/isolate/ReceivePort/toSendPort_A01_t02: Fail
+LibTest/isolate/SendPort/send_A01_t01: Fail
+LibTest/isolate/SendPort/send_A02_t02: Fail
+LibTest/isolate/SendPort/send_A02_t03: Fail
+LibTest/isolate/isolate_api/spawnFunction_A02_t02: Fail
+LibTest/isolate/isolate_api/spawnFunction_A04_t01: Fail
+LibTest/isolate/isolate_api/spawnUri_A02_t01: Fail
+LibTest/isolate/isolate_api/spawnUri_A02_t02: Fail
+LibTest/isolate/isolate_api/spawnUri_A02_t03: Fail
+LibTest/isolate/isolate_api/streamSpawnFunction_A02_t01: Fail
+LibTest/isolate/isolate_api/streamSpawnFunction_A02_t02: Fail
+
 #co19 issue 631
-Language/05_Variables/05_Variables_A11_t01: Fail
 Language/12_Expressions/30_Identifier_Reference_A02_t01: Fail
 Language/13_Statements/03_Variable_Declaration_A01_t09: Fail
 Language/13_Statements/03_Variable_Declaration_A01_t16: Fail
@@ -162,3 +232,10 @@
 LibTest/collection/ListQueue/ListQueue_class_A01_t01: Fail # co19-roll r623: Please triage this failure
 LibTest/collection/Queue/Queue_class_A01_t01: Fail # co19-roll r623: Please triage this failure
 LibTest/core/Iterable/Iterable.generate_A01_t01: Fail # co19-roll r623: Please triage this failure
+
+Language/13_Statements/04_Local_Function_Declaration_A04_t02: Fail # co19-roll r641: Please triage this failure
+LibTest/collection/HashMap/allTests_A01_t01: Fail # co19-roll r641: Please triage this failure
+LibTest/collection/LinkedHashMap/LinkedHashMap_class_A01_t01: Fail # co19-roll r641: Please triage this failure
+LibTest/collection/LinkedHashMap/allTests_A01_t01: Fail # co19-roll r641: Please triage this failure
+LibTest/collection/SplayTreeMap/allTests_A01_t01: Fail # co19-roll r641: Please triage this failure
+LibTest/core/Map/allTests_A01_t01: Fail # co19-roll r641: Please triage this failure
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 3ca6991..4a4cb2a 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -12,17 +12,9 @@
 # TBF: infinite look: class A {const A();final m = const A();}
 Language/12_Expressions/01_Constants_A17_t03: fail
 
-# analyzer issue https://code.google.com/p/dart/issues/detail?id=11534
-Language/15_Types/4_Interface_Types_A11_t01: Skip
-Language/15_Types/4_Interface_Types_A11_t02: Skip
-
 # TBF: malformed or malbounded type in "conts" is static warning
 Language/12_Expressions/12_Instance_Creation_A01_t08: Fail
 
-# TBF: typedef self reference
-Language/15_Types/3_Type_Declarations/1_Typedef_A07_t08: Fail
-Language/15_Types/3_Type_Declarations/1_Typedef_A07_t09: Fail
-
 
 
 # co19 issue #442, undefined name "Expect"
@@ -56,7 +48,6 @@
 Language/12_Expressions/12_Instance_Creation/1_New_A01_t04: fail, OK
 
 # co19 issue #528, Const: wrong number of type arguments
-Language/12_Expressions/12_Instance_Creation_A01_t02: fail, OK
 Language/12_Expressions/12_Instance_Creation_A01_t05: fail, OK
 Language/12_Expressions/12_Instance_Creation_A01_t06: fail, OK
 
@@ -150,19 +141,27 @@
 LibTest/async/EventTransformStream/transform_A01_t01: Fail
 LibTest/async/EventTransformStream/where_A01_t01: Fail
 LibTest/async/EventTransformStream/where_A01_t02: Fail
-LibTest/async/Stream/asBroadcastStream_A02_t01: Fail
-LibTest/async/Stream/transform_A01_t01: Fail
 LibTest/async/StreamEventTransformer/bind_A01_t01: Fail
 LibTest/async/StreamEventTransformer/handleData_A01_t01: Fail
 LibTest/async/StreamEventTransformer/handleDone_A01_t01: Fail
 LibTest/async/StreamEventTransformer/handleError_A01_t01: Fail
 
+#co19 issue 631
+Language/12_Expressions/30_Identifier_Reference_A02_t01: Fail
+Language/13_Statements/03_Variable_Declaration_A01_t09: Fail
+Language/13_Statements/03_Variable_Declaration_A01_t16: Fail
+
 Language/13_Statements/09_Switch_A02_t04: Fail  # Issue 629
 
-Language/07_Classes/6_Constructors/2_Factories_A14_t01: Fail # co19-roll r623: Please triage this failure
-Language/07_Classes/6_Constructors/2_Factories_A14_t02: Fail # co19-roll r623: Please triage this failure
 Language/12_Expressions/05_Strings_A20_t01: Fail # co19-roll r623: Please triage this failure
 LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue_class_A01_t01: Fail # co19-roll r623: Please triage this failure
 LibTest/collection/ListQueue/ListQueue_class_A01_t01: Fail # co19-roll r623: Please triage this failure
 LibTest/collection/Queue/Queue_class_A01_t01: Fail # co19-roll r623: Please triage this failure
 LibTest/core/Iterable/Iterable.generate_A01_t01: Fail # co19-roll r623: Please triage this failure
+
+Language/13_Statements/04_Local_Function_Declaration_A04_t02: Fail # co19-roll r641: Please triage this failure
+LibTest/collection/HashMap/allTests_A01_t01: Fail # co19-roll r641: Please triage this failure
+LibTest/collection/LinkedHashMap/LinkedHashMap_class_A01_t01: Fail # co19-roll r641: Please triage this failure
+LibTest/collection/LinkedHashMap/allTests_A01_t01: Fail # co19-roll r641: Please triage this failure
+LibTest/collection/SplayTreeMap/allTests_A01_t01: Fail # co19-roll r641: Please triage this failure
+LibTest/core/Map/allTests_A01_t01: Fail # co19-roll r641: Please triage this failure
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index be9a01b..09b02e0 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -8,8 +8,57 @@
 
 ### GENERAL FAILURES ###
 
+[ $runtime == vm || $runtime != vm ]
+# Tests that fail everywhere, including the analyzer.
+LibTest/core/Match/str_A01_t01: Fail, OK # Issue 635
+LibTest/core/RegExp/allMatches_A01_t01: Fail, OK # Issue 635
+LibTest/core/RegExp/firstMatch_A01_t01: Fail, OK # Issue 635
 
-[ $runtime == vm || $compiler == dart2dart || $compiler == dart2js ]
+LibTest/StreamTransformer/StreamTransformer.fromHandlers_A01_t01: Fail, CompileTimeError # co19-roll r641: Please triage this failure
+LibTest/StreamTransformer/StreamTransformer.fromHandlers_A01_t02: Fail, CompileTimeError # co19-roll r641: Please triage this failure
+LibTest/StreamTransformer/StreamTransformer.fromHandlers_A01_t03: Fail, CompileTimeError # co19-roll r641: Please triage this failure
+LibTest/StreamTransformer/StreamTransformer.fromHandlers_A01_t04: Fail, CompileTimeError # co19-roll r641: Please triage this failure
+LibTest/StreamTransformer/StreamTransformer_A01_t02: Fail, CompileTimeError # co19-roll r641: Please triage this failure
+LibTest/StreamTransformer/StreamTransformer_A01_t03: Fail, CompileTimeError # co19-roll r641: Please triage this failure
+LibTest/StreamTransformer/StreamTransformer_A02_t01: Fail, CompileTimeError # co19-roll r641: Please triage this failure
+LibTest/StreamTransformer/StreamTransformer_A02_t02: Fail, CompileTimeError # co19-roll r641: Please triage this failure
+LibTest/StreamTransformer/StreamTransformer_A03_t01: Fail, CompileTimeError # co19-roll r641: Please triage this failure
+LibTest/StreamTransformer/StreamTransformer_A03_t02: Fail, CompileTimeError # co19-roll r641: Please triage this failure
+LibTest/StreamTransformer/bind_A01_t01: Fail # co19-roll r641: Please triage this failure
+
+LibTest/json/BuildJsonListener/BuildJsonListener_A01_t01: Fail, OK # Issue 637
+LibTest/json/JsonParser/JsonParser_A01_t01: Fail, OK # Issue 637
+LibTest/json/JsonParser/constants_A01_t01: Fail, OK # Issue 637
+LibTest/json/JsonParser/fail_A01_t01: Fail, OK # Issue 637
+LibTest/json/JsonParser/parseFalse_A01_t01: Fail, OK # Issue 637
+LibTest/json/JsonParser/parseNull_A01_t01: Fail, OK # Issue 637
+LibTest/json/JsonParser/parseNumber_A01_t01: Fail, OK # Issue 637
+LibTest/json/JsonParser/parseString_A01_t01: Fail, OK # Issue 637
+LibTest/json/JsonParser/parseTrue_A01_t01: Fail, OK # Issue 637
+LibTest/json/JsonParser/parse_A01_t01: Fail, OK # Issue 637
+LibTest/json/JsonParser/properties_A01_t01: Fail, OK # Issue 637
+LibTest/json/ReviverJsonListener/ReviverJsonListener_A01_t01: Fail, OK # Issue 637
+LibTest/json/parse_A01_t01: Fail, OK # Issue 637
+LibTest/json/parse_A02_t01: Fail, OK # Issue 637
+LibTest/json/parse_A03_t01: Fail, OK # Issue 637
+LibTest/json/printOn_A01_t01: Fail, OK # Issue 637
+LibTest/json/printOn_A02_t01: Fail, OK # Issue 637
+LibTest/json/printOn_A03_t01: Fail, OK # Issue 637
+LibTest/json/printOn_A03_t02: Fail, OK # Issue 637
+LibTest/json/printOn_A03_t03: Fail, OK # Issue 637
+LibTest/json/printOn_A04_t01: Fail, OK # Issue 637
+LibTest/json/stringify_A01_t01: Fail, OK # Issue 637
+LibTest/json/stringify_A02_t01: Fail, OK # Issue 637
+LibTest/json/stringify_A03_t01: Fail, OK # Issue 637
+LibTest/json/stringify_A03_t02: Fail, OK # Issue 637
+LibTest/json/stringify_A03_t03: Fail, OK # Issue 637
+LibTest/json/stringify_A04_t01: Fail, OK # Issue 637
+
+[ $runtime == vm || $runtime == dartium || $compiler == dart2dart || $compiler == dart2js ]
+Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t04: fail, pass, ok # co19 issue 634
+Language/12_Expressions/12_Instance_Creation/2_Const_A09_t02: fail, pass, ok # co19 issue 634
+Language/12_Expressions/12_Instance_Creation/2_Const_A09_t03: fail, pass, ok # co19 issue 634
+
 Language/05_Variables/05_Variables_A06_t01: fail, pass, ok # co19 issue 624
 Language/05_Variables/05_Variables_A06_t02: fail, pass, ok # co19 issue 624
 Language/05_Variables/05_Variables_A06_t03: fail, pass, ok # co19 issue 624
@@ -18,42 +67,42 @@
 Language/05_Variables/05_Variables_A06_t06: fail, pass, ok # co19 issue 624
 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/toFilePath_A01_t01: pass, fail, ok # co19 Issue 592
+Language/05_Variables/05_Variables_A11_t01: Fail, MissingCompileTimeError # co19-roll r641: Please triage this failure
+
 # 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/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/04_Local_Function_Declaration_A04_t01: Fail, MissingCompileTimeError # co19-roll r607: Please triage this failure
 LibTest/collection/LinkedList/forEach_A02_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
 
-Language/07_Classes/07_Classes_A13_t01: Pass, MissingCompileTimeError # co19-roll r623: Please triage this failure
-Language/07_Classes/07_Classes_A13_t04: Pass, MissingCompileTimeError # co19-roll r623: Please triage this failure
-Language/07_Classes/07_Classes_A13_t07: Pass, MissingCompileTimeError # co19-roll r623: Please triage this failure
-Language/07_Classes/6_Constructors/2_Factories_A14_t01: MissingCompileTimeError # co19-roll r623: Please triage this failure
-Language/07_Classes/6_Constructors/2_Factories_A14_t02: MissingCompileTimeError # co19-roll r623: Please triage this failure
+Language/07_Classes/07_Classes_A13_t01: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
+Language/07_Classes/07_Classes_A13_t04: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
+Language/07_Classes/07_Classes_A13_t07: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
 LibTest/collection/HashSet/HashSet_class_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
 LibTest/collection/IterableBase/IterableBase_class_A01_t02: RuntimeError # co19-roll r623: Please triage this failure
 LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
 LibTest/core/Set/IterableBase_A01_t01: RuntimeError # co19-roll r623: 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
-LibTest/core/List/removeAt_A02_t01: RuntimeError # co19-roll r623: Please triage this failure
 
-[ $runtime == vm || $compiler == dart2js ]
-Language/07_Classes/6_Constructors_A02_t01: SKIP # co19 issue 415.
-Language/14_Libraries_and_Scripts/1_Imports_A03_t65: PASS, FAIL, OK # co19 issue 560
+LibTest/core/Uri/toFilePath_A01_t01: pass, fail, ok # co19 Issue 592
 
+LibTest/async/Stream/handleError_A04_t02: Fail # co19-roll r641: Please triage this failure
+LibTest/async/Stream/listen_A05_t02: Fail # co19-roll r641: Please triage this failure
+LibTest/async/StreamSink/addError_A01_t01: Fail # co19-roll r641: Please triage this failure
+LibTest/async/StreamSink/addStream_A01_t01: Timeout, Fail # co19-roll r641: Please triage this failure
+LibTest/async/StreamSink/addStream_A01_t02: Timeout, Fail # co19-roll r641: Please triage this failure
+LibTest/collection/ListBase/ListBase_class_A01_t01: Fail, Timeout # co19-roll r641: Please triage this failure
+LibTest/collection/ListMixin/ListMixin_class_A01_t01: Fail, Timeout # co19-roll r641: Please triage this failure
+
+
+[ $runtime == vm || $runtime == dartium || $compiler == dart2js ]
 LibTest/math/acos_A01_t01: PASS, FAIL, OK # co19 issue 44
 LibTest/math/asin_A01_t01: PASS, FAIL, OK # co19 issue 44
 LibTest/math/atan_A01_t01: PASS, FAIL, OK # co19 issue 44
-LibTest/math/cos_A01_t01: PASS, FAIL, OK # co19 issue 44
-LibTest/math/exp_A01_t01: PASS, FAIL, OK # co19 issue 44
-LibTest/math/sin_A01_t01: PASS, FAIL, OK # co19 issue 44
-LibTest/math/tan_A01_t01: PASS, FAIL, OK  # co19 issue 44
 
 LibTest/core/double/ceil_A01_t03: FAIL, OK # co19 issue 389
 LibTest/core/double/ceil_A01_t04: FAIL, OK # co19 issue 389
@@ -63,6 +112,23 @@
 LibTest/core/double/round_A01_t04: FAIL, OK # co19 issue 389
 
 LibTest/async/Stream/Stream.periodic_A01_t01: TIMEOUT, PASS, FAIL, OK # co19 issue 538
+
+LibTest/isolate/SendPort/send_A02_t02: SKIP # co19 issue 493
+LibTest/isolate/SendPort/send_A02_t03: SKIP # co19 issue 495
+LibTest/isolate/isolate_api/streamSpawnFunction_A02_t02: PASS, FAIL, TIMEOUT, OK # co19 issue 540
+
+LibTest/typed_data/Int8List/Int8List.fromList_A01_t02: Fail # co19-roll r559: Please triage this failure
+
+
+[ $runtime == vm || $compiler == dart2js ]
+Language/07_Classes/6_Constructors_A02_t01: SKIP # co19 issue 415.
+Language/14_Libraries_and_Scripts/1_Imports_A03_t65: PASS, FAIL, OK # co19 issue 560
+
+LibTest/math/cos_A01_t01: PASS, FAIL, OK # co19 issue 44
+LibTest/math/exp_A01_t01: PASS, FAIL, OK # co19 issue 44
+LibTest/math/sin_A01_t01: PASS, FAIL, OK # co19 issue 44
+LibTest/math/tan_A01_t01: PASS, FAIL, OK  # co19 issue 44
+
 LibTest/async/Stream/Stream.periodic_A03_t01: PASS, FAIL, OK # co19 issue 538
 LibTest/async/Timer/run_A01_t01: PASS, FAIL, OK # co19 issue 538
 LibTest/async/Timer/Timer_A01_t01: PASS, FAIL, OK # co19 issue 538
@@ -70,16 +136,10 @@
 LibTest/async/Timer/Timer.periodic_A01_t01: PASS, FAIL, OK # co19 issue 537
 LibTest/async/Timer/Timer.periodic_A02_t01: PASS, FAIL, OK # co19 issue 538
 LibTest/async/Future/Future.delayed_A01_t02: PASS, FAIL, OK # co19 issue 536
-
-LibTest/isolate/SendPort/send_A02_t02: SKIP # co19 issue 493
-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/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/isolate/IsolateStream/contains_A02_t01: PASS, FAIL, OK # co19 issue 540
+
 
 [ $runtime == vm || $compiler == none || $compiler == dart2js ]
 LibTest/async/EventTransformStream/EventTransformStream_A01_t01: Fail # co19 issue 626
@@ -88,7 +148,6 @@
 LibTest/async/EventTransformStream/any_A02_t01: Fail # co19 issue 626
 LibTest/async/EventTransformStream/asBroadcastStream_A01_t01: Fail # co19 issue 626
 LibTest/async/EventTransformStream/asBroadcastStream_A01_t02: Fail # co19 issue 626
-LibTest/async/EventTransformStream/asBroadcastStream_A02_t01: Fail # co19 issue 626
 LibTest/async/EventTransformStream/contains_A01_t01: Fail # co19 issue 626
 LibTest/async/EventTransformStream/contains_A02_t01: Fail # co19 issue 626
 LibTest/async/EventTransformStream/contains_A03_t01: Fail # co19 issue 626
@@ -151,29 +210,86 @@
 LibTest/async/EventTransformStream/transform_A01_t01: Fail # co19 issue 626
 LibTest/async/EventTransformStream/where_A01_t01: Fail # co19 issue 626
 LibTest/async/EventTransformStream/where_A01_t02: Fail # co19 issue 626
-LibTest/async/Stream/asBroadcastStream_A02_t01: Fail # co19 issue 626
-LibTest/async/Stream/transform_A01_t01: Fail # co19 issue 626
 LibTest/async/StreamEventTransformer/bind_A01_t01: Fail # co19 issue 626
 LibTest/async/StreamEventTransformer/handleData_A01_t01: Fail # co19 issue 626
 LibTest/async/StreamEventTransformer/handleDone_A01_t01: Fail # co19 issue 626
 LibTest/async/StreamEventTransformer/handleError_A01_t01: Fail # co19 issue 626
 
+Language/12_Expressions/12_Spawning_an_Isolate_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateSink/add_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateSink/add_A01_t02: Fail # Co19 issue 639
+LibTest/isolate/IsolateSink/add_A02_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateSink/close_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateSink/close_A01_t02: Fail # Co19 issue 639
+LibTest/isolate/IsolateSink/close_A01_t03: Fail # Co19 issue 639
+LibTest/isolate/IsolateSink/close_A01_t04: Fail # Co19 issue 639
+LibTest/isolate/IsolateSink/operator_equality_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/any_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/asBroadcastStream_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/contains_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/first_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/first_A02_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/first_A02_t02: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/isBroadcast_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/isBroadcast_A01_t02: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/isEmpty_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/last_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/last_A02_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/length_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/single_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/IsolateStream/single_A02_t01: Fail # Co19 issue 639
+LibTest/isolate/ReceivePort/close_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/ReceivePort/close_A02_t01: Fail # Co19 issue 639
+LibTest/isolate/ReceivePort/receive_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/ReceivePort/receive_A01_t03: Fail # Co19 issue 639
+LibTest/isolate/ReceivePort/toSendPort_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/ReceivePort/toSendPort_A01_t03: Fail # Co19 issue 639
+LibTest/isolate/SendPort/call_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/SendPort/hashCode_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/SendPort/operator_equality_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/SendPort/send_A01_t01: Pass
+LibTest/isolate/SendPort/send_A02_t01: Fail # Co19 issue 639
+LibTest/isolate/SendPort/send_A02_t04: Fail # Co19 issue 639
+LibTest/isolate/SendPort/send_A02_t05: Fail # Co19 issue 639
+LibTest/isolate/SendPort/send_A02_t06: Fail # Co19 issue 639
+LibTest/isolate/SendPort/send_A03_t01: Fail # Co19 issue 639
+LibTest/isolate/SendPort/send_A03_t02: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnFunction_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnFunction_A01_t02: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnFunction_A01_t03: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnFunction_A01_t04: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnFunction_A01_t05: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnFunction_A02_t01: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnFunction_A03_t01: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnFunction_A04_t02: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnFunction_A04_t03: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnUri_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnUri_A01_t02: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnUri_A01_t03: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnUri_A01_t04: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/spawnUri_A01_t05: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/streamSpawnFunction_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/stream_A01_t01: Fail # Co19 issue 639
+LibTest/isolate/isolate_api/port_A01_t01: Fail # Co19 issue 639
+
+Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: MissingRuntimeError, OK # co19 issue 638
 
 ### CHECKED MODE FAILURES ###
 
-[ ($runtime == vm || $compiler == dart2js) && $checked]
-Language/13_Statements/09_Switch_A09_t01: PASS, FAIL, OK # co19 issue 633
+[ ($runtime == vm || $runtime == dartium || $compiler == dart2js) && $checked]
 Language/07_Classes/6_Constructors/2_Factories_A12_t02: fail # co19-roll r587: Please triage this failure
-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
-LibTest/async/EventTransformStream/contains_A01_t01: FAIL, OK  # co19 issue 498
-LibTest/collection/DoubleLinkedQueue/removeFirst_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
-
+Language/13_Statements/09_Switch_A09_t01: PASS, FAIL, OK # co19 issue 633
 LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue_class_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
+LibTest/collection/DoubleLinkedQueue/removeFirst_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/LinkedList_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
 LibTest/collection/ListQueue/ListQueue_class_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
 LibTest/collection/Queue/Queue_class_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
 LibTest/core/Iterable/Iterable.generate_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
-LibTest/collection/LinkedList/LinkedList_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
-
 LibTest/typed_data/Float32x4List/reduce_A01_t01: Fail # co19-roll r623: Please triage this failure
+LibTest/async/Future/catchError_A03_t05: RuntimeError # co19-roll r641: Please triage this failure
+
+[ ($runtime == vm || $compiler == dart2js) && $checked]
+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
+LibTest/async/EventTransformStream/contains_A01_t01: FAIL, OK  # co19 issue 498
 
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 171db73..f539402 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -3,6 +3,8 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2dart ]
+Language/07_Classes/6_Constructors/2_Factories_A14_t01: MissingCompileTimeError # Issue 13663
+Language/07_Classes/6_Constructors/2_Factories_A14_t02: MissingCompileTimeError # Issue 13663
 Language/07_Classes/07_Classes_A13_t02: Fail # Missing CT error on member with same name a type parameter
 Language/07_Classes/07_Classes_A13_t03: Fail # Missing CT error on member with same name a type parameter
 Language/07_Classes/07_Classes_A13_t05: Fail # Missing CT error on member with same name a type parameter
@@ -39,7 +41,6 @@
 Language/07_Classes/3_Setters_A04_t05: Fail # inherited from VM
 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/3_Constant_Constructors_A05_t04: Fail # Issue 13652
 Language/07_Classes/6_Constructors_A02_t01: Fail # http://dartbug.com/5519
 Language/12_Expressions/01_Constants_A03_t01: Fail # Issue 13652
 
@@ -131,7 +132,6 @@
 Language/13_Statements/02_Expression_Statements_A01_t08: fail # co19-roll r546: Please triage this failure
 Language/13_Statements/06_For_A01_t11: fail # co19-roll r546: Please triage this failure
 Language/13_Statements/09_Switch_A01_t02: fail # co19-roll r546: Please triage this failure
-Language/13_Statements/11_Try_A07_t03: fail # co19-roll r546: Please triage this failure
 Language/13_Statements/12_Labels_A01_t03: fail # co19-roll r546: Please triage this failure
 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
@@ -166,13 +166,12 @@
 LibTest/core/Function/Function_class_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
 
 [ $compiler == dart2dart && $minified ]
-Language/12_Expressions/08_Throw_A08_t01: RuntimeError # co19 Issue 630
 Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: fail # co19-roll r559: Please triage this failure
 Language/12_Expressions/17_Getter_Invocation_A02_t01: fail # co19-roll r559: Please triage this failure
 Language/12_Expressions/18_Assignment_A05_t02: fail # co19-roll r559: Please triage this failure
 Language/12_Expressions/18_Assignment_A05_t04: fail # co19-roll r559: Please triage this failure
-Language/13_Statements/11_Try_A06_t01: fail # co19-roll r546: Please triage this failure
-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/convert/JsonCodec/encode_A01_t02: RuntimeError # co19-roll r641: 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/stringify_A02_t01: fail # co19-roll r587: Please triage this failure
+LibTest/json/stringify_A03_t02: fail # co19-roll r587: Please triage this failure
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index cabdf4d..82fffb0 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -3,7 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $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
 
@@ -15,6 +14,8 @@
 # Crashes first, please. Then untriaged bugs. There is a section below
 # for co19 bugs.
 [ $compiler == dart2js ]
+Language/07_Classes/6_Constructors/2_Factories_A14_t01: MissingCompileTimeError # Issue 13663
+Language/07_Classes/6_Constructors/2_Factories_A14_t02: MissingCompileTimeError # Issue 13663
 Language/07_Classes/07_Classes_A13_t02: Fail # Missing CT error on member with same name a type parameter
 Language/07_Classes/07_Classes_A13_t03: Fail # Missing CT error on member with same name a type parameter
 Language/07_Classes/07_Classes_A13_t05: Fail # Missing CT error on member with same name a type parameter
@@ -24,7 +25,6 @@
 Language/03_Overview/1_Scoping_A02_t05: CompileTimeError # TODO(ahe): Please triage this failure.
 Language/03_Overview/1_Scoping_A02_t06: CompileTimeError # TODO(ahe): Please triage this failure.
 Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: fail # co19-roll r576: Please triage this failure
-Language/13_Statements/11_Try_A07_t03: fail # co19-roll r576: Please triage this failure
 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.
@@ -140,7 +140,6 @@
 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.
 LibTest/isolate/isolate_api/spawnUri_A01_t02: RuntimeError # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
 LibTest/isolate/isolate_api/spawnUri_A01_t03: RuntimeError # Runtime error: UnsupportedError: Currently spawnUri is not supported without web workers.
@@ -335,7 +334,6 @@
 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
 
 
@@ -436,7 +434,6 @@
 Language/13_Statements/06_For_A01_t11: fail # co19-roll r546: Please triage this failure
 Language/13_Statements/10_Rethrow_A01_t04: fail # co19-roll r559: Please triage this failure
 Language/13_Statements/10_Rethrow_A01_t05: fail # co19-roll r559: Please triage this failure
-Language/13_Statements/11_Try_A06_t01: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/13_Libraries_and_Scripts_A05_t03: fail # co19-roll r546: Please triage this failure
 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
@@ -445,7 +442,6 @@
 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
 Language/14_Libraries_and_Scripts/4_Scripts_A03_t01: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/5_URIs_A01_t01: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/5_URIs_A01_t11: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/5_URIs_A01_t21: fail # co19-roll r546: Please triage this failure
@@ -523,8 +519,6 @@
 Language/12_Expressions/07_Maps_A10_t05: 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
-Language/12_Expressions/12_Instance_Creation/2_Const_A09_t03: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/12_Instance_Creation_A01_t07: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/19_Conditional_A04_t03: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/20_Logical_Boolean_Expressions_A03_t01: fail # co19-roll r546: Please triage this failure
@@ -566,9 +560,6 @@
 LibTest/async/Future/Future.delayed_A03_t01: fail # co19-roll r546: Please triage this failure
 LibTest/async/Stream/first_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/async/Stream/first_A02_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/Stream.fromFuture_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/Stream.fromFuture_A02_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/Stream.fromIterable_A01_t02: fail # co19-roll r546: Please triage this failure
 LibTest/async/Stream/Stream.periodic_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/async/Timer/cancel_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/async/Timer/Timer_A01_t01: fail # co19-roll r546: Please triage this failure
@@ -577,9 +568,11 @@
 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 || $runtime == ie9) ]
-Language/12_Expressions/08_Throw_A08_t01: RuntimeError # co19 Issue 630
+LibTest/async/Stream/asBroadcastStream_A04_t03: RuntimeError # co19-roll r641: Please triage this failure
+LibTest/async/Stream/asBroadcastStream_A03_t01: RuntimeError # co19-roll r641: Please triage this failure
+LibTest/async/Timer/isActive_A01_t01: RuntimeError # co19-roll r641: Please triage this failure
+LibTest/async/Future/wait_A01_t07: RuntimeError # co19-roll r641: Please triage this failure
+LibTest/async/Timer/isActive_A01_t02: RuntimeError # co19-roll r641: 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
@@ -612,9 +605,10 @@
 Language/12_Expressions/07_Maps_A13_t01: MissingCompileTimeError # co19-roll r607: Please triage this failure
 Language/14_Libraries_and_Scripts/2_Exports_A05_t03: MissingCompileTimeError # co19-roll r623: Please triage this failure
 Language/12_Expressions/06_Symbols_A01_t02: CompileTimeError # co19-roll r623: Please triage this failure
-LibTest/core/List/List_class_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
 
 [ $compiler == dart2js ]
+LibTest/core/List/List_class_A01_t01: RuntimeError # co19-roll r623: 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
@@ -622,3 +616,9 @@
 LibTest/math/pow_A04_t01: fail # co19-roll r587: Please triage this failure
 LibTest/math/pow_A14_t01: fail # co19-roll r587: Please triage this failure
 LibTest/math/pow_A16_t01: fail # co19-roll r587: Please triage this failure
+
+LibTest/async/Stream/handleError_A04_t01: RuntimeError # co19-roll r641: Please triage this failure
+LibTest/async/Stream/listen_A05_t01: RuntimeError # co19-roll r641: Please triage this failure
+LibTest/convert/JsonCodec/encode_A01_t01: RuntimeError # co19-roll r641: Please triage this failure
+LibTest/convert/JsonCodec/encode_A01_t02: RuntimeError # co19-roll r641: Please triage this failure
+
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index 2be217a..f667cf7 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -6,106 +6,14 @@
 *: Skip # running co19 tests on content_shell would make our dartium cycle-times very long
 
 [ $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/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/07_Classes_A13_t01: Fail # co19-roll r623: Please triage this failure
-Language/07_Classes/07_Classes_A13_t04: Fail # co19-roll r623: Please triage this failure
-Language/07_Classes/07_Classes_A13_t07: Fail # co19-roll r623: Please triage this failure
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: Pass, 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/07_Classes/6_Constructors/2_Factories_A14_t01: Fail # co19-roll r623: Please triage this failure
-Language/07_Classes/6_Constructors/2_Factories_A14_t02: Fail # co19-roll r623: 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/2_Const_A10_t01: Fail # Issue 13719: 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/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/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/12_Expressions/12_Spawning_an_Isolate_A01_t01: Fail # Issue 13921
 Language/14_Libraries_and_Scripts/3_Parts_A02_t02: Pass, Timeout # Issue 13719: Please triage this failure.
 Language/14_Libraries_and_Scripts/4_Scripts_A03_t02: Fail # Issue 13719: 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
+Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: Pass # Issue 14478: This should break.
 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/HashSet/HashSet_class_A01_t01: Fail # co19-roll r623: Please triage this failure
-LibTest/collection/IterableBase/IterableBase_class_A01_t02: Fail # co19-roll r623: Please triage this failure
-LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/collection/LinkedList/forEach_A02_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/async/Future/Future_A01_t03: Fail # co19-roll r641: Please triage this failure
 LibTest/core/int/operator_left_shift_A01_t02: Pass, 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/List/List_class_A01_t01: Fail # co19-roll r623: Please triage this failure
-LibTest/core/List/removeAt_A02_t01: Fail # co19-roll r623: 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/Set/IterableBase_A01_t01: Fail # co19-roll r623: 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: Fail, Timeout # Issue 13719: Please triage this failure.
-LibTest/isolate/isolate_api/spawnUri_A01_t02: Fail # Issue 13719: Please triage this failure.
-LibTest/isolate/isolate_api/spawnUri_A01_t03: Fail # Issue 13719: Please triage this failure.
-LibTest/isolate/isolate_api/spawnUri_A01_t04: Fail, Timeout # Issue 13719: Please triage this failure.
-LibTest/isolate/isolate_api/spawnUri_A01_t05: Fail, Timeout # Issue 13719: Please triage this failure.
-LibTest/isolate/isolate_api/spawnUri_A02_t02: Fail, Timeout # Issue 13719: Please triage this failure.
-LibTest/isolate/isolate_api/spawnUri_A02_t03: Fail, Timeout # 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/ReceivePort/toSendPort_A01_t02: Pass, Fail # Issue 13719: Please triage this failure.
-LibTest/isolate/SendPort/send_A01_t01: Fail # Issue 13719: Please triage this failure.
-LibTest/math/acos_A01_t01: Pass, Fail # Issue 13719: Please triage this failure.
-LibTest/math/asin_A01_t01: Pass, Fail # Issue 13719: Please triage this failure.
-LibTest/math/atan_A01_t01: Pass, 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.
-
-Language/12_Expressions/12_Spawning_an_Isolate_A01_t01: Fail # Issue 13921
 LibTest/isolate/isolate_api/spawnFunction_A01_t01: Fail # Issue 13921
 LibTest/isolate/isolate_api/spawnFunction_A01_t02: Fail # Issue 13921
 LibTest/isolate/isolate_api/spawnFunction_A01_t03: Fail # Issue 13921
@@ -113,21 +21,19 @@
 LibTest/isolate/isolate_api/spawnFunction_A01_t05: Fail # Issue 13921
 LibTest/isolate/isolate_api/spawnFunction_A02_t01: Fail # Issue 13921
 LibTest/isolate/isolate_api/spawnFunction_A03_t01: Fail # Issue 13921
-LibTest/isolate/isolate_api/spawnFunction_A04_t01: Fail # Issue 13921
 LibTest/isolate/isolate_api/spawnFunction_A04_t02: Fail # Issue 13921
+LibTest/isolate/isolate_api/spawnFunction_A04_t02: Timeout # Issue 13719: Please triage this failure.
 LibTest/isolate/isolate_api/spawnFunction_A04_t03: Fail # Issue 13921
+LibTest/isolate/isolate_api/spawnFunction_A04_t03: Timeout # Issue 13719: Please triage this failure.
 LibTest/isolate/isolate_api/streamSpawnFunction_A01_t01: Fail # Issue 13921
-LibTest/isolate/isolate_api/streamSpawnFunction_A02_t01: Fail # Issue 13921
-LibTest/isolate/isolate_api/streamSpawnFunction_A02_t02: Fail # Issue 13921
 LibTest/isolate/IsolateSink/add_A01_t01: Fail # Issue 13921
 LibTest/isolate/IsolateSink/add_A01_t02: Fail # Issue 13921
 LibTest/isolate/IsolateSink/add_A02_t01: Fail # Issue 13921
 LibTest/isolate/IsolateSink/close_A01_t03: Fail # Issue 13921
 LibTest/isolate/IsolateSink/close_A01_t04: Fail # Issue 13921
 LibTest/isolate/IsolateSink/operator_equality_A01_t01: Fail # Issue 13921
+LibTest/isolate/ReceivePort/toSendPort_A01_t02: Pass, Fail # Issue 13719: Please triage this failure.
 LibTest/isolate/SendPort/send_A02_t01: Fail # Issue 13921
-LibTest/isolate/SendPort/send_A02_t02: Fail # Issue 13921
-LibTest/isolate/SendPort/send_A02_t03: Fail # Issue 13921
 LibTest/isolate/SendPort/send_A02_t04: Fail # Issue 13921
 LibTest/isolate/SendPort/send_A02_t05: Fail # Issue 13921
 LibTest/isolate/SendPort/send_A02_t06: Fail # Issue 13921
@@ -137,3 +43,10 @@
 LibTest/isolate/isolate_api/spawnUri_A01_t03: Skip # Issue 13992
 LibTest/isolate/isolate_api/spawnUri_A01_t04: Skip # Issue 13992
 LibTest/isolate/isolate_api/spawnUri_A01_t05: Skip # Issue 13992
+
+[ $compiler == none && $runtime == dartium && $checked ]
+Language/07_Classes/6_Constructors/2_Factories_A12_t02: Fail # Please triage this failure (enabled checked mode tests on dartium)
+Language/13_Statements/09_Switch_A09_t01: Fail # Please triage this failure (enabled checked mode tests on dartium)
+LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue_class_A01_t01: Fail # Please triage this failure (enabled checked mode tests on dartium)
+Language/12_Expressions/12_Instance_Creation_A01_t08: Fail # Please triage this failure (enabled checked mode tests on dartium)
+LibTest/core/List/removeAt_A02_t01: Fail # co19-roll r641: Please triage this failure
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 1017509..357e7b6 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -2,13 +2,17 @@
 # for 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 == vm ]
-Language/12_Expressions/01_Constants_A16_t04: fail # Issue 392
-Language/12_Expressions/01_Constants_A16_t05: fail # Issue 392
-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 || $runtime == dartium) && $unchecked]
+Language/12_Expressions/01_Constants_A16_t04: fail # Issue 392, passes in checked mode b/c of type check
+
+[ $compiler == none && ($runtime == vm || $runtime == dartium) ]
+Language/13_Statements/03_Variable_Declaration_A04_t01: Fail, MissingCompileTimeError # Issue 7052
+Language/13_Statements/03_Variable_Declaration_A04_t02: Fail, MissingCompileTimeError # Issue 7052
+Language/13_Statements/03_Variable_Declaration_A04_t05: Fail, MissingCompileTimeError # Issue 7052
+Language/13_Statements/03_Variable_Declaration_A04_t06: Fail, MissingCompileTimeError # Issue 7052
+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/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Fail # Dart issue 5802
 Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t05: Fail # Dart issue 5894
@@ -32,42 +36,40 @@
 
 Language/05_Variables/05_Variables_A05_t01: fail # Dart issue 12539
 Language/05_Variables/05_Variables_A05_t02: fail # Dart issue 12539
-Language/12_Expressions/12_Instance_Creation/2_Const_A10_t01: fail # co19 issue 525
 Language/12_Expressions/30_Identifier_Reference_A08_t02: fail # Dart issue 12593
-Language/13_Statements/03_Variable_Declaration_A04_t07: fail # co19 issue 535
-Language/13_Statements/03_Variable_Declaration_A04_t08: fail # co19 issue 535
 Language/13_Statements/06_For_A01_t11: fail # Dart issue 5675
 Language/13_Statements/09_Switch_A01_t02: fail # Dart issue 12908
 Language/13_Statements/12_Labels_A01_t03: fail # Dart issue 2238
 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/4_Scripts_A03_t03: MissingRuntimeError, OK # co19 issue
 
 LibTest/core/DateTime/parse_A03_t01: fail # Issue 12514
 
 # All isolate are being ignored at the moment as the library will go through some changes.
+LibTest/isolate/isolate_api/spawnUri_A02_t02: Fail, Timeout # VM triage, check spec.
+LibTest/isolate/isolate_api/spawnUri_A02_t03: Fail, Timeout # VM triage, check spec.
 LibTest/isolate/IsolateSink/addError_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateSink/addError_A01_t02: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateStream/any_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateStream/contains_A02_t01: fail, pass # co19-roll r546: Please triage this failure
-LibTest/isolate/SendPort/send_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/ReceivePort/receive_A01_t02: Fail # VM triage, check spec.
-LibTest/isolate/isolate_api/spawnUri_A02_t02: Fail # VM triage, check spec.
-LibTest/isolate/isolate_api/spawnUri_A02_t03: Fail # VM triage, check spec.
+LibTest/isolate/SendPort/send_A01_t01: fail # co19-roll r546: Please triage this failure
 
-LibTest/typed_data/Float32x4/clamp_A01_t01: Pass, Fail # Issue 13106 
-LibTest/typed_data/Float32x4/reciprocalSqrt_A01_t01: Pass, Fail # Issue 13398
-LibTest/typed_data/Float32x4/reciprocal_A01_t01: Pass, Fail # Issue 13398
-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
+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/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
+LibTest/typed_data/Float32x4/clamp_A01_t01: Pass, Fail # Issue 13106 
 
+[ $compiler == none && $runtime == vm ]
+LibTest/typed_data/Float32x4/reciprocalSqrt_A01_t01: Pass, Fail # Issue 13398
+LibTest/typed_data/Float32x4/reciprocal_A01_t01: Pass, Fail # Issue 13398
 
 [ $compiler == none && $runtime == vm && $checked ]
 LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/core/List/removeAt_A02_t01: Fail # co19-roll r641: Please triage this failure
 
 # Passing for the wrong reasons:
 LibTest/async/Completer/completeError_A03_t02: Pass # No AsyncError anymore. Issue 407 and 463
@@ -81,6 +83,8 @@
 LibTest/isolate/isolate_api/spawnFunction_A02_t01: Crash
 LibTest/async/Stream/Stream.periodic_A03_t01: Fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateStream/contains_A02_t01: Fail # co19-roll r546: Please triage this failure
+Language/15_Types/4_Interface_Types_A11_t01: Pass, Slow
+LibTest/core/List/List_class_A01_t01: Pass, Slow
 
 [ $compiler == none && $runtime == vm && $arch != x64 ]
 LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
@@ -92,7 +96,7 @@
 [ $compiler == none && $runtime == vm && ($arch == simarm || $arch == simmips) ]
 LibTest/core/Uri/Uri_A06_t03: Pass, Timeout # co19-roll r576: Please triage this failure
 
-[ $compiler == none && $runtime == vm && $checked ]
+[ $compiler == none && $checked && ($runtime == vm || $runtime == dartium) ]
 LibTest/typed_data/Float32x4List/elementAt_A01_t01: Fail # Dart issue 12861
 LibTest/typed_data/Float32x4List/fillRange_A01_t01: Fail # Dart issue 12861
 LibTest/typed_data/Float32x4List/first_A01_t01: Fail # Dart issue 12861
@@ -120,5 +124,3 @@
 Language/15_Types/4_Interface_Types_A11_t01: pass, timeout # Issue 13349
 Language/15_Types/4_Interface_Types_A11_t02: pass, timeout # Issue 13349
 
-[ $compiler == none && $runtime == vm && $unchecked ]
-LibTest/core/List/List_class_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
diff --git a/tests/compiler/dart2js/interceptor_test.dart b/tests/compiler/dart2js/interceptor_test.dart
index 59fa151..53a3ef5 100644
--- a/tests/compiler/dart2js/interceptor_test.dart
+++ b/tests/compiler/dart2js/interceptor_test.dart
@@ -37,5 +37,5 @@
   Expect.isFalse(generated.contains(r'a.get$length()'));
   Expect.isTrue(generated.contains(new RegExp(r'[$A-Z]+\.A\$\(\)\.length')));
   Expect.isTrue(
-      generated.contains(new RegExp(r'[$A-Z]+\.get\$length\$a\(a\)')));
+      generated.contains(new RegExp(r'[$A-Z]+\.get\$length\$as\(a\)')));
 }
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index eed4542..27e412d 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -58,7 +58,7 @@
     // 2. Some code was refactored, and there are more methods.
     // Either situation could be problematic, but in situation 2, it is often
     // acceptable to increase [expectedMethodCount] a little.
-    int expectedMethodCount = 336;
+    int expectedMethodCount = 337;
     Expect.isTrue(
         generatedCode.length <= expectedMethodCount,
         'Too many compiled methods: '
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 4c497d3..4acd9a2 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -204,6 +204,9 @@
   bool identical(Object a, Object b) { return true; }''';
 
 const String DEFAULT_ISOLATE_HELPERLIB = r'''
+  var startRootIsolate;
+  var _currentIsolate;
+  var _callInIsolate;
   class _WorkerBase {}''';
 
 class MockCompiler extends Compiler {
@@ -385,8 +388,7 @@
 
   resolverVisitor() {
     Element mockElement =
-        new ElementX('', ElementKind.FUNCTION,
-            mainApp.entryCompilationUnit);
+        new ElementX('', ElementKind.FUNCTION, mainApp.entryCompilationUnit);
     ResolverVisitor visitor =
         new ResolverVisitor(this, mockElement,
                             new CollectingTreeElements(mockElement));
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 05dca89..9657bfa 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -736,18 +736,15 @@
 
     // Check that a method just in the patch class is a target for a
     // typed selector.
-    var selector = new Selector.call(
-        'method', compiler.coreLibrary, 0);
+    var selector = new Selector.call('method', compiler.coreLibrary, 0);
     var typedSelector = new TypedSelector.exact(cls, selector);
-    Element method =
-        cls.implementation.lookupLocalMember('method');
+    Element method = cls.implementation.lookupLocalMember('method');
     Expect.isTrue(selector.applies(method, compiler));
     Expect.isTrue(typedSelector.applies(method, compiler));
 
     // Check that the declaration method in the declaration class is a target
     // for a typed selector.
-    selector = new Selector.call(
-        'clear', compiler.coreLibrary, 0);
+    selector = new Selector.call('clear', compiler.coreLibrary, 0);
     typedSelector = new TypedSelector.exact(cls, selector);
     method = cls.lookupLocalMember('clear');
     Expect.isTrue(selector.applies(method, compiler));
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index a6a382c..b1aeb6a 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -205,8 +205,7 @@
   compiler.parseScript("class Foo { foo() { return this; } }");
   compiler.resolveStatement("Foo foo;");
   ClassElement fooElement = compiler.mainApp.find("Foo");
-  FunctionElement funElement =
-      fooElement.lookupLocalMember("foo");
+  FunctionElement funElement = fooElement.lookupLocalMember("foo");
   ResolverVisitor visitor =
       new ResolverVisitor(compiler, funElement,
                           new CollectingTreeElements(funElement));
@@ -228,8 +227,7 @@
   compiler.parseScript("class Foo { static foo() { return this; } }");
   compiler.resolveStatement("Foo foo;");
   fooElement = compiler.mainApp.find("Foo");
-  funElement =
-      fooElement.lookupLocalMember("foo");
+  funElement = fooElement.lookupLocalMember("foo");
   visitor = new ResolverVisitor(compiler, funElement,
                                 new CollectingTreeElements(funElement));
   function = funElement.parseNode(compiler);
@@ -621,13 +619,11 @@
   MockCompiler compiler = new MockCompiler(coreSource: corelib);
   compiler.parseScript(script);
   compiler.resolveStatement(statement);
-  ClassElement classElement =
-      compiler.mainApp.find(className);
+  ClassElement classElement = compiler.mainApp.find(className);
   Element element;
   if (constructor != '') {
     element = classElement.lookupConstructor(
-        new Selector.callConstructor(constructor,
-                                     classElement.getLibrary()));
+        new Selector.callConstructor(constructor, classElement.getLibrary()));
   } else {
     element = classElement.lookupConstructor(
         new Selector.callDefaultConstructor(classElement.getLibrary()));
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 00c15d3..19539ae 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -470,8 +470,7 @@
 testMethodInvocationsInClass() {
   LibraryElement library = mockLibrary(compiler, CLASS_WITH_METHODS);
   compiler.parseScript(CLASS_WITH_METHODS, library);
-  ClassElement ClassWithMethods =
-      library.find("ClassWithMethods");
+  ClassElement ClassWithMethods = library.find("ClassWithMethods");
   ClassWithMethods.ensureResolved(compiler);
   Element c = ClassWithMethods.lookupLocalMember('method');
   assert(c != null);
@@ -1096,8 +1095,7 @@
   compiler.parseScript(script, library);
   ClassElement classTest = library.find("Test");
   classTest.ensureResolved(compiler);
-  FunctionElement methodTest =
-    classTest.lookupLocalMember("test");
+  FunctionElement methodTest = classTest.lookupLocalMember("test");
 
   test(String expression, [message]) {
     analyzeIn(methodTest, "{ $expression; }", message);
@@ -1138,8 +1136,7 @@
   compiler.parseScript(script, library);
   ClassElement classTest = library.find("Test");
   classTest.ensureResolved(compiler);
-  FunctionElement methodTest =
-    classTest.lookupLocalMember("test");
+  FunctionElement methodTest = classTest.lookupLocalMember("test");
 
   test(String expression, [message]) {
     analyzeIn(methodTest, "{ $expression; }", message);
@@ -1162,8 +1159,7 @@
   compiler.parseScript(script, library);
   ClassElement classTest = library.find("Test");
   classTest.ensureResolved(compiler);
-  FunctionElement methodTest =
-    classTest.lookupLocalMember("test");
+  FunctionElement methodTest = classTest.lookupLocalMember("test");
 
   test(String expression, [message]) {
     analyzeIn(methodTest, "{ $expression; }", message);
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index ff4d572..5ad5f46 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -32,6 +32,9 @@
 to_string_test: Fail # Issue 7179.
 runtime_type_test: Fail, OK # Tests extected output of Type.toString().
 
+[ $compiler == dart2js && ($runtime == drt || $runtime == ff || $runtime == safari || $runtime == chrome) ]
+isolate2_test/01: Fail # Issue 14458.
+
 [ $jscl ]
 timer_test: Fail # Issue 7728.
 
@@ -42,6 +45,3 @@
 [ $csp ]
 deferred/deferred_class_test: Fail # http://dartbug.com/3940
 deferred/deferred_constant_test: Fail # http://dartbug.com/3940
-
-[ $compiler == dart2js && $browser ]
-mirror_printer_test: Fail # Issue 14304
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/isolate2_negative_test.dart b/tests/compiler/dart2js_extra/isolate2_test.dart
similarity index 72%
rename from tests/compiler/dart2js_extra/isolate2_negative_test.dart
rename to tests/compiler/dart2js_extra/isolate2_test.dart
index 8004371..ea06acd 100644
--- a/tests/compiler/dart2js_extra/isolate2_negative_test.dart
+++ b/tests/compiler/dart2js_extra/isolate2_test.dart
@@ -10,11 +10,13 @@
 library isolate2_negative_test;
 import 'dart:isolate';
 
-void entry() {
-  throw "foo";
+void entry(SendPort replyTo) {
+  throw "foo";  /// 01: runtime error
+  replyTo.send("done");
 }
 
 main() {
-  SendPort port = spawnFunction(entry);
-  port.receive((msg) {});
+  var port = new ReceivePort();
+  Isolate.spawn(entry, port.sendPort);
+  port.first;
 }
diff --git a/tests/compiler/dart2js_native/native_class_avoids_hidden_name_frog_test.dart b/tests/compiler/dart2js_native/native_class_avoids_hidden_name_frog_test.dart
index 5e4e0c3..1d3b04b 100644
--- a/tests/compiler/dart2js_native/native_class_avoids_hidden_name_frog_test.dart
+++ b/tests/compiler/dart2js_native/native_class_avoids_hidden_name_frog_test.dart
@@ -11,32 +11,32 @@
   static AA create() => makeA();
 }
 
-class BB native "C" {
+class BB native "CC" {
   get name => 'BB';
   static BB create() => makeB();
 }
 
-class C {  // Ordinary class with name clashing with native class.
-  get name => 'C';
-  static C create() => new C();
+class CC {  // Ordinary class with name clashing with native class.
+  get name => 'CC';
+  static CC create() => new CC();
 }
 
 makeA() native;
 makeB() native;
 
 void setup1() native """
-// Poison hidden native names 'BB' and 'C' to prove the compiler didn't place
+// Poison hidden native names 'BB' and 'CC' to prove the compiler didn't place
 // anthing on the hidden native class.
 BB = null;
-C = null;
+CC = null;
 """;
 
 void setup2() native """
 // This code is all inside 'setup' and so not accesible from the global scope.
 function BB(){}
-function C(){}
-makeA = function(){return new BB};  // AA is "*BB"
-makeB = function(){return new C};  // BB is "*C"
+function CC(){}
+makeA = function(){return new BB};  // AA is native "BB"
+makeB = function(){return new CC};  // BB is native "CC"
 """;
 
 int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1));
@@ -45,12 +45,12 @@
   setup1();
   setup2();
 
-  var things = [AA.create(), BB.create(), C.create()];
+  var things = [AA.create(), BB.create(), CC.create()];
   var a = things[inscrutable(0)];
   var b = things[inscrutable(1)];
   var c = things[inscrutable(2)];
 
   Expect.equals('AA', a.name);
   Expect.equals('BB', b.name);
-  Expect.equals('C', c.name);
+  Expect.equals('CC', c.name);
 }
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 3ea6490..c3db052 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -66,7 +66,6 @@
 [ $compiler == dart2dart ]
 compare_to2_test: Fail # inherited from VM
 unicode_test: Fail # inherited from VM
-main_test: Fail # dart2dart needs to check for both main() and main(args).
 
 # Library changes
 [ $compiler == none || $compiler == dart2js || $compiler == dart2dart ]
diff --git a/tests/corelib/json_test.dart b/tests/corelib/json_test.dart
index e5d0758..86485e0 100644
--- a/tests/corelib/json_test.dart
+++ b/tests/corelib/json_test.dart
@@ -5,12 +5,12 @@
 library json_test;
 
 import "package:expect/expect.dart";
-import "dart:json";
+import "dart:convert";
 
 bool badFormat(e) => e is FormatException;
 
 void testJson(json, expected) {
-  var value = parse(json);
+  var value = JSON.decode(json);
   compare(expected, actual, path) {
     if (expected is List) {
       Expect.isTrue(actual is List);
@@ -53,7 +53,7 @@
 }
 
 void testThrows(json) {
-  Expect.throws(() => parse(json), badFormat, "json = '${escape(json)}'");
+  Expect.throws(() => JSON.decode(json), badFormat, "json = '${escape(json)}'");
 }
 
 testNumbers() {
diff --git a/tests/corelib/string_pattern_test.dart b/tests/corelib/string_pattern_test.dart
index 25e12e7..c1bd241 100644
--- a/tests/corelib/string_pattern_test.dart
+++ b/tests/corelib/string_pattern_test.dart
@@ -34,7 +34,7 @@
   Expect.equals(str.indexOf('with', 0), match.start);
   Expect.equals(str.indexOf('with', 0) + helloPattern.length, match.end);
   Expect.equals(helloPattern, match.pattern);
-  Expect.equals(str, match.str);
+  Expect.equals(str, match.input);
   Expect.equals(helloPattern, match[0]);
   Expect.equals(0, match.groupCount);
 }
@@ -51,7 +51,7 @@
     Expect.equals(
         str.indexOf('hello', start) + helloPattern.length, match.end);
     Expect.equals(helloPattern, match.pattern);
-    Expect.equals(str, match.str);
+    Expect.equals(str, match.input);
     Expect.equals(helloPattern, match[0]);
     Expect.equals(0, match.groupCount);
     start = match.end;
diff --git a/tests/corelib/string_source_test.dart b/tests/corelib/string_source_test.dart
index 9c16be5..bf91390 100644
--- a/tests/corelib/string_source_test.dart
+++ b/tests/corelib/string_source_test.dart
@@ -4,7 +4,7 @@
 
 // Test that different representations of the same string are all equal.
 
-import "dart:json" as json;
+import "dart:convert";
 
 import "package:expect/expect.dart";
 
@@ -23,8 +23,8 @@
     (new StringBuffer()..writeCharCode(0xd801)
                        ..writeCharCode(0xdc12)).toString(),
     (new StringBuffer()..writeCharCode(0x10412)).toString(),
-    json.parse('"\u{10412}"'),
-    json.parse('{"\u{10412}":[]}').keys.first
+    JSON.decode('"\u{10412}"'),
+    JSON.decode('{"\u{10412}":[]}').keys.first
   ];
   for (String string in strings) {
     Expect.equals(base.length, string.length);
diff --git a/tests/corelib/toInt_test.dart b/tests/corelib/toInt_test.dart
new file mode 100644
index 0000000..7a69691
--- /dev/null
+++ b/tests/corelib/toInt_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+main() {
+  Expect.equals(-0x80000001, (-0x80000001).toInt()); 
+  Expect.equals(-0x80000000, (-0x80000000 - 0.7).toInt()); 
+  Expect.equals(-0x80000000, (-0x80000000 - 0.3).toInt()); 
+  Expect.equals(-0x7FFFFFFF, (-0x80000000 + 0.3).toInt()); 
+  Expect.equals(-0x7FFFFFFF, (-0x80000000 + 0.7).toInt()); 
+  Expect.equals(-0x7FFFFFFF, (-0x7FFFFFFF).toInt()); 
+  Expect.equals(0x7FFFFFFE, (0x7FFFFFFE).toInt()); 
+  Expect.equals(0x7FFFFFFE, (0x7FFFFFFF - 0.7).toInt()); 
+  Expect.equals(0x7FFFFFFE, (0x7FFFFFFF - 0.3).toInt()); 
+  Expect.equals(0x7FFFFFFF, (0x7FFFFFFF + 0.3).toInt()); 
+  Expect.equals(0x7FFFFFFF, (0x7FFFFFFF + 0.7).toInt()); 
+  Expect.equals(0x80000000, 0x80000000.toInt()); 
+}
diff --git a/tests/html/async_test.dart b/tests/html/async_test.dart
index 616258c..a0d99fb 100644
--- a/tests/html/async_test.dart
+++ b/tests/html/async_test.dart
@@ -7,61 +7,61 @@
 import 'dart:isolate';
 import 'dart:html';
 
-oneshotTimerIsolate() {
-  port.receive((msg, replyTo) {
-    expect(msg, 'START');
-    new Timer(const Duration(milliseconds: 10), () {
+oneshotTimerIsolate(message) {
+  var command = message[0];
+  var replyTo = message[1];
+  expect(command, 'START');
+  new Timer(const Duration(milliseconds: 10), () {
+    replyTo.send('DONE');
+  });
+}
+
+periodicTimerIsolate(message) {
+  var command = message[0];
+  var replyTo = message[1];
+  expect(command, 'START');
+  int counter = 0;
+  new Timer.periodic(const Duration(milliseconds: 10), (timer) {
+    if (counter == 3) {
+      counter = 1024;
+      timer.cancel();
+      // Wait some more time to be sure callback won't be invoked any
+      // more.
+      new Timer(const Duration(milliseconds: 30), () {
+        replyTo.send('DONE');
+      });
+      return;
+    }
+    assert(counter < 3);
+    counter++;
+  });
+}
+
+cancellingIsolate(message) {
+  var command = message[0];
+  var replyTo = message[1];
+  expect(command, 'START');
+  bool shot = false;
+  var oneshot;
+  var periodic;
+  periodic = new Timer.periodic(const Duration(milliseconds: 10), (timer) {
+    expect(shot, isFalse);
+    shot = true;
+    expect(timer, same(periodic));
+    periodic.cancel();
+    oneshot.cancel();
+    // Wait some more time to be sure callbacks won't be invoked any
+    // more.
+    new Timer(const Duration(milliseconds: 50), () {
       replyTo.send('DONE');
     });
   });
-}
-
-periodicTimerIsolate() {
-  port.receive((msg, replyTo) {
-    expect(msg, 'START');
-    int counter = 0;
-    new Timer.periodic(const Duration(milliseconds: 10), (timer) {
-      if (counter == 3) {
-        counter = 1024;
-        timer.cancel();
-        // Wait some more time to be sure callback won't be invoked any
-        // more.
-        new Timer(const Duration(milliseconds: 30), () {
-          replyTo.send('DONE');
-        });
-        return;
-      }
-      assert(counter < 3);
-      counter++;
-    });
-  });
-}
-
-cancellingIsolate() {
-  port.receive((msg, replyTo) {
-    expect(msg, 'START');
-    bool shot = false;
-    var oneshot;
-    var periodic;
-    periodic = new Timer.periodic(const Duration(milliseconds: 10), (timer) {
-      expect(shot, isFalse);
-      shot = true;
-      expect(timer, same(periodic));
-      periodic.cancel();
-      oneshot.cancel();
-      // Wait some more time to be sure callbacks won't be invoked any
-      // more.
-      new Timer(const Duration(milliseconds: 50), () {
-        replyTo.send('DONE');
-      });
-    });
-    // We launch the oneshot timer after the periodic timer. Otherwise a
-    // (very long) context switch could make this test flaky: assume the
-    // oneshot timer is created first and then there is a 30ms context switch.
-    // when the periodic timer is scheduled it would execute after the oneshot.
-    oneshot = new Timer(const Duration(milliseconds: 30), () {
-      fail('Should never be invoked');
-    });
+  // We launch the oneshot timer after the periodic timer. Otherwise a
+  // (very long) context switch could make this test flaky: assume the
+  // oneshot timer is created first and then there is a 30ms context switch.
+  // when the periodic timer is scheduled it would execute after the oneshot.
+  oneshot = new Timer(const Duration(milliseconds: 30), () {
+    fail('Should never be invoked');
   });
 }
 
@@ -69,15 +69,21 @@
   useHtmlConfiguration();
 
   test('one shot timer in pure isolate', () {
-    expect(spawnFunction(oneshotTimerIsolate).call('START'),
-           completion('DONE'));
+    var response = new ReceivePort();
+    var remote = Isolate.spawn(oneshotTimerIsolate,
+                               ['START', response.sendPort]);
+    expect(remote.then((_) => response.first), completion('DONE'));
   });
   test('periodic timer in pure isolate', () {
-    expect(spawnFunction(periodicTimerIsolate).call('START'),
-           completion('DONE'));
+    var response = new ReceivePort();
+    var remote = Isolate.spawn(periodicTimerIsolate,
+                               ['START', response.sendPort]);
+    expect(remote.then((_) => response.first), completion('DONE'));
   });
   test('cancellation in pure isolate', () {
-    expect(spawnFunction(cancellingIsolate).call('START'),
-           completion('DONE'));
+    var response = new ReceivePort();
+    var remote = Isolate.spawn(cancellingIsolate,
+                               ['START', response.sendPort]);
+    expect(remote.then((_) => response.first), completion('DONE'));
   });
 }
diff --git a/tests/html/document_test.dart b/tests/html/document_test.dart
index ca04a0f..2a543e7 100644
--- a/tests/html/document_test.dart
+++ b/tests/html/document_test.dart
@@ -66,7 +66,7 @@
       var div = new Element.html('<div><div id="foo">bar</div></div>');
       var doc = document.implementation.createHtmlDocument('');
       expect(doc.adoptNode(div), div);
-      expect(div.document, doc);
+      expect(div.ownerDocument, doc);
       doc.body.nodes.add(div);
       expect(doc.query('#foo').text, 'bar');
     });
@@ -76,7 +76,7 @@
       var doc = document.implementation.createHtmlDocument('');
       var div2 = doc.importNode(div, true);
       expect(div2, isNot(equals(div)));
-      expect(div2.document, doc);
+      expect(div2.ownerDocument, doc);
       doc.body.nodes.add(div2);
       expect(doc.query('#foo').text, 'bar');
     });
diff --git a/tests/html/html.status b/tests/html/html.status
index e211881..cb34ece 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -70,7 +70,7 @@
 worker_api_test: Fail # IE does not support URL.createObjectURL in web workers.
 
 [ $compiler == dart2js && $runtime == safari ]
-url_test: Fail # Issue 10096
+url_test: Pass, Fail # Issue 14506 Passes only on certain versions of Safari
 audiobuffersourcenode_test/supported: Pass, Timeout # Issue 12772
 
 [ $compiler == dart2js && $browser && $checked ]
@@ -273,8 +273,8 @@
 input_element_test/supported_time: Fail, Crash
 input_element_test/supported_week: Fail, Crash
 webgl_1_test: Pass, Fail # Issue 8219
-wheelevent_test: Fail # Issue: 12798
-xhr_test/xhr_requestBlob: Fail # Issue: 9178 Safari doesn't support Blob responses.
+wheelevent_test: Pass, Fail # Issue: 14506 Passes only on certain versions of Safari
+xhr_test/xhr_requestBlob: Pass, Fail # Issue: 14506 Passes only on certain versions of Safari
 canvasrenderingcontext2d_test/drawImage_video_element: Fail # Safari does not support drawImage w/ video element
 canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Fail # Safari does not support drawImage w/ video element
 audiocontext_test/functional: Fail # Issue 14354
diff --git a/tests/html/isolates_test.dart b/tests/html/isolates_test.dart
index 608593f..fe35c20 100644
--- a/tests/html/isolates_test.dart
+++ b/tests/html/isolates_test.dart
@@ -2,12 +2,15 @@
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_config.dart';
 import 'dart:html';
-import 'dart:json';
+import 'dart:convert';
 import 'dart:isolate' as isolate;
 
 String responseFor(message) => 'response for $message';
 
-void isolateEntry() {
+void isolateEntry(isolate.SendPort initialReplyTo) {
+  var port = new isolate.ReceivePort();
+  initialReplyTo.send(port.sendPort);
+
   bool wasThrown = false;
   try {
     window.alert('Test');
@@ -19,31 +22,44 @@
     return;
   }
 
-  // Check that JSON library was loaded to isolate.
-  stringify([1, 2, 3]);
+  // Check that convert library was loaded to isolate.
+  JSON.encode([1, 2, 3]);
 
-  isolate.port.receive((message, replyTo) {
-    replyTo.send(responseFor(message), null);
+  port.listen((message) {
+    var data = message[0];
+    var replyTo = message[1];
+    replyTo.send(responseFor(data));
   });
 }
 
+Future sendReceive(isolate.SendPort port, msg) {
+  var response = new isolate.ReceivePort();
+  port.send([msg, response.sendPort]);
+  return response.first;
+}
+
 main() {
   useHtmlConfiguration();
   test('IsolateSpawn', () {
-    isolate.spawnFunction(isolateEntry);
+    var port = new isolate.ReceivePort();
+    isolate.Isolate.spawn(isolateEntry, port.sendPort);
+    port.close();
   });
   test('NonDOMIsolates', () {
     var callback = expectAsync0((){});
-    var port = isolate.spawnFunction(isolateEntry);
-    final msg1 = 'foo';
-    final msg2 = 'bar';
-    port.call(msg1).then((response) {
-      guardAsync(() {
-        expect(response, equals(responseFor(msg1)));
-        port.call(msg2).then((response) {
-          guardAsync(() {
-            expect(response, equals(responseFor(msg2)));
-            callback();
+    var response = new isolate.ReceivePort();
+    var remote = isolate.Isolate.spawn(isolateEntry, response.sendPort);
+    response.first.then((port) {
+      final msg1 = 'foo';
+      final msg2 = 'bar';
+      sendReceive(port, msg1).then((response) {
+        guardAsync(() {
+          expect(response, equals(responseFor(msg1)));
+          sendReceive(port, msg2).then((response) {
+            guardAsync(() {
+              expect(response, equals(responseFor(msg2)));
+              callback();
+            });
           });
         });
       });
diff --git a/tests/html/js_test.dart b/tests/html/js_test.dart
index c7d53f3..633ed89 100644
--- a/tests/html/js_test.dart
+++ b/tests/html/js_test.dart
@@ -210,6 +210,10 @@
 
 class TestDartObject {}
 
+class Callable {
+  call() => 'called';
+}
+
 main() {
   _injectJs();
   useHtmlConfiguration();
@@ -470,7 +474,7 @@
 
   });
 
-  group('Dart callback', () {
+  group('Dart functions', () {
     test('invoke Dart callback from JS', () {
       expect(() => context.callMethod('invokeCallback'), throws);
 
@@ -508,6 +512,13 @@
       expect(result, 42);
     });
 
+    test('emulated functions should be callable in JS', () {
+      context['callable'] = new Callable();
+      var result = context.callMethod('callable');
+      expect(result, 'called');
+      context.deleteProperty('callable');
+    });
+
   });
 
   group('JsObject.jsify()', () {
diff --git a/tests/html/mutationobserver_test.dart b/tests/html/mutationobserver_test.dart
index f73f2a5..0af69c5 100644
--- a/tests/html/mutationobserver_test.dart
+++ b/tests/html/mutationobserver_test.dart
@@ -99,15 +99,5 @@
         div1.append(div2);
       }, expectation);
     });
-
-    test('mutation event', () {
-      // Bug 8076 that not all optional params are optional in Dartium.
-      var event = new MutationEvent('something', prevValue: 'prev',
-          newValue: 'new', attrName: 'attr');
-      expect(event is MutationEvent, isTrue);
-      expect(event.prevValue, 'prev');
-      expect(event.newValue, 'new');
-      expect(event.attrName, 'attr');
-    });
   });
 }
diff --git a/tests/html/webgl_1_test.dart b/tests/html/webgl_1_test.dart
index f09db72..ae276eb 100644
--- a/tests/html/webgl_1_test.dart
+++ b/tests/html/webgl_1_test.dart
@@ -88,7 +88,24 @@
         context.texSubImage2DCanvas(1, 1, 1, 1, 1, 10, new CanvasElement());
         context.texSubImage2DVideo(1, 1, 1, 1, 1, 10, new VideoElement());
       });
+
+      test('getContextAttributes', () {
+        var canvas = new CanvasElement();
+        var context = canvas.getContext3d();
+        var attributes = context.getContextAttributes();
+
+        expect(attributes, isNotNull);
+        expect(attributes, new isInstanceOf<gl.ContextAttributes>());
+
+        expect(attributes.alpha, isBoolean);
+        expect(attributes.antialias, isBoolean);
+        expect(attributes.depth, isBoolean);
+        expect(attributes.premultipliedAlpha, isBoolean);
+        expect(attributes.preserveDrawingBuffer, isBoolean);
+        expect(attributes.stencil, isBoolean);
+      });
     }
   });
 }
 
+Matcher isBoolean = anyOf(isTrue, isFalse);
diff --git a/tests/html/worker_api_test.dart b/tests/html/worker_api_test.dart
index 947c918..e1ab1a4 100644
--- a/tests/html/worker_api_test.dart
+++ b/tests/html/worker_api_test.dart
@@ -8,24 +8,25 @@
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
 
-worker() {
-  port.receive((String uri, SendPort replyTo) {
-    try {
-      var url = Url.createObjectUrl(new Blob([''], 'application/javascript'));
-      Url.revokeObjectUrl(url);
-      replyTo.send('Hello from Worker');
-    } catch (e) {
-      replyTo.send('Error: $e');
-    }
-    port.close();
-  });
+worker(message) {
+  var uri = message[0];
+  var replyTo = message[1];
+  try {
+    var url = Url.createObjectUrl(new Blob([''], 'application/javascript'));
+    Url.revokeObjectUrl(url);
+    replyTo.send('Hello from Worker');
+  } catch (e) {
+    replyTo.send('Error: $e');
+  }
 }
 
 main() {
   useHtmlConfiguration();
 
   test('Use Worker API in Worker', () {
-    spawnFunction(worker).call('').then(
-        expectAsync1((reply) => expect(reply, equals('Hello from Worker'))));
+    var response = new ReceivePort();
+    var remote = Isolate.spawn(worker, ['', response.sendPort]);
+    remote.then((_) => response.first)
+        .then(expectAsync1((reply) => expect(reply, equals('Hello from Worker'))));
   });
 }
diff --git a/tests/isolate/browser/compute_this_script_browser_stream_test.dart b/tests/isolate/browser/compute_this_script_browser_stream_test.dart
deleted file mode 100644
index 509614e..0000000
--- a/tests/isolate/browser/compute_this_script_browser_stream_test.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that spawn works even when there are many script files in the page.
-// This requires computing correctly the URL to the orignal script, so we can
-// pass it to the web worker APIs.
-library compute_this_script;
-
-import 'dart:html';
-import 'dart:isolate';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-
-child() {
-  var sink;
-  stream.listen((msg) {
-    sink = msg;
-  }, onDone: () {
-    sink.add("done");
-    sink.close();
-  });
-}
-
-main() {
-  useHtmlConfiguration();
-  var script = new ScriptElement();
-  document.body.append(script);
-  test('spawn with other script tags in page', () {
-    var box = new MessageBox();
-    box.stream.listen(expectAsync1((msg) {
-      expect(msg, equals("done"));
-    }));
-
-    IsolateSink s = streamSpawnFunction(child);
-    s.add(box.sink);
-    s.close();
-  });
-}
diff --git a/tests/isolate/browser/compute_this_script_browser_test.dart b/tests/isolate/browser/compute_this_script_browser_test.dart
index 74cd118..2b71451 100644
--- a/tests/isolate/browser/compute_this_script_browser_test.dart
+++ b/tests/isolate/browser/compute_this_script_browser_test.dart
@@ -12,11 +12,10 @@
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
 
-child() {
-  port.receive((msg, reply) {
-    reply.send('re: $msg');
-    port.close();
-  });
+child(var message) {
+  var data = message[0];
+  var reply = message[1];
+  reply.send('re: $data');
 }
 
 main() {
@@ -25,12 +24,11 @@
   document.body.append(script);
   test('spawn with other script tags in page', () {
     ReceivePort port = new ReceivePort();
-    port.receive(expectAsync2((msg, _) {
+    port.listen(expectAsync1((msg) {
       expect(msg, equals('re: hi'));
       port.close();
     }));
 
-    SendPort s = spawnFunction(child);
-    s.send('hi', port.toSendPort());
+    Isolate.spawn(child, ['hi', port.sendPort]);
   });
 }
diff --git a/tests/isolate/browser/typed_data_message_test.dart b/tests/isolate/browser/typed_data_message_test.dart
index 38e7815..e448390 100644
--- a/tests/isolate/browser/typed_data_message_test.dart
+++ b/tests/isolate/browser/typed_data_message_test.dart
@@ -56,42 +56,55 @@
   expect(actual.length, expected.length);
 }
 
-pingPong() {
+pingPong(SendPort initialReplyTo) {
+  var port = new ReceivePort();
+  initialReplyTo.send(port.sendPort);
   initializeList();
   int count = 0;
-  port.receive((var message, SendPort replyTo) {
-    if (message == -1) {
+  port.listen((var message) {
+    var data = message[0];
+    SendPort replyTo = message[1];
+    if (data == -1) {
       port.close();
       replyTo.send(count, null);
     } else {
       // Check if the received object is correct.
       if (count < elements.length) {
-        VerifyObject(count, message);
+        VerifyObject(count, data);
       }
       // Bounce the received object back so that the sender
       // can make sure that the object matches.
-      replyTo.send(message, null);
+      replyTo.send(data, null);
       count++;
     }
   });
 }
 
+Future sendReceive(SendPort port, msg) {
+  ReceivePort response = new ReceivePort();
+  port.send([msg, response.sendPort]);
+  return response.first;
+}
+
 main() {
   initializeList();
   test("send objects and receive them back", () {
-    SendPort remote = spawnFunction(pingPong);
-    // Send objects and receive them back.
-    for (int i = 0; i < elements.length; i++) {
-      var sentObject = elements[i];
-      var idx = i;
-      remote.call(sentObject).then(expectAsync1((var receivedObject) {
-        VerifyObject(idx, receivedObject);
-      }));
-    }
+    ReceivePort response = new ReceivePort();
+    Isolate.spawn(pingPong, response.sendPort);
+    response.first.then((SendPort remote) {
+      // Send objects and receive them back.
+      for (int i = 0; i < elements.length; i++) {
+        var sentObject = elements[i];
+        var idx = i;
+        sendReceive(remote, sentObject).then(expectAsync1((var receivedObject) {
+          VerifyObject(idx, receivedObject);
+        }));
+      }
 
-    // Shutdown the MessageServer.
-    remote.call(-1).then(expectAsync1((int message) {
-        expect(message, elements.length);
-      }));
+      // Shutdown the MessageServer.
+      sendReceive(remote, -1).then(expectAsync1((int message) {
+          expect(message, elements.length);
+        }));
+    });
   });
 }
diff --git a/tests/isolate/count_stream_test.dart b/tests/isolate/count_stream_test.dart
deleted file mode 100644
index 50119ae..0000000
--- a/tests/isolate/count_stream_test.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library CountTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import 'dart:isolate';
-
-void countMessages() {
-  int count = 0;
-  IsolateSink replySink;
-  bool isFirst = true;
-  stream.listen((msg) {
-    if (isFirst) {
-      replySink = msg;
-      isFirst = false;
-      return;
-    }
-    replySink.add(count);
-    count++;
-  }, onDone: () {
-    expect(count, 10);
-    replySink.close();
-  });
-}
-
-void main() {
-  test("count 10 consecutive stream messages", () {
-    int count = 0;
-    MessageBox box = new MessageBox();
-    IsolateSink remote = streamSpawnFunction(countMessages);
-    remote.add(box.sink);
-    box.stream.listen(expectAsync1((remoteCount) {
-      expect(remoteCount, count);
-      count++;
-      if (count < 10) {
-        remote.add(null);
-      } else {
-        remote.close();
-      }
-    }, count: 10), onDone: expectAsync0(() {
-      expect(count, 10);
-    }));
-    remote.add(null);
-  });
-}
diff --git a/tests/isolate/count_test.dart b/tests/isolate/count_test.dart
index 2010c88..c0cbde3 100644
--- a/tests/isolate/count_test.dart
+++ b/tests/isolate/count_test.dart
@@ -6,47 +6,53 @@
 import '../../pkg/unittest/lib/unittest.dart';
 import 'dart:isolate';
 
-void countMessages() {
+void countMessages(replyTo) {
   int count = 0;
-  port.receive((int message, SendPort replyTo) {
+  var port = new ReceivePort();
+  replyTo.send(["init", port.sendPort]);
+  port.listen((int message) {
     if (message == -1) {
       expect(count, 10);
-      replyTo.send(-1, null);
+      replyTo.send(["done"]);
       port.close();
       return;
     }
-    expect(message, count);
     count++;
-    replyTo.send(message * 2, null);
+    expect(message, count);
+    replyTo.send(["count", message * 2]);
   });
 }
 
 void main() {
   test("count 10 consecutive messages", () {
-    int count = 0;
-    SendPort remote = spawnFunction(countMessages);
     ReceivePort local = new ReceivePort();
-    SendPort reply = local.toSendPort();
-
-    local.receive(expectAsync2((int message, SendPort replyTo) {
-      if (message == -1) {
-        // [count] is '11' because when we sent '9' to [remote],
-        // the other isolate will send another message '18', that this
-        // isolate will receive. Then this isolate will send '10' to
-        // [remote] and increment [count]. Note that this last '10'
-        // message will not be received by the other isolate, since it
-        // received '-1' before.
-        expect(count, 11);
-        local.close();
-        return;
+    Isolate.spawn(countMessages, local.sendPort);
+    SendPort remote;
+    int count = 0;
+    var done = expectAsync0((){});
+    local.listen((msg) {
+      switch (msg[0]) {
+        case "init":
+          expect(remote, null);
+          remote = msg[1];
+          remote.send(++count);
+          break;
+        case "count":
+          expect(msg[1], count * 2);
+          if (count == 10) {
+            remote.send(-1);
+          } else {
+            remote.send(++count);
+          }
+          break;
+        case "done":
+          expect(count, 10);
+          local.close();
+          done();
+          break;
+        default:
+          fail("unreachable: ${msg[0]}");
       }
-
-      expect(message, (count - 1) * 2);
-      remote.send(count++, reply);
-      if (count == 10) {
-        remote.send(-1, reply);
-      }
-    }, count: 11));
-    remote.send(count++, reply);
+    });
   });
 }
diff --git a/tests/isolate/cross_isolate_message_stream_test.dart b/tests/isolate/cross_isolate_message_stream_test.dart
deleted file mode 100644
index 70d1345..0000000
--- a/tests/isolate/cross_isolate_message_stream_test.dart
+++ /dev/null
@@ -1,112 +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.
-
-// Dart test program for testing that isolates can communicate to isolates
-// other than the main isolate.
-
-library CrossIsolateMessageTest;
-import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
-
-/*
- * Everything starts in the main-isolate (in the main-method).
- * The main isolate spawns two isolates: isolate1 (with entry point
- * 'crossIsolate1') and isolate2 (with entry point 'crossIsolate2').
- *
- * The main-isolate creates a new message-box and sends its sink to both
- * isolates. Whenever isolate1 or isolate2 send something to the main-isolate
- * they will use this sink.
- * Isolate2 stores the sink and replies with a new sink (sink2b) it created.
- * Isolate1 stores the sink and waits for another message.
- * Main receives isolate2's sink2b and sends it to isolate1.
- * Isolate1 stores this sink as "otherIsolate" and send a new sink (sink1b) to
- * the main isolate.
- * Main receives sink1b and sents a message "fromMain, 42" to sink1b.
- * isolate1 receives this message, modifies it (adding 58 to 42) and forwards
- * it to isolate2 (otherIsolate).
- * isolate2 receives the message, modifies it (adding 399), and sends it to
- * the main isolate.
- * The main-isolate receives it, verifies that the result is 499 and ends the
- * test.
- */
-
-void crossIsolate1() {
-  bool first = true;
-  IsolateSink mainIsolate;
-  var subscription = stream.listen((msg) {
-    if (first) {
-      first = false;
-      mainIsolate = msg;
-      return;
-    }
-    IsolateSink otherIsolate = msg;
-    MessageBox box = new MessageBox();
-    box.stream.single.then((msg) {
-      expect(msg[0], "fromMain");
-      otherIsolate.add(["fromIsolate1", msg[1] + 58]);  // 100;
-      otherIsolate.close();
-      box.stream.close();
-    });
-    mainIsolate.add(['ready1', box.sink]);
-    stream.close();
-  });
-}
-
-void crossIsolate2() {
-  var subscription;
-  subscription = stream.listen((msg) {
-    IsolateSink mainIsolate = msg;
-    MessageBox box = new MessageBox();
-    box.stream.listen((msg) {
-      expect(msg[0], "fromIsolate1");
-      mainIsolate.add(["fromIsolate2", msg[1] + 399]);  // 499;
-      mainIsolate.close();
-      box.stream.close();
-    });
-    mainIsolate.add(['ready2', box.sink]);
-    subscription.cancel();
-  });
-}
-
-main() {
-  test("share sink, and send message cross isolates ", () {
-    IsolateSink sink1 = streamSpawnFunction(crossIsolate1);
-    IsolateSink sink2 = streamSpawnFunction(crossIsolate2);
-    // Create a new sink and send it to isolate2.
-    MessageBox box = new MessageBox();
-    sink1.add(box.sink);
-    sink2.add(box.sink);
-    int msgNumber = 0;
-
-    bool isReady1 = false;
-    bool isReady2 = false;
-    bool hasSentMessage = false;
-
-    Function ready1 = expectAsync0(() => isReady1 = true);
-    Function ready2 = expectAsync0(() => isReady2 = true);
-    Function fromIsolate2 = expectAsync1((data) {
-      expect(data, 499);
-    });
-    IsolateSink sink1b;
-    IsolateSink sink2b;
-
-    box.stream.listen((msg) {
-      switch (msg[0]) {
-        case 'ready1': ready1(); sink1b = msg[1]; break;
-        case 'ready2':
-          ready2();
-          sink2b = msg[1];
-          sink1.add(sink2b);
-          break;
-        case 'fromIsolate2': fromIsolate2(msg[1]); break;
-        default: throw "bad message";
-      }
-      if (isReady1 && isReady2 && !hasSentMessage) {
-        hasSentMessage = true;
-        sink1b.add(["fromMain", 42]);
-        sink1b.close();
-      }
-    });
-  });
-}
diff --git a/tests/isolate/cross_isolate_message_test.dart b/tests/isolate/cross_isolate_message_test.dart
index 41b2c7a..00874d0 100644
--- a/tests/isolate/cross_isolate_message_test.dart
+++ b/tests/isolate/cross_isolate_message_test.dart
@@ -9,51 +9,49 @@
 import 'dart:isolate';
 import '../../pkg/unittest/lib/unittest.dart';
 
-void crossIsolate1() {
-  port.receive((msg, replyTo) {
-    SendPort otherIsolate = msg;
-    ReceivePort receivePort = new ReceivePort();
-    receivePort.receive((msg, replyTo) {
-      otherIsolate.send(msg + 58, null);  // 100.
-      receivePort.close();
-    });
-    replyTo.send(['ready', receivePort.toSendPort()]);
-    port.close();
+/*
+ * Everything starts in the main-isolate (in the main-method).
+ * The main isolate spawns two isolates: isolate1 (with entry point
+ * 'crossIsolate1') and isolate2 (with entry point 'crossIsolate2').
+ *
+ * The main isolate creates two isolates, isolate1 and isolate2.
+ * The second isolate is created with a send-port being listened on by
+ * isolate1. A message is passed along this from isolate2 to isolate1.
+ * Isolate1 then sends the result back to the main isolate for final checking.
+ */
+
+void crossIsolate1(SendPort mainIsolate) {
+  ReceivePort local = new ReceivePort();
+  mainIsolate.send(["ready1", local.sendPort]);
+  local.first.then((msg) {
+    // Message from crossIsolate2
+    expect(msg[0], "fromIsolate2");
+    mainIsolate.send(["fromIsolate1", msg[1] + 58]);  // 100.
   });
 }
 
-// crossIsolate2 is nearly the same as crossIsolate1, but contains a
-// different constant.
-void crossIsolate2() {
-  port.receive((msg, replyTo) {
-    SendPort mainIsolate = msg;
-    ReceivePort receivePort = new ReceivePort();
-    receivePort.receive((msg, replyTo) {
-      mainIsolate.send(msg + 399, null); // 499.
-      receivePort.close();
-    });
-    replyTo.send(['ready', receivePort.toSendPort()]);
-    port.close();
-  });
+void crossIsolate2(SendPort toIsolate1) {
+  toIsolate1.send(["fromIsolate2", 42]);
 }
 
 main() {
-  test("share port, and send message cross isolates ", () {
-    SendPort port1 = spawnFunction(crossIsolate1);
-    SendPort port2 = spawnFunction(crossIsolate2);
-    // Create a new receive port and send it to isolate2.
-    ReceivePort myPort = new ReceivePort();
-    port2.call(myPort.toSendPort()).then(expectAsync1((msg) {
-      expect(msg[0], "ready");
-      // Send port of isolate2 to isolate1.
-      port1.call(msg[1]).then(expectAsync1((msg) {
-        expect(msg[0], "ready");
-        myPort.receive(expectAsync2((msg, replyTo) {
-          expect(msg, 499);
-          myPort.close();
-        }));
-        msg[1].send(42, null);
-      }));
-    }));
+  test("send message cross isolates ", () {
+    ReceivePort fromIsolate1 = new ReceivePort();
+    Isolate.spawn(crossIsolate1, fromIsolate1.sendPort);
+    var done = expectAsync0((){});
+    fromIsolate1.listen((msg) {
+      switch (msg[0]) {
+        case "ready1":
+          SendPort toIsolate1 = msg[1];
+          Isolate.spawn(crossIsolate2, toIsolate1);
+          break;
+        case "fromIsolate1":
+          expect(msg[1], 100);
+          fromIsolate1.close();
+          break;
+        default:
+          fail("unreachable! Tag: ${msg[0]}");
+      }
+    }, onDone: done);
   });
 }
diff --git a/tests/isolate/global_error_handler2_test.dart b/tests/isolate/global_error_handler2_test.dart
deleted file mode 100644
index a71d595..0000000
--- a/tests/isolate/global_error_handler2_test.dart
+++ /dev/null
@@ -1,45 +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.
-
-library test;
-
-import 'package:expect/expect.dart';
-import 'dart:async';
-import 'dart:isolate';
-import "package:async_helper/async_helper.dart";
-
-runTest() {
-  SendPort mainIsolate;
-  bool isFirst = true;
-  port.receive((msg, replyTo) {
-    if (isFirst) {
-      mainIsolate = msg;
-      isFirst = false;
-      throw new UnsupportedError("ignore exception");
-    }
-    Expect.equals("message 2", msg);
-    mainIsolate.send("received");
-  });
-}
-
-bool globalErrorHandler(IsolateUnhandledException e) {
-  return e.source is UnsupportedError && e.source.message == "ignore exception";
-}
-
-main() {
-  // Make sure this test doesn't last longer than 2 seconds.
-  var timer = new Timer(const Duration(seconds: 2), () { throw "failed"; });
-
-  var port = new ReceivePort();
-  SendPort otherIsolate = spawnFunction(runTest, globalErrorHandler);
-  otherIsolate.send(port.toSendPort());
-  otherIsolate.send("message 2");
-  asyncStart();
-  port.receive((msg, replyPort) {
-    Expect.equals("received", msg);
-    port.close();
-    timer.cancel();
-    asyncEnd();
-  });
-}
diff --git a/tests/isolate/global_error_handler_stream2_test.dart b/tests/isolate/global_error_handler_stream2_test.dart
deleted file mode 100644
index 8a1aa5f..0000000
--- a/tests/isolate/global_error_handler_stream2_test.dart
+++ /dev/null
@@ -1,53 +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.
-
-library test;
-
-import 'package:expect/expect.dart';
-import 'dart:async';
-import 'dart:isolate';
-import "package:async_helper/async_helper.dart";
-
-runTest() {
-  IsolateSink mainIsolate;
-  stream.listen((msg) {
-    mainIsolate = msg;
-    throw new UnsupportedError("ignore exception");
-  }, onDone: () {
-    mainIsolate.add("received done");
-    mainIsolate.close();
-  });
-}
-
-bool globalErrorHandler(IsolateUnhandledException e) {
-  var source = e.source;
-  return source is UnsupportedError && source.message == "ignore exception";
-}
-
-main() {
-  var keepRunningBox = new MessageBox();
-  // Make sure this test doesn't last longer than 2 seconds.
-  var timer = new Timer(const Duration(seconds: 2), () { throw "failed"; });
-
-  var box = new MessageBox();
-  IsolateSink otherIsolate = streamSpawnFunction(runTest, globalErrorHandler);
-  otherIsolate.add(box.sink);
-  // The previous event should have been handled entirely, but the current
-  // implementations don't guarantee that and might mix the done event with
-  // the handling of the previous event. We therefore delay the closing.
-  // Note: if the done is sent too early it won't lead to failing tests, but
-  // just won't make sure that the globalErrorHandler works.
-  asyncStart();
-  new Timer(const Duration(milliseconds: 10), () {
-    otherIsolate.close();
-    asyncEnd();
-  });
-  asyncStart();
-  box.stream.single.then((msg) {
-    Expect.equals("received done", msg);
-    timer.cancel();
-    keepRunningBox.stream.close();
-    asyncEnd();
-  });
-}
diff --git a/tests/isolate/global_error_handler_stream_test.dart b/tests/isolate/global_error_handler_stream_test.dart
deleted file mode 100644
index c1d8ce8..0000000
--- a/tests/isolate/global_error_handler_stream_test.dart
+++ /dev/null
@@ -1,47 +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.
-
-library test;
-
-import 'dart:async';
-import 'dart:isolate';
-
-var firstFunction;
-var finishFunction;
-
-void runFunctions() {
-  try {
-    firstFunction();
-  } catch (e) {
-    new Timer(Duration.ZERO, finishFunction);
-    rethrow;
-  }
-}
-
-void startTest(EventSink finishSink) {
-  firstFunction = () { throw new UnsupportedError("ignore exception"); };
-  finishFunction = () { finishSink.add("done"); finishSink.close(); };
-  new Timer(Duration.ZERO, runFunctions);
-}
-
-runTest() {
-  stream.single.then(startTest);
-}
-
-bool globalErrorHandler(IsolateUnhandledException e) {
-  return e.source is UnsupportedError && e.source.message == "ignore exception";
-}
-
-main() {
-  var box = new MessageBox();
-  var timer;
-  EventSink otherIsolate = streamSpawnFunction(runTest, globalErrorHandler);
-  otherIsolate.add(box.sink);
-  otherIsolate.close();
-  box.stream.single.then((msg) {
-    box.stream.close();
-    timer.cancel();
-  });
-  timer = new Timer(const Duration(seconds: 2), () { throw "failed"; });
-}
diff --git a/tests/isolate/global_error_handler_test.dart b/tests/isolate/global_error_handler_test.dart
deleted file mode 100644
index aa5ba92..0000000
--- a/tests/isolate/global_error_handler_test.dart
+++ /dev/null
@@ -1,43 +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.
-
-library test;
-
-import 'dart:async';
-import 'dart:isolate';
-
-var firstFunction;
-var finishFunction;
-
-void runFunctions() {
-  try {
-    firstFunction();
-  } catch (e) {
-    new Timer(Duration.ZERO, finishFunction);
-    rethrow;
-  }
-}
-
-void startTest(SendPort finishPort, replyPort) {
-  firstFunction = () { throw new UnsupportedError("ignore exception"); };
-  finishFunction = () { finishPort.send("done"); };
-  new Timer(Duration.ZERO, runFunctions);
-}
-
-runTest() {
-  port.receive(startTest);
-}
-
-bool globalErrorHandler(IsolateUnhandledException e) {
-  return e.source is UnsupportedError && e.source.message == "ignore exception";
-}
-
-main() {
-  var port = new ReceivePort();
-  var timer;
-  SendPort otherIsolate = spawnFunction(runTest, globalErrorHandler);
-  otherIsolate.send(port.toSendPort());
-  port.receive((msg, replyPort) { port.close(); timer.cancel(); });
-  timer = new Timer(const Duration(seconds: 2), () { throw "failed"; });
-}
diff --git a/tests/isolate/illegal_msg_stream_test.dart b/tests/isolate/illegal_msg_stream_test.dart
deleted file mode 100644
index 5f80065..0000000
--- a/tests/isolate/illegal_msg_stream_test.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test;
-
-import 'package:expect/expect.dart';
-import 'dart:isolate';
-import "package:async_helper/async_helper.dart";
-
-funcFoo(x) => x + 2;
-
-foo() {
-  stream.single.then((msg) {
-    IsolateSink sink = msg;
-    sink.add(499);
-    sink.close();
-  });
-}
-
-main() {
-  var box = new MessageBox();
-  var snd = streamSpawnFunction(foo);
-  var caught_exception = false;
-  try {
-    snd.add(funcFoo);
-  } catch (e) {
-    caught_exception = true;
-  }
-  snd.add(box.sink);
-  snd.close();
-
-  asyncStart();
-  box.stream.single.then((msg) {
-    Expect.equals(499, msg);
-    asyncEnd();
-  });
-}
diff --git a/tests/isolate/illegal_msg_test.dart b/tests/isolate/illegal_msg_test.dart
index ed29bd9..422ae39 100644
--- a/tests/isolate/illegal_msg_test.dart
+++ b/tests/isolate/illegal_msg_test.dart
@@ -9,29 +9,37 @@
 
 funcFoo(x) => x + 2;
 
-echo() {
-  port.receive((msg, reply) {
-    reply.send("echoing ${msg(1)}}");
+echo(sendPort) {
+  var port = new ReceivePort();
+  sendPort.send(port.sendPort);
+  port.listen((msg) {
+    sendPort.send("echoing ${msg(1)}}");
   });
 }
 
 main() {
-  var snd = spawnFunction(echo);
+  ReceivePort port = new ReceivePort();
+  Future spawn = Isolate.spawn(echo, port.sendPort);
   var caught_exception = false;
-  try {
-    snd.send(funcFoo, port.toSendPort());
-  } catch (e) {
-    caught_exception = true;
-  }
+  var stream = port.asBroadcastStream();
+  asyncStart();
+  stream.first.then((snd) {
+    try {
+      snd.send(funcFoo);
+    } catch (e) {
+      caught_exception = true;
+    }
 
-  if (caught_exception) {
-    port.close();
-  } else {
-    asyncStart();
-    port.receive((msg, reply) {
-      print("from worker ${msg}");
-      asyncEnd();
-    });
-  }
-  Expect.isTrue(caught_exception);
+    if (caught_exception) {
+      port.close();
+    } else {
+      asyncStart();
+      stream.first.then((msg) {
+        print("from worker ${msg}");
+        asyncEnd();
+      });
+    }
+    Expect.isTrue(caught_exception);
+    asyncEnd();
+  });
 }
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 70a991d..d7e85a6 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -14,31 +14,26 @@
 [ $analyzer ]
 isolate2_negative_test: Fail
 isolate_negative_test: Fail
+isolate_import_negative_test: Fail
 spawn_function_negative_test: Fail
 spawn_uri_vm_negative_test: Fail
 unresolved_ports_negative_test: Fail
+mandel_isolate_test: Fail # issue 14452
 
 [ $compiler == dart2js && $jscl ]
 browser/*: SkipByDesign  # Browser specific tests
-illegal_msg_stream_test: RuntimeError # Issue 6750
-
-[ $compiler == dart2js && $browser ]
-illegal_msg_stream_test: Fail, Pass # Issue 6750
 
 [ $compiler == dart2js && $runtime == drt ]
 unresolved_ports_negative_test: Pass, Crash # Issue 10613
+isolate_stress_test: Pass, Crash # Issue 14438
 
 [ $compiler == dart2js ]
 serialization_test: RuntimeError # Issue 1882, tries to access class TestingOnly declared in isolate_patch.dart
-illegal_msg_test: RuntimeError # Issue 6750
-stream_mangling_test: RuntimeError # Issue 9245
 
 global_error_handler_test: Pass, RuntimeError # Issue 9012, Issue 9024
-global_error_handler_stream_test: Pass, RuntimeError # Issue 9012, Issue 9024
 global_error_handler2_test: Pass, RuntimeError # Issue 9012, Issue 9024
-global_error_handler_stream2_test: Pass, RuntimeError # Issue 9012, Issue 9024
 
-[ $compiler == dart2js && ($runtime == drt || $runtime == ff || $runtime == chrome || $runtime == chromeOnAndroid || $runtime == ie9 || $runtime == ie10 || $runtime == safari) ]
+[ $compiler == dart2js && $runtime == ie9 ]
 browser/typed_data_message_test: Fail # Issue 12624
 
 [ $compiler == dart2js && $runtime == safari ]
@@ -66,7 +61,6 @@
 [ $compiler == dart2js && $runtime == none ]
 spawn_function_negative_test: Fail # Issue 12628
 unresolved_ports_negative_test: Fail # Issue 12628
-stream_mangling_test: Pass # Issue 12628
 isolate_negative_test: Fail # Issue 12628
 serialization_test: Pass # Issue 12628
 isolate_import_negative_test: Fail # Issue 12628
@@ -75,7 +69,6 @@
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 isolate_stress_test: Pass, Slow # TODO(kasperl): Please triage.
-mandel_isolate_stream_test: Pass, Slow # TODO(kasperl): Please triage.
 
 mandel_isolate_test: Pass, Timeout # TODO(kasperl): Please triage.
 
@@ -84,15 +77,14 @@
 
 [ $compiler == dart2js && $runtime == ff && ($system == windows || $system == linux) ]
 mandel_isolate_test: Pass, Fail, Timeout # Issue 7952
-mandel_isolate_stream_test: Pass, Fail, Timeout # Issue 7952
 
 [ $compiler == dart2js && ( $runtime == ff || $runtime == safari || $runtime == drt || $runtime == chrome ) ]
 isolate_stress_test: Pass, Slow # Issue 10697
+isolate_stress_test: Timeout # Issue 14461
 
 [ $compiler == none && $runtime == drt ]
-isolate_stress_test: Skip # Issue 12537
-nested_spawn_stream2_test: Fail # Issue 13433
-cross_isolate_message_stream_test: Fail # Issue 13433
+isolate_stress_test: Skip # Issue 14463
+spawn_uri_nested_vm_test: Skip # Issue 14463
 
 [ $csp ]
 spawn_uri_multi_test/none: Fail # http://dartbug.com/13454
@@ -102,37 +94,25 @@
 spawn_uri_multi_test/none: RuntimeError # http://dartbug.com/13544
 
 [ $compiler == none && $runtime == dartium ]
-cross_isolate_message_stream_test: Fail # Issue 13719: Please triage this failure.
 global_error_handler2_test: Fail # Issue 13719: Please triage this failure.
-global_error_handler_stream2_test: Fail # Issue 13719: Please triage this failure.
-nested_spawn_stream2_test: Fail # Issue 13719: Please triage this failure.
+spawn_uri_nested_vm_test: Skip # Issue 14479: This test is timing out.
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 # Issue 13921: spawnFunction is not allowed on Dartium's DOM thread.
-browser/compute_this_script_browser_stream_test: Fail
 browser/compute_this_script_browser_test: Fail
 browser/typed_data_message_test: Skip # 13961
-count_stream_test: Fail
 count_test: Fail
 cross_isolate_message_test: Fail
 global_error_handler2_test: Fail
-global_error_handler_stream2_test: Fail
-global_error_handler_stream_test: Fail
 global_error_handler_test: Fail
-illegal_msg_stream_test: Fail
 illegal_msg_test: Fail
-isolate_complex_messages_stream_test: Fail
 isolate_complex_messages_test: Fail
 isolate_stress_test: Fail
-mandel_isolate_stream_test: Fail
 mandel_isolate_test: Fail
 message2_test: Fail
-message_stream2_test: Fail
-message_stream_test: Fail
 message_test: Fail
 mint_maker_test: Fail
 nested_spawn2_test: Fail
-nested_spawn_stream_test: Fail
 nested_spawn_test: Fail
 request_reply_test: Fail
 spawn_function_custom_class_test: Fail
diff --git a/tests/isolate/isolate2_negative_test.dart b/tests/isolate/isolate2_negative_test.dart
index 49ccb2e..03fdb3c 100644
--- a/tests/isolate/isolate2_negative_test.dart
+++ b/tests/isolate/isolate2_negative_test.dart
@@ -9,7 +9,7 @@
 import 'dart:isolate';
 import "package:async_helper/async_helper.dart";
 
-void entry() {
+void entry(msg) {
   throw "foo";
 }
 
@@ -18,5 +18,5 @@
   // anything back except an exception there is no asyncEnd().
   // If the exception is not thrown this test will timeout.
   asyncStart();
-  SendPort port = spawnFunction(entry);
+  Isolate.spawn(entry);
 }
diff --git a/tests/isolate/isolate3_negative_test.dart b/tests/isolate/isolate3_negative_test.dart
index 59510eb..ed46f27 100644
--- a/tests/isolate/isolate3_negative_test.dart
+++ b/tests/isolate/isolate3_negative_test.dart
@@ -17,11 +17,9 @@
   num fld2;
 }
 
-void entry() {
-  port.receive((ignored, replyTo) {
-    var tmp = new TestClass.named(10);
-    replyTo.send(tmp, null);
-  });
+void entry(SendPort replyTo) {
+  var tmp = new TestClass.named(10);
+  replyTo.send(tmp);
 }
 
 main() {
@@ -29,7 +27,8 @@
     void msg_callback(var message) {
       // This test is a negative test and should not complete successfully.
     }
-    SendPort port = spawnFunction(entry);
-    port.call("foo").then(expectAsync1(msg_callback));
+    ReceivePort response = new ReceivePort();
+    Isolate.spawn(entry, response.sendPort);
+    response.first.then(expectAsync1(msg_callback));
   });
 }
diff --git a/tests/isolate/isolate_complex_messages_stream_test.dart b/tests/isolate/isolate_complex_messages_stream_test.dart
deleted file mode 100644
index 219b289..0000000
--- a/tests/isolate/isolate_complex_messages_stream_test.dart
+++ /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.
-
-// Dart test program for testing isolate communication with
-// complex messages.
-
-library IsolateComplexMessagesTest;
-import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
-
-main() {
-  test("complex messages are serialized correctly", () {
-    var box = new MessageBox();
-    IsolateSink remote = streamSpawnFunction(logMessages);
-    remote.add(1);
-    remote.add("Hello");
-    remote.add("World");
-    remote.add(const [null, 1, 2, 3, 4]);
-    remote.add(const [1, 2.0, true, false, 0xffffffffff]);
-    remote.add(const ["Hello", "World", 0xffffffffff]);
-    remote.add(box.sink);
-    remote.close();
-    box.stream.single.then((message) {
-      expect(message, 7);
-    });
-  });
-}
-
-
-void logMessages() {
-  int count = 0;
-  IsolateSink replySink;
-
-  stream.listen((message) {
-    switch (count) {
-      case 0:
-        expect(message, 1);
-        break;
-      case 1:
-        expect(message, "Hello");
-        break;
-      case 2:
-        expect(message, "World");
-        break;
-      case 3:
-        expect(message.length, 5);
-        expect(message[0], null);
-        expect(message[1], 1);
-        expect(message[2], 2);
-        expect(message[3], 3);
-        expect(message[4], 4);
-        break;
-      case 4:
-        expect(message.length, 5);
-        expect(message[0], 1);
-        expect(message[1], 2.0);
-        expect(message[2], true);
-        expect(message[3], false);
-        expect(message[4], 0xffffffffff);
-        break;
-      case 5:
-        expect(message.length, 3);
-        expect(message[0], "Hello");
-        expect(message[1], "World");
-        expect(message[2], 0xffffffffff);
-        break;
-      case 6:
-        replySink = message;
-        break;
-    }
-    count++;
-  },
-  onDone: () {
-    replySink.add(count);
-    replySink.close();
-  });
-}
diff --git a/tests/isolate/isolate_complex_messages_test.dart b/tests/isolate/isolate_complex_messages_test.dart
index e4fae99..effeffe 100644
--- a/tests/isolate/isolate_complex_messages_test.dart
+++ b/tests/isolate/isolate_complex_messages_test.dart
@@ -11,28 +11,40 @@
 
 main() {
   test("complex messages are serialized correctly", () {
-    SendPort remote = spawnFunction(logMessages);
-    remote.send(1, null);
-    remote.send("Hello", null);
-    remote.send("World", null);
-    remote.send(const [null, 1, 2, 3, 4], null);
-    remote.send(const [1, 2.0, true, false, 0xffffffffff], null);
-    remote.send(const ["Hello", "World", 0xffffffffff], null);
-    // Shutdown the LogRunner.
-    remote.call(-1).then(expectAsync1((int message) {
-      expect(message, 6);
-    }));
+    ReceivePort local = new ReceivePort();
+    Isolate.spawn(logMessages, local.sendPort);
+    var done = expectAsync0((){});
+    local.listen(expectAsync1((msg) {
+      switch (msg[0]) {
+        case "init":
+          var remote = msg[1];
+          remote.send(1, null);
+          remote.send("Hello", null);
+          remote.send("World", null);
+          remote.send(const [null, 1, 2, 3, 4], null);
+          remote.send(const [1, 2.0, true, false, 0xffffffffff], null);
+          remote.send(const ["Hello", "World", 0xffffffffff], null);
+          // Shutdown the LogRunner.
+          remote.send(-1);
+          break;
+        case "done":
+          local.close();
+          expect(msg[1], 6);
+          done();
+      }
+    }, count: 2));
   });
 }
 
 
-void logMessages() {
+void logMessages(mainPort) {
   int count = 0;
-
-  port.receive((var message, SendPort replyTo) {
+  ReceivePort port = new ReceivePort();
+  mainPort.send(["init", port.sendPort]);
+  port.listen((var message) {
     if (message == -1) {
       port.close();
-      replyTo.send(count, null);
+      mainPort.send(["done", count]);
     } else {
       switch (count) {
         case 0:
diff --git a/tests/isolate/isolate_import_negative_test.dart b/tests/isolate/isolate_import_negative_test.dart
index 0f5a042..1ea9102 100644
--- a/tests/isolate/isolate_import_negative_test.dart
+++ b/tests/isolate/isolate_import_negative_test.dart
@@ -6,9 +6,9 @@
 // Omitting the following import is an error:
 // import 'dart:isolate';
 
-void entry() {}
+void entry(msg) {}
 
 main() {
-  spawnFunction(entry);
+  Isolate.spawn(entry);
 }
 
diff --git a/tests/isolate/isolate_negative_test.dart b/tests/isolate/isolate_negative_test.dart
index 7f753f2..e40d23e 100644
--- a/tests/isolate/isolate_negative_test.dart
+++ b/tests/isolate/isolate_negative_test.dart
@@ -9,16 +9,15 @@
 import 'dart:isolate';
 import '../../pkg/unittest/lib/unittest.dart';
 
-void entry() {
-  port.receive((ignored, replyTo) {
-    replyTo.send("foo", null);
-  });
+void entry(SendPort replyTo) {
+  replyTo.send("foo");
 }
 
 main() {
   test("ensure isolate code is executed", () {
-    SendPort port = spawnFunction(entry);
-    port.call("foo").then(expectAsync1((message) {
+    ReceivePort response = new ReceivePort();
+    Isolate.spawn(entry, response.sendPort);
+    response.first.then(expectAsync1((message) {
       expect("Expected fail", isTrue);   // <=-------- Should fail here.
     }));
   });
diff --git a/tests/isolate/isolate_stress_test.dart b/tests/isolate/isolate_stress_test.dart
index f00e457..8a76b02 100644
--- a/tests/isolate/isolate_stress_test.dart
+++ b/tests/isolate/isolate_stress_test.dart
@@ -12,11 +12,8 @@
 // TODO(12588): Remove this import when we have wrapper-less testing.
 import 'dart:html';
 
-worker() {
-  port.receive((String uri, SendPort replyTo) {
-    replyTo.send('Hello from Worker');
-    port.close();
-  });
+worker(SendPort replyTo) {
+  replyTo.send('Hello from Worker');
 }
 
 main() {
@@ -33,11 +30,12 @@
       throw new Exception('Unexpected reply from worker: $reply');
     }
     if (++isolateCount > 200) {
-      port.close();
       window.postMessage('unittest-suite-success', '*');
       return;
     }
-    spawnFunction(worker).call('').then(spawnMany);
+    ReceivePort response = new ReceivePort();
+    var remote = Isolate.spawn(worker, response.sendPort);
+    remote.then((_) => response.first).then(spawnMany);
     print('isolateCount = $isolateCount');
   }
 
diff --git a/tests/isolate/mandel_isolate_stream_test.dart b/tests/isolate/mandel_isolate_stream_test.dart
deleted file mode 100644
index ffe3c9a..0000000
--- a/tests/isolate/mandel_isolate_stream_test.dart
+++ /dev/null
@@ -1,155 +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 MandelIsolateTest;
-import 'dart:async';
-import 'dart:isolate';
-import 'dart:math';
-import '../../pkg/unittest/lib/unittest.dart';
-
-const TERMINATION_MESSAGE = -1;
-const N = 100;
-const ISOLATES = 20;
-
-main() {
-  // Test is really slow in debug builds of the VM.
-  unittestConfiguration.timeout = const Duration(seconds: 480);
-  test("Render Mandelbrot in parallel", () {
-    final state = new MandelbrotState();
-    state._validated.future.then(expectAsync1((result) {
-      expect(result, isTrue);
-    }));
-    for (int i = 0; i < min(ISOLATES, N); i++) state.startClient(i);
-  });
-}
-
-
-class MandelbrotState {
-
-  MandelbrotState() {
-    _result = new List<List<int>>(N);
-    _lineProcessedBy = new List<LineProcessorClient>(N);
-    _sent = 0;
-    _missing = N;
-    _validated = new Completer<bool>();
-  }
-
-  void startClient(int id) {
-    assert(_sent < N);
-    final client = new LineProcessorClient(this, id);
-    client.processLine(_sent++);
-  }
-
-  void notifyProcessedLine(LineProcessorClient client, int y, List<int> line) {
-    assert(_result[y] == null);
-    _result[y] = line;
-    _lineProcessedBy[y] = client;
-
-    if (_sent != N) {
-      client.processLine(_sent++);
-    } else {
-      client.shutdown();
-    }
-
-    // If all lines have been computed, validate the result.
-    if (--_missing == 0) {
-      _printResult();
-      _validateResult();
-    }
-  }
-
-  void _validateResult() {
-    // TODO(ngeoffray): Implement this.
-    _validated.complete(true);
-  }
-
-  void _printResult() {
-    var output = new StringBuffer();
-    for (int i = 0; i < _result.length; i++) {
-      List<int> line = _result[i];
-      for (int j = 0; j < line.length; j++) {
-        if (line[j] < 10) output.write("0");
-        output.write(line[j]);
-      }
-      output.write("\n");
-    }
-    // print(output);
-  }
-
-  List<List<int>> _result;
-  List<LineProcessorClient> _lineProcessedBy;
-  int _sent;
-  int _missing;
-  Completer<bool> _validated;
-}
-
-
-class LineProcessorClient {
-
-  LineProcessorClient(MandelbrotState this._state, int this._id) {
-    _sink = streamSpawnFunction(processLines);
-    _box = new MessageBox();
-    _sink.add(_box.sink);
-    _box.stream.listen((List<int> message) {
-      _state.notifyProcessedLine(this, _currentLine, message);
-    });
-  }
-
-  void processLine(int y) {
-    _currentLine = y;
-    _sink.add(y);
-  }
-
-  void shutdown() {
-    _sink.close();
-    _box.stream.close();
-  }
-
-  MandelbrotState _state;
-  int _id;
-  IsolateSink _sink;
-  int _currentLine;
-  MessageBox _box;
-}
-
-List<int> processLine(int y) {
-  double inverseN = 2.0 / N;
-  double Civ = y * inverseN - 1.0;
-  List<int> result = new List<int>(N);
-  for (int x = 0; x < N; x++) {
-    double Crv = x * inverseN - 1.5;
-
-    double Zrv = Crv;
-    double Ziv = Civ;
-
-    double Trv = Crv * Crv;
-    double Tiv = Civ * Civ;
-
-    int i = 49;
-    do {
-      Ziv = (Zrv * Ziv) + (Zrv * Ziv) + Civ;
-      Zrv = Trv - Tiv + Crv;
-
-      Trv = Zrv * Zrv;
-      Tiv = Ziv * Ziv;
-    } while (((Trv + Tiv) <= 4.0) && (--i > 0));
-
-    result[x] = i;
-  }
-  return result;
-}
-
-void processLines() {
-  bool isFirst = true;
-  IsolateSink replyTo;
-
-  stream.listen((message) {
-    if (isFirst) {
-      isFirst = false;
-      replyTo = message;
-      return;
-    }
-    replyTo.add(processLine(message));
-  });
-}
diff --git a/tests/isolate/mandel_isolate_test.dart b/tests/isolate/mandel_isolate_test.dart
index 9e3e14f..241ff29 100644
--- a/tests/isolate/mandel_isolate_test.dart
+++ b/tests/isolate/mandel_isolate_test.dart
@@ -37,8 +37,10 @@
 
   void startClient(int id) {
     assert(_sent < N);
-    final client = new LineProcessorClient(this, id);
-    client.processLine(_sent++);
+    int line = _sent++;
+    LineProcessorClient.create(this, id).then((final client) {
+      client.processLine(line);
+    });
   }
 
   void notifyProcessedLine(LineProcessorClient client, int y, List<int> line) {
@@ -86,24 +88,32 @@
 
 
 class LineProcessorClient {
+  MandelbrotState _state;
+  int _id;
+  SendPort _port;
 
-  LineProcessorClient(MandelbrotState this._state, int this._id) {
-    _port = spawnFunction(processLines);
+  LineProcessorClient(this._state, this._id, this._port);
+
+  static Future<LineProcessorClient> create(MandelbrotState state, int id) {
+    ReceivePort reply = new ReceivePort();
+    return Isolate.spawn(processLines, reply.sendPort).then((_) {
+      return reply.first.then((port) {
+        return new LineProcessorClient(state, id, port);
+      });
+    });
   }
 
   void processLine(int y) {
-    _port.call(y).then((List<int> message) {
+    ReceivePort reply = new ReceivePort();
+    _port.send([y, reply.sendPort]);
+    reply.first.then((List<int> message) {
       _state.notifyProcessedLine(this, y, message);
     });
   }
 
   void shutdown() {
-    _port.send(TERMINATION_MESSAGE, null);
+    _port.send(TERMINATION_MESSAGE);
   }
-
-  MandelbrotState _state;
-  int _id;
-  SendPort _port;
 }
 
 List<int> processLine(int y) {
@@ -133,13 +143,16 @@
   return result;
 }
 
-void processLines() {
-  port.receive((message, SendPort replyTo) {
-    if (message == TERMINATION_MESSAGE) {
-      assert(replyTo == null);
-      port.close();
+void processLines(SendPort replyPort) {
+  ReceivePort port = new ReceivePort();
+  port.listen((message) {
+    if (message != TERMINATION_MESSAGE) {
+      int line = message[0];
+      SendPort replyTo = message[1];
+      replyTo.send(processLine(line));
     } else {
-      replyTo.send(processLine(message), null);
+      port.close();
     }
   });
+  replyPort.send(port.sendPort);
 }
diff --git a/tests/isolate/message2_test.dart b/tests/isolate/message2_test.dart
index 07b34e6..334ae04 100644
--- a/tests/isolate/message2_test.dart
+++ b/tests/isolate/message2_test.dart
@@ -41,29 +41,36 @@
   }
 }
 
-void pingPong() {
-  port.receive((var message, SendPort replyTo) {
-    if (message == -1) {
+void pingPong(replyPort) {
+  ReceivePort port = new ReceivePort();
+  port.listen((message) {
+    if (message == null) {
       port.close();
     } else {
       // Bounce the received object back so that the sender
       // can make sure that the object matches.
-      replyTo.send(message, null);
+      message[1].send(message[0]);
     }
   });
+  replyPort.send(port.sendPort);
 }
 
 main() {
   test("map is equal after it is sent back and forth", () {
-    SendPort remote = spawnFunction(pingPong);
-    Map m = new Map();
-    m[1] = "eins";
-    m[2] = "deux";
-    m[3] = "tre";
-    m[4] = "four";
-    remote.call(m).then(expectAsync1((var received) {
-      MessageTest.mapEqualsDeep(m, received);
-      remote.send(-1, null);
+    ReceivePort port = new ReceivePort();
+    Isolate.spawn(pingPong, port.sendPort);
+    port.first.then(expectAsync1((remote) {
+      Map m = new Map();
+      m[1] = "eins";
+      m[2] = "deux";
+      m[3] = "tre";
+      m[4] = "four";
+      ReceivePort replyPort = new ReceivePort();
+      remote.send([m, replyPort.sendPort]);
+      replyPort.first.then(expectAsync1((var received) {
+        MessageTest.mapEqualsDeep(m, received);
+        remote.send(null);
+      }));
     }));
   });
 }
diff --git a/tests/isolate/message_stream2_test.dart b/tests/isolate/message_stream2_test.dart
deleted file mode 100644
index c9a6a67..0000000
--- a/tests/isolate/message_stream2_test.dart
+++ /dev/null
@@ -1,76 +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.
-
-// Dart test program for testing serialization of messages.
-// VMOptions=--enable_type_checks --enable_asserts
-
-library Message2Test;
-import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
-
-// ---------------------------------------------------------------------------
-// Message passing test 2.
-// ---------------------------------------------------------------------------
-
-class MessageTest {
-  static void mapEqualsDeep(Map expected, Map actual) {
-    expect(expected, isMap);
-    expect(actual, isMap);
-    expect(actual.length, expected.length);
-    testForEachMap(key, value) {
-      if (value is List) {
-        listEqualsDeep(value, actual[key]);
-      } else {
-        expect(actual[key], value);
-      }
-    }
-    expected.forEach(testForEachMap);
-  }
-
-  static void listEqualsDeep(List expected, List actual) {
-    for (int i = 0; i < expected.length; i++) {
-      if (expected[i] is List) {
-        listEqualsDeep(expected[i], actual[i]);
-      } else if (expected[i] is Map) {
-        mapEqualsDeep(expected[i], actual[i]);
-      } else {
-        expect(actual[i], expected[i]);
-      }
-    }
-  }
-}
-
-void pingPong() {
-  bool isFirst = true;
-  IsolateSink replyTo;
-  stream.listen((var message) {
-    if (isFirst) {
-      isFirst = false;
-      replyTo = message;
-      return;
-    }
-    // Bounce the received object back so that the sender
-    // can make sure that the object matches.
-    replyTo.add(message);
-  });
-}
-
-main() {
-  test("map is equal after it is sent back and forth", () {
-    IsolateSink remote = streamSpawnFunction(pingPong);
-    Map m = new Map();
-    m[1] = "eins";
-    m[2] = "deux";
-    m[3] = "tre";
-    m[4] = "four";
-    MessageBox box = new MessageBox();
-    remote.add(box.sink);
-    remote.add(m);
-    box.stream.listen(expectAsync1((var received) {
-      MessageTest.mapEqualsDeep(m, received);
-      remote.close();
-      box.stream.close();
-    }));
-  });
-}
diff --git a/tests/isolate/message_stream_test.dart b/tests/isolate/message_stream_test.dart
deleted file mode 100644
index bfd7d4c..0000000
--- a/tests/isolate/message_stream_test.dart
+++ /dev/null
@@ -1,144 +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.
-
-// Dart test program for testing serialization of messages.
-// VMOptions=--enable_type_checks --enable_asserts
-
-library MessageTest;
-import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
-
-// ---------------------------------------------------------------------------
-// Message passing test.
-// ---------------------------------------------------------------------------
-
-class MessageTest {
-  static const List list1 = const ["Hello", "World", "Hello", 0xfffffffffff];
-  static const List list2 = const [null, list1, list1, list1, list1];
-  static const List list3 = const [list2, 2.0, true, false, 0xfffffffffff];
-  static const Map map1 = const {
-    "a=1" : 1, "b=2" : 2, "c=3" : 3,
-  };
-  static const Map map2 = const {
-    "list1" : list1, "list2" : list2, "list3" : list3,
-  };
-  static const List list4 = const [map1, map2];
-  static const List elms = const [
-      list1, list2, list3, list4,
-  ];
-
-  static void VerifyMap(Map expected, Map actual) {
-    expect(expected, isMap);
-    expect(actual,  isMap);
-    expect(actual.length, expected.length);
-    testForEachMap(key, value) {
-      if (value is List) {
-        VerifyList(value, actual[key]);
-      } else {
-        expect(actual[key], value);
-      }
-    }
-    expected.forEach(testForEachMap);
-  }
-
-  static void VerifyList(List expected, List actual) {
-    for (int i = 0; i < expected.length; i++) {
-      if (expected[i] is List) {
-        VerifyList(expected[i], actual[i]);
-      } else if (expected[i] is Map) {
-        VerifyMap(expected[i], actual[i]);
-      } else {
-        expect(actual[i], expected[i]);
-      }
-    }
-  }
-
-  static void VerifyObject(int index, var actual) {
-    var expected = elms[index];
-    expect(expected, isList);
-    expect(actual, isList);
-    expect(actual.length, expected.length);
-    VerifyList(expected, actual);
-  }
-}
-
-pingPong() {
-  int count = 0;
-  bool isFirst = true;
-  IsolateSink replyTo;
-  stream.listen((var message) {
-    if (isFirst) {
-      isFirst = false;
-      replyTo = message;
-      return;
-    }
-    // Check if the received object is correct.
-    if (count < MessageTest.elms.length) {
-      MessageTest.VerifyObject(count, message);
-    }
-    // Bounce the received object back so that the sender
-    // can make sure that the object matches.
-    replyTo.add(message);
-    count++;
-  }, onDone: () {
-    replyTo.add(count);
-    replyTo.close();
-  });
-}
-
-main() {
-  test("send objects and receive them back", () {
-    IsolateSink remote = streamSpawnFunction(pingPong);
-    MessageBox box = new MessageBox();
-    remote.add(box.sink);
-
-    // Send objects and receive them back.
-    for (int i = 0; i < MessageTest.elms.length; i++) {
-      var sentObject = MessageTest.elms[i];
-      // TODO(asiva): remove this local var idx once thew new for-loop
-      // semantics for closures is implemented.
-      var idx = i;
-      remote.add(sentObject);
-    }
-
-    // Send recursive objects and receive them back.
-    List local_list1 = ["Hello", "World", "Hello", 0xffffffffff];
-    List local_list2 = [null, local_list1, local_list1 ];
-    List local_list3 = [local_list2, 2.0, true, false, 0xffffffffff];
-    List sendObject = new List(5);
-    sendObject[0] = local_list1;
-    sendObject[1] = sendObject;
-    sendObject[2] = local_list2;
-    sendObject[3] = sendObject;
-    sendObject[4] = local_list3;
-    remote.add(sendObject);
-
-    // Shutdown the MessageServer.
-    remote.close();
-
-    int receivedCounter = 0;
-    box.stream.listen((message) {
-      if (receivedCounter < MessageTest.elms.length) {
-        MessageTest.VerifyObject(receivedCounter, message);
-      } else if (receivedCounter == MessageTest.elms.length) {
-        var replyObject = message;
-        expect(sendObject, isList);
-        expect(replyObject, isList);
-        expect(sendObject.length, equals(replyObject.length));
-        expect(replyObject[1], same(replyObject));
-        expect(replyObject[3], same(replyObject));
-        expect(replyObject[0], same(replyObject[2][1]));
-        expect(replyObject[0], same(replyObject[2][2]));
-        expect(replyObject[2], same(replyObject[4][0]));
-        expect(replyObject[0][0], same(replyObject[0][2]));
-        // Bigint literals are not canonicalized so do a == check.
-        expect(replyObject[0][3], equals(replyObject[4][4]));
-      } else {
-        // Reply from done.
-        expect(message, MessageTest.elms.length + 1);
-      }
-      receivedCounter++;
-    });
-  });
-}
diff --git a/tests/isolate/message_test.dart b/tests/isolate/message_test.dart
index ee00de5..de252c5 100644
--- a/tests/isolate/message_test.dart
+++ b/tests/isolate/message_test.dart
@@ -7,6 +7,7 @@
 
 library MessageTest;
 import 'dart:isolate';
+import 'dart:async';
 import '../../pkg/unittest/lib/unittest.dart';
 
 // ---------------------------------------------------------------------------
@@ -63,12 +64,15 @@
   }
 }
 
-pingPong() {
+pingPong(replyTo) {
+  ReceivePort port = new ReceivePort();
   int count = 0;
-  port.receive((var message, SendPort replyTo) {
+  port.listen((pair) {
+    var message = pair[0];
+    var replyTo = pair[1];
     if (message == -1) {
       port.close();
-      replyTo.send(count, null);
+      replyTo.send(count);
     } else {
       // Check if the received object is correct.
       if (count < MessageTest.elms.length) {
@@ -76,53 +80,60 @@
       }
       // Bounce the received object back so that the sender
       // can make sure that the object matches.
-      replyTo.send(message, null);
+      replyTo.send(message);
       count++;
     }
   });
+  replyTo.send(port.sendPort);
+}
+
+Future remoteCall(SendPort port, message) {
+  ReceivePort receivePort = new ReceivePort();
+  port.send([message, receivePort.sendPort]);
+  return receivePort.first;
 }
 
 main() {
   test("send objects and receive them back", () {
-    SendPort remote = spawnFunction(pingPong);
-    // Send objects and receive them back.
-    for (int i = 0; i < MessageTest.elms.length; i++) {
-      var sentObject = MessageTest.elms[i];
-      // TODO(asiva): remove this local var idx once thew new for-loop
-      // semantics for closures is implemented.
-      var idx = i;
-      remote.call(sentObject).then(expectAsync1((var receivedObject) {
-        MessageTest.VerifyObject(idx, receivedObject);
-      }));
-    }
+    ReceivePort port = new ReceivePort();
+    Isolate.spawn(pingPong, port.sendPort);
+    port.first.then(expectAsync1((remote) {
+      // Send objects and receive them back.
+      for (int i = 0; i < MessageTest.elms.length; i++) {
+        var sentObject = MessageTest.elms[i];
+        remoteCall(remote, sentObject).then(expectAsync1((var receivedObject) {
+          MessageTest.VerifyObject(i, receivedObject);
+        }));
+      }
 
-    // Send recursive objects and receive them back.
-    List local_list1 = ["Hello", "World", "Hello", 0xffffffffff];
-    List local_list2 = [null, local_list1, local_list1 ];
-    List local_list3 = [local_list2, 2.0, true, false, 0xffffffffff];
-    List sendObject = new List(5);
-    sendObject[0] = local_list1;
-    sendObject[1] = sendObject;
-    sendObject[2] = local_list2;
-    sendObject[3] = sendObject;
-    sendObject[4] = local_list3;
-    remote.call(sendObject).then((var replyObject) {
-      expect(sendObject, isList);
-      expect(replyObject, isList);
-      expect(sendObject.length, equals(replyObject.length));
-      expect(replyObject[1], same(replyObject));
-      expect(replyObject[3], same(replyObject));
-      expect(replyObject[0], same(replyObject[2][1]));
-      expect(replyObject[0], same(replyObject[2][2]));
-      expect(replyObject[2], same(replyObject[4][0]));
-      expect(replyObject[0][0], same(replyObject[0][2]));
-      // Bigint literals are not canonicalized so do a == check.
-      expect(replyObject[0][3], equals(replyObject[4][4]));
-    });
+      // Send recursive objects and receive them back.
+      List local_list1 = ["Hello", "World", "Hello", 0xffffffffff];
+      List local_list2 = [null, local_list1, local_list1 ];
+      List local_list3 = [local_list2, 2.0, true, false, 0xffffffffff];
+      List sendObject = new List(5);
+      sendObject[0] = local_list1;
+      sendObject[1] = sendObject;
+      sendObject[2] = local_list2;
+      sendObject[3] = sendObject;
+      sendObject[4] = local_list3;
+      remoteCall(remote, sendObject).then((var replyObject) {
+        expect(sendObject, isList);
+        expect(replyObject, isList);
+        expect(sendObject.length, equals(replyObject.length));
+        expect(replyObject[1], same(replyObject));
+        expect(replyObject[3], same(replyObject));
+        expect(replyObject[0], same(replyObject[2][1]));
+        expect(replyObject[0], same(replyObject[2][2]));
+        expect(replyObject[2], same(replyObject[4][0]));
+        expect(replyObject[0][0], same(replyObject[0][2]));
+        // Bigint literals are not canonicalized so do a == check.
+        expect(replyObject[0][3], equals(replyObject[4][4]));
+      });
 
-    // Shutdown the MessageServer.
-    remote.call(-1).then(expectAsync1((int message) {
-        expect(message, MessageTest.elms.length + 1);
+      // Shutdown the MessageServer.
+      remoteCall(remote, -1).then(expectAsync1((int message) {
+          expect(message, MessageTest.elms.length + 1);
       }));
+    }));
   });
 }
diff --git a/tests/isolate/mint_maker_test.dart b/tests/isolate/mint_maker_test.dart
index 90ad058..457a42a 100644
--- a/tests/isolate/mint_maker_test.dart
+++ b/tests/isolate/mint_maker_test.dart
@@ -2,117 +2,84 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// Things that should be "auto-generated" are between AUTO START and
-// AUTO END (or just AUTO if it's a single line).
-
 library MintMakerTest;
 import 'dart:isolate';
 import '../../pkg/unittest/lib/unittest.dart';
 
 class Mint {
-  Mint() : registry_ = new Map<SendPort, Purse>() {
-    // AUTO START
+  Map<SendPort, Purse> _registry;
+  SendPort port;
+
+  Mint() : _registry = new Map<SendPort, Purse>() {
     ReceivePort mintPort = new ReceivePort();
-    port = mintPort.toSendPort();
+    port = mintPort.sendPort;
     serveMint(mintPort);
-    // AUTO END
   }
 
-  // AUTO START
   void serveMint(ReceivePort port) {
-    port.receive((var message, SendPort replyTo) {
-      int balance = message;
+    port.listen((message) {
+      int balance = message[0];
       Purse purse = createPurse(balance);
-      replyTo.send([ purse.port ], null);
+      message[1].send(purse.port);
     });
   }
-  // AUTO END
 
   Purse createPurse(int balance) {
     Purse purse = new Purse(this, balance);
-    registry_[purse.port] = purse;
+    _registry[purse.port] = purse;
     return purse;
   }
 
   Purse lookupPurse(SendPort port) {
-    return registry_[port];
+    return _registry[port];
   }
-
-  Map<SendPort, Purse> registry_;
-  // AUTO
-  SendPort port;
 }
 
 
-// AUTO START
 class MintWrapper {
-  MintWrapper(SendPort this.mint_) {}
+  SendPort _mint;
+  MintWrapper(SendPort this._mint) {}
 
   void createPurse(int balance, handlePurse(PurseWrapper purse)) {
-    mint_.call(balance).then((var message) {
-      SendPort purse = message[0];
+    ReceivePort reply = new ReceivePort();
+    reply.first.then((SendPort purse) {
       handlePurse(new PurseWrapper(purse));
     });
+    _mint.send([balance, reply.sendPort]);
   }
 
-  SendPort mint_;
 }
-// AUTO END
-
-
-/*
-One way this could look without the autogenerated code:
-
-class Mint {
-  Mint() : registry_ = new Map<SendPort, Purse>() {
-  }
-
-  wrap Purse createPurse(int balance) {
-    Purse purse = new Purse(this, balance);
-    registry_[purse.port] = purse;
-    return purse;
-  }
-
-  Purse lookupPurse(SendPort port) {
-    return registry_[port];
-  }
-
-  Map<SendPort, Purse> registry_;
-}
-
-The other end of the port would use Wrapper<Mint> as the wrapper, or
-Future<Mint> as a future for the wrapper.
-*/
-
 
 class Purse {
-  Purse(Mint this.mint, int this.balance) {
-    // AUTO START
+  Mint mint;
+  int balance;
+  SendPort port;
+
+  Purse(this.mint, this.balance) {
     ReceivePort recipient = new ReceivePort();
-    port = recipient.toSendPort();
+    port = recipient.sendPort;
     servePurse(recipient);
-    // AUTO END
   }
 
-  // AUTO START
   void servePurse(ReceivePort recipient) {
-    recipient.receive((var message, SendPort replyTo) {
+    recipient.listen((message) {
       String command = message[0];
       if (command == "balance") {
-        replyTo.send(queryBalance(), null);
+        SendPort replyTo = message.last;
+        replyTo.send(queryBalance());
       } else if (command == "deposit") {
         Purse source = mint.lookupPurse(message[2]);
         deposit(message[1], source);
       } else if (command == "sprout") {
+        SendPort replyTo = message.last;
         Purse result = sproutPurse();
-        replyTo.send([ result.port ], null);
+        replyTo.send(result.port);
       } else {
         // TODO: Send an exception back.
-        replyTo.send("Exception: Command not understood", null);
+        throw UnsupportedError("Unsupported commend: $command");
       }
     });
   }
-  // AUTO END
 
   int queryBalance() { return balance; }
 
@@ -124,64 +91,60 @@
     balance += amount;
     source.balance -= amount;
   }
-
-  Mint mint;
-  int balance;
-  // AUTO
-  SendPort port;
 }
 
 
-// AUTO START
 class PurseWrapper {
-  PurseWrapper(SendPort this.purse_) {}
+  SendPort _purse;
+
+  PurseWrapper(this._purse) {}
+
+  void _sendReceive(message, replyHandler(reply)) {
+    ReceivePort reply = new ReceivePort();
+    _purse.send([message, reply.sendPort]);
+    reply.first.then(replyHandler);
+  }
 
   void queryBalance(handleBalance(int balance)) {
-    purse_.call([ "balance" ]).then((var message) {
-      int balance = message;
-      handleBalance(balance);
-    });
+    _sendReceive("balance", handleBalance);
   }
 
   void sproutPurse(handleSprouted(PurseWrapper sprouted)) {
-    purse_.call([ "sprout" ]).then((var message) {
-      SendPort sprouted = message[0];
+    _sendReceive("sprout", (SendPort sprouted) {
       handleSprouted(new PurseWrapper(sprouted));
     });
   }
 
   void deposit(PurseWrapper source, int amount) {
-    purse_.send([ "deposit", amount, source.purse_ ], null);
+    _purse.send([ "deposit", amount, source._purse ]);
   }
-
-
-  SendPort purse_;
 }
-// AUTO END
 
-
-// AUTO STATUS UNCLEAR!
-
-mintMakerWrapper() {
-  port.receive((var message, SendPort replyTo) {
+mintMakerWrapper(SendPort replyPort) {
+  ReceivePort receiver = new ReceivePort();
+  replyPort.send(receiver.sendPort);
+  receiver.listen((SendPort replyTo) {
     Mint mint = new Mint();
-    replyTo.send([ mint.port ], null);
+    replyTo.send(mint.port);
   });
 }
 
 class MintMakerWrapper {
-  MintMakerWrapper() {
-    port_ = spawnFunction(mintMakerWrapper);
+  final SendPort _port;
+
+  static Future<MintMakerWrapper> create() {
+    ReceivePort reply = new ReceivePort();
+    return Isolate.spawn(mintMakerWrapper, reply.sendPort).then((_) =>
+        reply.first.then((port) => new MintMakerWrapper._(port)));
   }
 
+  MintMakerWrapper._(this._port);
+
   void makeMint(handleMint(MintWrapper mint)) {
-    port_.call(null).then((var message) {
-      SendPort mint = message[0];
-      handleMint(new MintWrapper(mint));
-    });
+    ReceivePort reply = new ReceivePort();
+    reply.first.then((SendPort mint) { handleMint(new MintWrapper(mint)); });
+    _port.send(reply.sendPort);
   }
-
-  SendPort port_;
 }
 
 _checkBalance(PurseWrapper wrapper, expected) {
@@ -192,70 +155,24 @@
 
 main() {
   test("creating purse, deposit, and query balance", () {
-    MintMakerWrapper mintMaker = new MintMakerWrapper();
-    mintMaker.makeMint(expectAsync1((MintWrapper mint) {
-      mint.createPurse(100, expectAsync1((PurseWrapper purse) {
-        _checkBalance(purse, 100);
-        purse.sproutPurse(expectAsync1((PurseWrapper sprouted) {
-          _checkBalance(sprouted, 0);
+    MintMakerWrapper.create().then(expectAsync1((mintMaker) {
+      mintMaker.makeMint(expectAsync1((MintWrapper mint) {
+        mint.createPurse(100, expectAsync1((PurseWrapper purse) {
           _checkBalance(purse, 100);
+          purse.sproutPurse(expectAsync1((PurseWrapper sprouted) {
+            _checkBalance(sprouted, 0);
+            _checkBalance(purse, 100);
 
-          sprouted.deposit(purse, 5);
-          _checkBalance(sprouted, 0 + 5);
-          _checkBalance(purse, 100 - 5);
+            sprouted.deposit(purse, 5);
+            _checkBalance(sprouted, 0 + 5);
+            _checkBalance(purse, 100 - 5);
 
-          sprouted.deposit(purse, 42);
-          _checkBalance(sprouted, 0 + 5 + 42);
-          _checkBalance(purse, 100 - 5 - 42);
+            sprouted.deposit(purse, 42);
+            _checkBalance(sprouted, 0 + 5 + 42);
+            _checkBalance(purse, 100 - 5 - 42);
+          }));
         }));
       }));
     }));
   });
-
-  /* This is an attempt to show how the above code could look like if we had
-   * better language support for asynchronous messages (deferred/asynccall).
-   * The static helper methods like createPurse and queryBalance would also
-   * have to be marked async.
-
-  void run(port) {
-    MintMakerWrapper mintMaker = spawnMintMaker();
-    deferred {
-      MintWrapper mint = asynccall mintMaker.createMint();
-      PurseWrapper purse = asynccall mint.createPurse(100);
-      expect(asynccall purse.queryBalance(), 100);
-
-      PurseWrapper sprouted = asynccall purse.sproutPurse();
-      expect(asynccall sprouted.queryBalance(), 0);
-
-      asynccall sprouted.deposit(purse, 5);
-      expect(asynccall sprouted.queryBalance(), 0 + 5);
-      expect(asynccall purse.queryBalance(), 100 - 5);
-
-      asynccall sprouted.deposit(purse, 42);
-      expect(asynccall sprouted.queryBalance(), 0 + 5 + 42);
-      expect(asynccall purse.queryBalance(), 100 - 5 - 42);
-    }
-  }
-  */
-
-  /* And a version using futures and wrappers.
-
-  void run(port) {
-    Wrapper<MintMaker> mintMaker = spawnMintMaker();
-    Future<Mint> mint = mintMaker...createMint();
-    Future<Purse> purse = mint...createPurse(100);
-    expect(purse.queryBalance(), 100);
-
-    Future<Purse> sprouted = purse...sproutPurse();
-    expect(0, sprouted.queryBalance());
-
-    sprouted...deposit(purse, 5);
-    expect(sprouted.queryBalance(), 0 + 5);
-    expect(purse.queryBalance(), 100 - 5);
-
-    sprouted...deposit(purse, 42);
-    expect(sprouted.queryBalance(), 0 + 5 + 42);
-    expect(purse.queryBalance(), 100 - 5 - 42);
-  }
-  */
 }
diff --git a/tests/isolate/nested_spawn2_test.dart b/tests/isolate/nested_spawn2_test.dart
index a868084..0c477dd 100644
--- a/tests/isolate/nested_spawn2_test.dart
+++ b/tests/isolate/nested_spawn2_test.dart
@@ -10,12 +10,13 @@
 import 'dart:isolate';
 import '../../pkg/unittest/lib/unittest.dart';
 
-void isolateA() {
-  port.receive((msg, replyTo) {
-    expect(msg, "launch nested!");
-    SendPort p = spawnFunction(isolateB);
-    p.send(replyTo, null);
-    port.close();
+void isolateA(SendPort init) {
+  ReceivePort port = new ReceivePort();
+  init.send(port.sendPort);
+  port.first.then((message) {
+    expect(message[0], "launch nested!");
+    SendPort replyTo = message[1];
+    Isolate.spawn(isolateB, replyTo);
   });
 }
 
@@ -29,42 +30,41 @@
 
 void _call(SendPort p, msg, void onreceive(m, replyTo)) {
   final replyTo = new ReceivePort();
-  p.send(msg, replyTo.toSendPort());
-  replyTo.receive((m, r) {
-    replyTo.close();
-    onreceive(m, r);
+  p.send([msg, replyTo.sendPort]);
+  replyTo.first.then((m) {
+    onreceive(m[0], m[1]);
   });
 }
 
-void isolateB() {
-  port.receive((mainPort, replyTo) {
-    port.close();
-    // Do a little ping-pong dance to give the intermediate isolate
-    // time to die.
-    _call(mainPort, msg0, ((msg, replyTo) {
-      expect(msg[0], "1");
-      _call(replyTo, msg2, ((msg, replyTo) {
-        expect(msg[0], "3");
-        _call(replyTo, msg4, ((msg, replyTo) {
-          expect(msg[0], "5");
-          replyTo.send(msg6, null);
-        }));
+void isolateB(SendPort mainPort) {
+  // Do a little ping-pong dance to give the intermediate isolate
+  // time to die.
+  _call(mainPort, msg0, ((msg, replyTo) {
+    expect(msg[0], "1");
+    _call(replyTo, msg2, ((msg, replyTo) {
+      expect(msg[0], "3");
+      _call(replyTo, msg4, ((msg, replyTo) {
+        expect(msg[0], "5");
+        replyTo.send([msg6, null]);
       }));
     }));
-  });
+  }));
 }
 
 main() {
   test("spawned isolate can spawn other isolates", () {
-    SendPort port = spawnFunction(isolateA);
-    _call(port, "launch nested!", expectAsync2((msg, replyTo) {
-      expect(msg[0], "0");
-      _call(replyTo, msg1, expectAsync2((msg, replyTo) {
-        expect(msg[0], "2");
-        _call(replyTo, msg3, expectAsync2((msg, replyTo) {
-          expect(msg[0], "4");
-          _call(replyTo, msg5, expectAsync2((msg, replyTo) {
-            expect(msg[0], "6");
+    ReceivePort init = new ReceivePort();
+    Isolate.spawn(isolateA, init.sendPort);
+    init.first.then(expectAsync1((port) {
+      _call(port, "launch nested!", expectAsync2((msg, replyTo) {
+        expect(msg[0], "0");
+        _call(replyTo, msg1, expectAsync2((msg, replyTo) {
+          expect(msg[0], "2");
+          _call(replyTo, msg3, expectAsync2((msg, replyTo) {
+            expect(msg[0], "4");
+            _call(replyTo, msg5, expectAsync2((msg, _) {
+              expect(msg[0], "6");
+            }));
           }));
         }));
       }));
diff --git a/tests/isolate/nested_spawn_stream2_test.dart b/tests/isolate/nested_spawn_stream2_test.dart
deleted file mode 100644
index d21933e..0000000
--- a/tests/isolate/nested_spawn_stream2_test.dart
+++ /dev/null
@@ -1,80 +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.
-
-// Dart test program for testing that isolates can spawn other isolates and
-// that the nested isolates can communicate with the main once the spawner has
-// disappeared.
-
-library NestedSpawn2Test;
-import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
-
-void _call(IsolateSink sink, msg, void onreceive(m, replyTo)) {
-  final box = new MessageBox();
-  sink.add([msg, box.sink]);
-  sink.close();
-  box.stream.single.then((msg) {
-    onreceive(msg[0], msg[1]);
-  });
-}
-
-void _receive(IsolateStream stream, void onreceive(m, replyTo)) {
-  stream.single.then((msg) {
-    onreceive(msg[0], msg[1]);
-  });
-}
-
-void isolateA() {
-  _receive(stream, (msg, replyTo) {
-    expect(msg, "launch nested!");
-    IsolateSink sink = streamSpawnFunction(isolateB);
-    sink.add(replyTo);
-    sink.close();
-    stream.close();
-  });
-}
-
-String msg0 = "0 there?";
-String msg1 = "1 Yes.";
-String msg2 = "2 great. Think the other one is already dead?";
-String msg3 = "3 Give him some time.";
-String msg4 = "4 now?";
-String msg5 = "5 Now.";
-String msg6 = "6 Great. Bye";
-
-void isolateB() {
-  stream.single.then((mainPort) {
-    // Do a little ping-pong dance to give the intermediate isolate
-    // time to die.
-    _call(mainPort, msg0, ((msg, replyTo) {
-      expect(msg[0], "1");
-      _call(replyTo, msg2, ((msg, replyTo) {
-        expect(msg[0], "3");
-        _call(replyTo, msg4, ((msg, replyTo) {
-          expect(msg[0], "5");
-          replyTo.add(msg6);
-          replyTo.close();
-        }));
-      }));
-    }));
-  });
-}
-
-main() {
-  test("spawned isolate can spawn other isolates", () {
-    IsolateSink sink = streamSpawnFunction(isolateA);
-    _call(sink, "launch nested!", expectAsync2((msg, replyTo) {
-      expect(msg[0], "0");
-      _call(replyTo, msg1, expectAsync2((msg, replyTo) {
-        expect(msg[0], "2");
-        _call(replyTo, msg3, expectAsync2((msg, replyTo) {
-          expect(msg[0], "4");
-          _call(replyTo, msg5, expectAsync2((msg, replyTo) {
-            expect(msg[0], "6");
-          }));
-        }));
-      }));
-    }));
-  });
-}
diff --git a/tests/isolate/nested_spawn_stream_test.dart b/tests/isolate/nested_spawn_stream_test.dart
deleted file mode 100644
index bc589ac..0000000
--- a/tests/isolate/nested_spawn_stream_test.dart
+++ /dev/null
@@ -1,61 +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.
-
-// Dart test program for testing that isolates can spawn other isolates.
-
-library NestedSpawnTest;
-import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
-
-void isolateA() {
-  IsolateSink replyTo;
-  bool isFirst = true;
-  stream.listen((msg) {
-    if (isFirst) {
-      isFirst = false;
-      replyTo = msg;
-      return;
-    }
-    expect(msg, "launch nested!");
-    IsolateSink sink = streamSpawnFunction(isolateB);
-    MessageBox box = new MessageBox();
-    sink.add(box.sink);
-    sink.add("alive?");
-    box.stream.single.then((msg) {
-      expect(msg, "and kicking");
-      replyTo.add(499);
-      replyTo.close();
-      stream.close();
-    });
-  });
-}
-
-void isolateB() {
-  IsolateSink replyTo;
-  bool isFirst = true;
-  stream.listen((msg) {
-    if (isFirst) {
-      isFirst = false;
-      replyTo = msg;
-      return;
-    }
-    expect(msg, "alive?");
-    replyTo.add("and kicking");
-    replyTo.close();
-    stream.close();
-  });
-}
-
-
-main() {
-  test("spawned isolates can spawn nested isolates", () {
-    MessageBox box = new MessageBox();
-    IsolateSink sink = streamSpawnFunction(isolateA);
-    sink.add(box.sink);
-    sink.add("launch nested!");
-    box.stream.single.then(expectAsync1((msg) {
-      expect(msg, 499);
-    }));
-  });
-}
diff --git a/tests/isolate/nested_spawn_test.dart b/tests/isolate/nested_spawn_test.dart
index 795ad99..51157f3 100644
--- a/tests/isolate/nested_spawn_test.dart
+++ b/tests/isolate/nested_spawn_test.dart
@@ -8,32 +8,24 @@
 import 'dart:isolate';
 import '../../pkg/unittest/lib/unittest.dart';
 
-void isolateA() {
-  port.receive((msg, replyTo) {
-    expect(msg, "launch nested!");
-    SendPort p = spawnFunction(isolateB);
-    p.call("alive?").then((msg) {
-      expect(msg, "and kicking");
-      replyTo.send(499, null);
-      port.close();
-    });
-  });
+void isolateA(message) {
+  message.add("isolateA");
+  Isolate.spawn(isolateB, message);
 }
 
-void isolateB() {
-  port.receive((msg, replyTo) {
-    expect(msg, "alive?");
-    replyTo.send("and kicking", null);
-    port.close();
-  });
+void isolateB(message) {
+  message.add("isolateB");
+  message[0].send(message);
 }
 
-
 main() {
   test("spawned isolates can spawn nested isolates", () {
-    SendPort port = spawnFunction(isolateA);
-    port.call("launch nested!").then(expectAsync1((msg) {
-      expect(msg, 499);
-    }));
+    ReceivePort port = new ReceivePort();
+    Isolate.spawn(isolateA, [port.sendPort, "main"]);
+    port.first.then((message) {
+      expect("main", message[1]);
+      expect("isolateA", message[2]);
+      expect("isolateB", message[3]);
+    });
   });
 }
diff --git a/tests/isolate/port_test.dart b/tests/isolate/port_test.dart
index 1de2c3c..c61e75d 100644
--- a/tests/isolate/port_test.dart
+++ b/tests/isolate/port_test.dart
@@ -20,8 +20,8 @@
 void testHashCode() {
   ReceivePort rp0 = new ReceivePort();
   ReceivePort rp1 = new ReceivePort();
-  Expect.equals(rp0.toSendPort().hashCode, rp0.toSendPort().hashCode);
-  Expect.equals(rp1.toSendPort().hashCode, rp1.toSendPort().hashCode);
+  Expect.equals(rp0.sendPort.hashCode, rp0.sendPort.hashCode);
+  Expect.equals(rp1.sendPort.hashCode, rp1.sendPort.hashCode);
   rp0.close();
   rp1.close();
 }
@@ -29,9 +29,9 @@
 void testEquals() {
   ReceivePort rp0 = new ReceivePort();
   ReceivePort rp1 = new ReceivePort();
-  Expect.equals(rp0.toSendPort(), rp0.toSendPort());
-  Expect.equals(rp1.toSendPort(), rp1.toSendPort());
-  Expect.isFalse(rp0.toSendPort() == rp1.toSendPort());
+  Expect.equals(rp0.sendPort, rp0.sendPort);
+  Expect.equals(rp1.sendPort, rp1.sendPort);
+  Expect.isFalse(rp0.sendPort == rp1.sendPort);
   rp0.close();
   rp1.close();
 }
@@ -40,22 +40,22 @@
   ReceivePort rp0 = new ReceivePort();
   ReceivePort rp1 = new ReceivePort();
   final map = new Map<SendPort, int>();
-  map[rp0.toSendPort()] = 42;
-  map[rp1.toSendPort()] = 87;
-  Expect.equals(map[rp0.toSendPort()], 42);
-  Expect.equals(map[rp1.toSendPort()], 87);
+  map[rp0.sendPort] = 42;
+  map[rp1.sendPort] = 87;
+  Expect.equals(map[rp0.sendPort], 42);
+  Expect.equals(map[rp1.sendPort], 87);
 
-  map[rp0.toSendPort()] = 99;
-  Expect.equals(map[rp0.toSendPort()], 99);
-  Expect.equals(map[rp1.toSendPort()], 87);
+  map[rp0.sendPort] = 99;
+  Expect.equals(map[rp0.sendPort], 99);
+  Expect.equals(map[rp1.sendPort], 87);
 
-  map.remove(rp0.toSendPort());
-  Expect.isFalse(map.containsKey(rp0.toSendPort()));
-  Expect.equals(map[rp1.toSendPort()], 87);
+  map.remove(rp0.sendPort);
+  Expect.isFalse(map.containsKey(rp0.sendPort));
+  Expect.equals(map[rp1.sendPort], 87);
 
-  map.remove(rp1.toSendPort());
-  Expect.isFalse(map.containsKey(rp0.toSendPort()));
-  Expect.isFalse(map.containsKey(rp1.toSendPort()));
+  map.remove(rp1.sendPort);
+  Expect.isFalse(map.containsKey(rp0.sendPort));
+  Expect.isFalse(map.containsKey(rp1.sendPort));
 
   rp0.close();
   rp1.close();
diff --git a/tests/isolate/request_reply_test.dart b/tests/isolate/request_reply_test.dart
index b582569..f70fb5a 100644
--- a/tests/isolate/request_reply_test.dart
+++ b/tests/isolate/request_reply_test.dart
@@ -7,28 +7,28 @@
 import 'dart:isolate';
 import '../../pkg/unittest/lib/unittest.dart';
 
-void entry() {
-  port.receive((message, SendPort replyTo) {
+void entry(initPort) {
+  ReceivePort port = new ReceivePort();
+  initPort.send(port.sendPort);
+  port.listen((pair) {
+    var message = pair[0];
+    SendPort replyTo = pair[1];
     replyTo.send(message + 87);
     port.close();
   });
 }
 
 void main() {
-  test("call", () {
-    SendPort port = spawnFunction(entry);
-    port.call(42).then(expectAsync1((message) {
-      expect(message, 42 + 87);
-    }));
-  });
-
   test("send", () {
-    SendPort port = spawnFunction(entry);
-    ReceivePort reply = new ReceivePort();
-    port.send(99, reply.toSendPort());
-    reply.receive(expectAsync2((message, replyTo) {
-      expect(message, 99 + 87);
-      reply.close();
+    ReceivePort init = new ReceivePort();
+    Isolate.spawn(entry, init.sendPort);
+    init.first.then(expectAsync1((port) {
+      ReceivePort reply = new ReceivePort();
+      port.send([99, reply.sendPort]);
+      reply.listen(expectAsync1((message) {
+        expect(message, 99 + 87);
+        reply.close();
+      }));
     }));
   });
 }
diff --git a/tests/isolate/spawn_function_custom_class_test.dart b/tests/isolate/spawn_function_custom_class_test.dart
index 78c3042..9e83b6f 100644
--- a/tests/isolate/spawn_function_custom_class_test.dart
+++ b/tests/isolate/spawn_function_custom_class_test.dart
@@ -18,21 +18,19 @@
   }
 }
 
-child() {
-  port.receive((msg, reply) {
-    reply.send('re: ${new MyClass().myFunc(msg)}');
-  });
+child(args) {
+  var reply = args[1];
+  var msg = args[0];
+  reply.send('re: ${new MyClass().myFunc(msg)}');
 }
 
 main() {
   test('message - reply chain', () {
     ReceivePort port = new ReceivePort();
-    port.receive((msg, _) {
+    Isolate.spawn(child, ['hi', port.sendPort]);
+    port.listen((msg) {
       port.close();
       expect(msg, equals('re: hi there'));
     });
-
-    SendPort s = spawnFunction(child);
-    s.send('hi', port.toSendPort());
   });
 }
diff --git a/tests/isolate/spawn_function_negative_test.dart b/tests/isolate/spawn_function_negative_test.dart
index faecde09..1806312 100644
--- a/tests/isolate/spawn_function_negative_test.dart
+++ b/tests/isolate/spawn_function_negative_test.dart
@@ -7,19 +7,19 @@
 import 'dart:isolate';
 import '../../pkg/unittest/lib/unittest.dart';
 
-child() {
-  port.receive((msg, reply) => reply.send('re: $msg'));
+child(args) {
+  var msg = args[0];
+  var reply = args[1];
+  reply.send('re: $msg');
 }
 
 main() {
   test('message - reply chain', () {
     ReceivePort port = new ReceivePort();
-    port.receive(expectAsync2((msg, _) {
+    Isolate.spawn(child, ['hi', port.sendPort]);
+    port.listen(expectAsync1((msg) {
       port.close();
       expect(msg, equals('re: hello')); // should be hi, not hello
     }));
-
-    SendPort s = spawnFunction(child);
-    s.send('hi', port.toSendPort());
   });
 }
diff --git a/tests/isolate/spawn_function_test.dart b/tests/isolate/spawn_function_test.dart
index 6829fd1..a452477 100644
--- a/tests/isolate/spawn_function_test.dart
+++ b/tests/isolate/spawn_function_test.dart
@@ -7,19 +7,19 @@
 import 'dart:isolate';
 import '../../pkg/unittest/lib/unittest.dart';
 
-child() {
-  port.receive((msg, reply) => reply.send('re: $msg'));
+child(args) {
+  var msg = args[0];
+  var reply = args[1];
+  reply.send('re: $msg');
 }
 
 main() {
   test('message - reply chain', () {
     ReceivePort port = new ReceivePort();
-    port.receive(expectAsync2((msg, _) {
+    Isolate.spawn(child, ['hi', port.sendPort]);
+    port.listen(expectAsync1((msg) {
       port.close();
       expect(msg, equals('re: hi'));
     }));
-
-    SendPort s = spawnFunction(child);
-    s.send('hi', port.toSendPort());
   });
 }
diff --git a/tests/isolate/spawn_uri_child_isolate.dart b/tests/isolate/spawn_uri_child_isolate.dart
index 9e5fc93..57f1dde 100644
--- a/tests/isolate/spawn_uri_child_isolate.dart
+++ b/tests/isolate/spawn_uri_child_isolate.dart
@@ -6,6 +6,7 @@
 library SpawnUriChildIsolate;
 import 'dart:isolate';
 
-void main() {
-  port.receive((msg, reply) => reply.send('re: $msg'));
+void main(List<String> args, SendPort replyTo) {
+  var data = args[0];
+  replyTo.send('re: $data');
 }
diff --git a/tests/isolate/spawn_uri_multi_test.dart b/tests/isolate/spawn_uri_multi_test.dart
index fc95962..5815ec8 100644
--- a/tests/isolate/spawn_uri_multi_test.dart
+++ b/tests/isolate/spawn_uri_multi_test.dart
@@ -17,15 +17,14 @@
 main() {
   test('isolate fromUri - negative test', () {
     ReceivePort port = new ReceivePort();
-    port.receive(expectAsync2((msg, _) {
+    port.first.then(expectAsync1((msg) {
       String expectedMessage = 're: hi';
       // Should be hi, not hello.
       expectedMessage = 're: hello'; /// 01: runtime error
       expect(msg, equals(expectedMessage));
-      port.close();
     }));
 
-    SendPort s = spawnUri('spawn_uri_child_isolate.dart');
-    s.send('hi', port.toSendPort());
+    Isolate.spawnUri(Uri.parse('spawn_uri_child_isolate.dart'),
+                     ['hi'], port.sendPort);
   });
 }
diff --git a/tests/isolate/spawn_uri_nested_child1_vm_isolate.dart b/tests/isolate/spawn_uri_nested_child1_vm_isolate.dart
index 26c6617..867cae3 100644
--- a/tests/isolate/spawn_uri_nested_child1_vm_isolate.dart
+++ b/tests/isolate/spawn_uri_nested_child1_vm_isolate.dart
@@ -8,17 +8,17 @@
 library NestedSpawnUriChild1Library;
 import 'dart:isolate';
 
-main() {
+main(List<String> args, message) {
   ReceivePort port2 = new ReceivePort();
-  port2.receive((msg, SendPort replyTo) {
+  port2.listen((msg) {
+    if (msg != "re: hi") throw "Bad response: $msg";
     port2.close();
   });
 
-  SendPort s = spawnUri('spawn_uri_nested_child2_vm_isolate.dart');
-  s.send('hi', port2.toSendPort());
+  Isolate.spawnUri(Uri.parse('spawn_uri_nested_child2_vm_isolate.dart'),
+                   ['hi'], port2.sendPort);
 
-  port.receive((message, SendPort replyTo) {
-    var result = message;
-    replyTo.send(result);
-  });
+  var data = message[0];
+  var replyTo = message[1];
+  replyTo.send(data);
 }
diff --git a/tests/isolate/spawn_uri_nested_child2_vm_isolate.dart b/tests/isolate/spawn_uri_nested_child2_vm_isolate.dart
index 87efa5b..d9b9b7e 100644
--- a/tests/isolate/spawn_uri_nested_child2_vm_isolate.dart
+++ b/tests/isolate/spawn_uri_nested_child2_vm_isolate.dart
@@ -6,6 +6,7 @@
 library NestedSpawnUriChild2Library;
 import 'dart:isolate';
 
-void main() {
-  port.receive((msg, reply) => reply.send('re: $msg'));
+void main(List<String> args, SendPort replyTo) {
+  var data = args[0];
+  replyTo.send('re: $data');
 }
diff --git a/tests/isolate/spawn_uri_nested_vm_test.dart b/tests/isolate/spawn_uri_nested_vm_test.dart
index e48483e..07deb9a 100644
--- a/tests/isolate/spawn_uri_nested_vm_test.dart
+++ b/tests/isolate/spawn_uri_nested_vm_test.dart
@@ -12,8 +12,9 @@
 
 main() {
   test('isolate fromUri - nested send and reply', () {
-    var port = spawnUri('spawn_uri_nested_child1_vm_isolate.dart');
-
-    port.call([1, 2]).then((result) => print(result));
+    ReceivePort port = new ReceivePort();
+    Isolate.spawnUri(Uri.parse('spawn_uri_nested_child1_vm_isolate.dart'),
+                     [], [[1, 2], port.sendPort]);
+    port.first.then(expectAsync1((result) => print(result)));
   });
 }
diff --git a/tests/isolate/spawn_uri_test.dart b/tests/isolate/spawn_uri_test.dart
index a68f34f..ddc5c17 100644
--- a/tests/isolate/spawn_uri_test.dart
+++ b/tests/isolate/spawn_uri_test.dart
@@ -13,12 +13,12 @@
 main() {
   test('isolate fromUri - send and reply', () {
     ReceivePort port = new ReceivePort();
-    port.receive(expectAsync2((msg, _) {
+    port.listen(expectAsync1((msg) {
       expect(msg, equals('re: hi'));
       port.close();
     }));
 
-    SendPort s = spawnUri('spawn_uri_child_isolate.dart');
-    s.send('hi', port.toSendPort());
+    Isolate.spawnUri(Uri.parse('spawn_uri_child_isolate.dart'),
+                     ['hi'], port.sendPort);
   });
 }
diff --git a/tests/isolate/spawn_uri_vm_negative_test.dart b/tests/isolate/spawn_uri_vm_negative_test.dart
index a342bfe..9bc6111 100644
--- a/tests/isolate/spawn_uri_vm_negative_test.dart
+++ b/tests/isolate/spawn_uri_vm_negative_test.dart
@@ -13,12 +13,11 @@
 main() {
   test('isolate fromUri - negative test', () {
     ReceivePort port = new ReceivePort();
-    port.receive(expectAsync2((msg, _) {
-      port.close();
+    port.first.then(expectAsync1((msg) {
       expect(msg, equals('re: hello')); // should be hi, not hello
     }));
 
-    SendPort s = spawnUri('spawn_uri_child_isolate.dart');
-    s.send('hi', port.toSendPort());
+    Isolate.spawnUri(Uri.parse('spawn_uri_child_isolate.dart'),
+                     ['hi'], port.sendPort);
   });
 }
diff --git a/tests/isolate/spawn_uri_vm_test.dart b/tests/isolate/spawn_uri_vm_test.dart
index e9bb0da..f72c3d8 100644
--- a/tests/isolate/spawn_uri_vm_test.dart
+++ b/tests/isolate/spawn_uri_vm_test.dart
@@ -13,12 +13,11 @@
 main() {
   test('isolate fromUri - send and reply', () {
     ReceivePort port = new ReceivePort();
-    port.receive(expectAsync2((msg, _) {
-      port.close();
+    port.first.then(expectAsync1((msg) {
       expect(msg, equals('re: hi'));
     }));
 
-    SendPort s = spawnUri('spawn_uri_child_isolate.dart');
-    s.send('hi', port.toSendPort());
+    Isolate.spawnUri(Uri.parse('spawn_uri_child_isolate.dart'),
+                     ['hi'], port.sendPort);
   });
 }
diff --git a/tests/isolate/stacktrace_message_test.dart b/tests/isolate/stacktrace_message_test.dart
index e0e05ec..56ec95f 100644
--- a/tests/isolate/stacktrace_message_test.dart
+++ b/tests/isolate/stacktrace_message_test.dart
@@ -5,21 +5,23 @@
 import 'dart:isolate';
 
 main() {
-  spawnFunction(runTest).call(null);
+  ReceivePort reply = new ReceivePort();
+  Isolate.spawn(runTest, reply.sendPort);
+  reply.first.then((StackTrace stack) {
+    print(stack);
+  });
 }
 
-runTest() {
-  port.receive((param, sendport) {
+runTest(SendPort sendport) {
+  try {
+    throw 'sorry';
+  } catch (e, stack) {
     try {
-      throw 'sorry';
-    } catch (e, stack) {
-      try {
-        sendport.send(stack);
-        print("Stacktrace sent");
-      } catch (e) {
-        print("Stacktrace not sent");
-        sendport.send(null);
-      }
+      sendport.send(stack);
+      print("Stacktrace sent");
+    } catch (e) {
+      print("Stacktrace not sent");
+      sendport.send(null);
     }
-  });
+  }
 }
diff --git a/tests/isolate/stream_mangling_test.dart b/tests/isolate/stream_mangling_test.dart
deleted file mode 100644
index 232a084..0000000
--- a/tests/isolate/stream_mangling_test.dart
+++ /dev/null
@@ -1,103 +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 stream_mangling_test;
-
-import "package:expect/expect.dart";
-import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
-
-main() {
-  test("Self referencing arrays serialize correctly", () {
-    var messageBox = new MessageBox();
-    var stream = messageBox.stream;
-    var sink = messageBox.sink;
-    var nested = [];
-    nested.add(nested);
-    Expect.identical(nested, nested[0]);
-    stream.listen(expectAsync1((data) {
-      Expect.isFalse(identical(nested, data));
-      Expect.isTrue(data is List);
-      Expect.equals(1, data.length);
-      Expect.identical(data, data[0]);
-      stream.close();
-    }));
-    sink.add(nested);
-  });
-
-  test("Self referencing arrays serialize correctly 2", () {
-    var messageBox = new MessageBox();
-    var stream = messageBox.stream;
-    var sink = messageBox.sink;
-    var nested = [0, 1];
-    nested.add(nested);
-    nested.add(3);
-    nested.add(4);
-    Expect.identical(nested, nested[2]);
-    stream.listen(expectAsync1((data) {
-      Expect.isFalse(identical(nested, data));
-      Expect.isTrue(data is List);
-      Expect.equals(5, data.length);
-      Expect.identical(data, data[2]);
-      Expect.equals(0, data[0]);
-      Expect.equals(1, data[1]);
-      Expect.equals(3, data[3]);
-      Expect.equals(4, data[4]);
-      stream.close();
-    }));
-    sink.add(nested);
-  });
-
-  test("Self referencing arrays serialize correctly 3", () {
-    var messageBox = new MessageBox();
-    var stream = messageBox.stream;
-    var sink = messageBox.sink;
-    var nested = [[[[[0, 1]]]]];
-    nested.add(nested);
-    nested[0][0][0][0].add(nested);
-    nested.add(3);
-    nested.add(4);
-    Expect.identical(nested, nested[0][0][0][0][2]);
-    stream.listen(expectAsync1((data) {
-      Expect.isFalse(identical(nested, data));
-      Expect.isTrue(data is List);
-      Expect.equals(4, data.length);
-      Expect.equals(1, data[0].length);
-      Expect.equals(1, data[0][0].length);
-      Expect.equals(1, data[0][0][0].length);
-      Expect.equals(3, data[0][0][0][0].length);
-      Expect.identical(data, data[0][0][0][0][2]);
-      Expect.identical(data, data[1]);
-      Expect.equals(3, data[2]);
-      Expect.equals(4, data[3]);
-      stream.close();
-    }));
-    sink.add(nested);
-  });
-
-  test("Self referencing maps serialize correctly", () {
-    var messageBox = new MessageBox();
-    var stream = messageBox.stream;
-    var sink = messageBox.sink;
-    var nested = {};
-    nested["foo"] = nested;
-    Expect.identical(nested, nested["foo"]);
-    stream.listen(expectAsync1((data) {
-      Expect.isFalse(identical(nested, data));
-      Expect.isTrue(data is Map);
-      Expect.equals(1, data.length);
-      Expect.identical(data, data["foo"]);
-      stream.close();
-    }));
-    sink.add(nested);
-  });
-
-  test("Sending of IsolateSinks", () {
-    // TODO(floitsch): add test.
-  });
-
-  test("Sending of IsolateSinks in complicated structures", () {
-    // TODO(floitsch): add test.
-  });
-}
\ No newline at end of file
diff --git a/tests/isolate/unresolved_ports_test.dart b/tests/isolate/unresolved_ports_test.dart
index 1072000..00cf144 100644
--- a/tests/isolate/unresolved_ports_test.dart
+++ b/tests/isolate/unresolved_ports_test.dart
@@ -14,28 +14,45 @@
 //       main -> beth -> tim -> bob -> main
 //    by giving 'beth' a send-port to 'tim'.
 
-bethIsolate() {
+bethIsolate(init) {
+  ReceivePort port = initIsolate(init);
   // TODO(sigmund): use expectAsync2 when it is OK to use it within an isolate
   // (issue #6856)
-  port.receive((msg, reply) => msg[1].send(
-        '${msg[0]}\nBeth says: Tim are you coming? And Bob?', reply));
+  port.first.then((msg) => msg[1].send([
+        '${msg[0]}\nBeth says: Tim are you coming? And Bob?', msg[2]]));
 }
 
-timIsolate() {
-  SendPort bob = spawnFunction(bobIsolate);
-  port.receive((msg, reply) => bob.send(
-        '$msg\nTim says: Can you tell "main" that we are all coming?', reply));
+timIsolate(init) {
+  ReceivePort port = initIsolate(init);
+  spawnFunction(bobIsolate).then((bob) {
+    port.first.then((msg) => bob.send([
+        '${msg[0]}\nTim says: Can you tell "main" that we are all coming?',
+        msg[1]]));
+  });
 }
 
-bobIsolate() {
-  port.receive((msg, reply) => reply.send(
-        '$msg\nBob says: we are all coming!'));
+bobIsolate(init) {
+  ReceivePort port = initIsolate(init);
+  port.first.then((msg) => msg[1].send(
+        '${msg[0]}\nBob says: we are all coming!'));
+}
+
+Future<SendPort> spawnFunction(function) {
+  ReceivePort init = new ReceivePort();
+  Isolate.spawn(function, init.sendPort);
+  return init.first;
+}
+
+ReceivePort initIsolate(SendPort starter) {
+  ReceivePort port = new ReceivePort();
+  starter.send(port.sendPort);
+  return port;
 }
 
 baseTest({bool failForNegativeTest: false}) {
   test('Message chain with unresolved ports', () {
     ReceivePort port = new ReceivePort();
-    port.receive(expectAsync2((msg, _) {
+    port.listen(expectAsync1((msg) {
       expect(msg, equals('main says: Beth, find out if Tim is coming.'
         '\nBeth says: Tim are you coming? And Bob?'
         '\nTim says: Can you tell "main" that we are all coming?'
@@ -44,14 +61,13 @@
       port.close();
     }));
 
-    SendPort tim = spawnFunction(timIsolate);
-    SendPort beth = spawnFunction(bethIsolate);
+    spawnFunction(timIsolate).then((tim) {
+      spawnFunction(bethIsolate).then((beth) {
+        beth.send(['main says: Beth, find out if Tim is coming.',
+                  tim, port.sendPort]);
+      });
+    });
 
-    beth.send(
-        // because tim is created asynchronously, here we are sending an
-        // unresolved port:
-        ['main says: Beth, find out if Tim is coming.', tim],
-        port.toSendPort());
   });
 }
 
diff --git a/tests/language/call_with_no_such_method_test.dart b/tests/language/call_with_no_such_method_test.dart
new file mode 100644
index 0000000..53792bb
--- /dev/null
+++ b/tests/language/call_with_no_such_method_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class F {
+  call() => null;
+  noSuchMethod(Invocation i) {
+    if (i.memberName == #call && i.isMethod) {
+      return i.positionalArguments[0];
+    }
+    return super.noSuchMethod(i);
+  }
+}
+
+main() {
+  var result = Function.apply(new F(), ['a', 'b', 'c', 'd']);
+  Expect.equals('a', result);
+}
diff --git a/tests/language/issue12336_test.dart b/tests/language/issue12336_test.dart
new file mode 100644
index 0000000..8e61d10
--- /dev/null
+++ b/tests/language/issue12336_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to generate wrong code for
+// [foo].
+
+import "package:expect/expect.dart";
+import "compiler_annotations.dart";
+
+main() {
+  var result = foo(1, 2);
+  Expect.equals(1, result[0]);
+  Expect.equals(2, result[1]);
+
+  result = foo([], 2);
+  Expect.equals(0, result[0]);
+  Expect.listEquals([], result[1]);
+}
+
+@DontInline()
+foo(a, b) {
+  () => 42;
+  if (a is List) {
+    var saved = a as List;
+    // By having two HTypeKnown SSA instructions for [a], dart2js was
+    // confused when updating the phis at exit of this block.
+    a = a.length;
+    b = saved;
+  }
+  return [a, b];
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 24845db..120f90f 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -33,14 +33,6 @@
 [ $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.
@@ -58,7 +50,7 @@
 compile_time_constant_checked3_test/05: Fail, OK
 compile_time_constant_checked3_test/06: Fail, OK
 
-[ $runtime == vm || ($runtime == drt && $compiler == none) ]
+[ $runtime == vm || (($runtime == drt || $runtime == dartium) && $compiler == none) ]
 call_test: Fail # Issue 12602
 dynamic_prefix_core_test: Fail # Issue 12478
 
@@ -72,26 +64,26 @@
 [ $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: Pass, Fail # Issue 13719: Please triage this failure.
-generic_test: Fail # Issue 13719: Please triage this failure.
-issue13474_test: Pass, 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.
+[ $compiler == none && $runtime == dartium && $unchecked ]
 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.
-regress_13494_test: Pass, Fail # Issue 13719: Please triage this failure.
+assertion_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.
 type_checks_in_factory_method_test: Fail # Issue 13719: Please triage this failure.
 vm/type_vm_test: Fail # Issue 13719: Please triage this failure.
 
+[ $compiler == none && $runtime == dartium ]
+first_class_types_literals_test: Pass, Fail # Issue 13719: Please triage this failure.
+issue13474_test: Pass, Fail # Issue 13719: Please triage this failure.
+regress_13494_test: Pass, Fail # Issue 13719: Please triage this failure.
+
 [ $compiler == none && ( $runtime == dartium || $runtime == drt ) ]
-typed_message_test: Fail # Issue 13921
+typed_message_test: Crash, Fail # Issue 13921, 14400
 
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index 53c27cc..8bdaf61 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -29,16 +29,6 @@
 
 built_in_identifier_test/none: Fail # Issue 13023
 
-# Invalid constant redirecting factories should cause compile-time error.
-const_types_test/23: Fail # Issue 14306
-const_types_test/24: Fail # Issue 14306
-const_types_test/25: Fail # Issue 14306
-const_types_test/26: Fail # Issue 14306
-const_types_test/27: Fail # Issue 14306
-const_types_test/28: Fail # Issue 14306
-const_types_test/29: Fail # Issue 14306
-const_types_test/30: Fail # Issue 14306
-const_types_test/41: Fail # Issue 14306
 
 # Please add new failing tests before this line.
 # Section below is for invalid tests.
@@ -46,8 +36,6 @@
 #
 
 
-
-
 # test issue 10683, It is a compile-time error if e refers to the name v or the name v=.
 block_scope_test: fail
 lazy_static3_test: fail
@@ -169,6 +157,9 @@
 # test issue 13916, Looks as no warning should be in this redirecting factory
 redirecting_factory_infinite_steps_test/01: fail
 
+# test issue  , disallow default values in redirecting factories
+redirecting_factory_default_values_test/none: fail # Issue 14471
+
 # test issue 13956, It is a static type warning if any of the type arguments to k' are not subtypes of the bounds of the corresponding formal type parameters of type.
 default_factory2_test/none: fail
 
@@ -201,6 +192,12 @@
 # test issue 14364, "E<A> << D"
 type_promotion_more_specific_test/08: fail
 
+# test issue 14406, setter for final field was removed from spec
+implicit_setter_test/01: fail
+implicit_setter_test/02: fail
+
+# test issue 14410, "typedef C = " is now really illegal syntax
+mixin_illegal_syntax_test/none: fail
 
 #
 # Please don't add new items here.
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index df55670..5d6dc93 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -29,18 +29,6 @@
 
 built_in_identifier_test/none: Fail # Issue 13023
 
-# test issue 13807, missing support for type promotion
-type_promotion_closure_test/none: Fail # Issue 13807
-type_promotion_functions_test/none: Fail # Issue 13807
-type_promotion_local_test/none: Fail # Issue 13807
-type_promotion_logical_and_test/none: Fail # Issue 13807
-type_promotion_multiple_test/none: Fail # Issue 13807
-type_promotion_parameter_test/none: Fail # Issue 13807
-
-# Missing checks for cyclic typedefs (through bounds)
-cyclic_typedef_test/10: Fail # Issue 13906
-cyclic_typedef_test/11: Fail # Issue 13906
-
 # Invalid constant redirecting factories should cause compile-time error.
 const_types_test/23: Fail # Issue 14306
 const_types_test/24: Fail # Issue 14306
@@ -58,8 +46,6 @@
 #
 
 
-
-
 # test issue 10683, It is a compile-time error if e refers to the name v or the name v=.
 block_scope_test: fail
 lazy_static3_test: fail
@@ -166,8 +152,6 @@
 issue11724_test: fail # Issue 12381
 call_nonexistent_static_test/08: fail # Issue 12381
 
-scope_variable_test/01: fail # Issue 12397
-
 # test issue 12539, rules for finals were loosened, contradiction in spec was fixed
 const_syntax_test/09: fail # Issue 12539
 
@@ -199,6 +183,29 @@
 # test issue 14228
 black_listed_test/none: fail # test issue 14228, warnings are required but not expected
 
+# test issue 14289
+bailout3_test: fail # test issue 14289
+prefix9_test: fail # test issue 14289
+
+# test issue 14358, E does not implement inherited A.+
+type_promotion_closure_test/none: Fail
+
+# test issue 14362, wrong assumption that dynamic << A
+type_promotion_functions_test/none: Fail
+
+# test issue 14363, "if ((a is B))" has the same effect as "if (a is B)", so no static warning expected
+type_promotion_parameter_test/53: Fail
+
+# test issue 14364, "E<A> << D"
+type_promotion_more_specific_test/08: fail
+
+# test issue 14406, setter for final field was removed from spec
+implicit_setter_test/01: fail
+implicit_setter_test/02: fail
+
+# test issue 14410, "typedef C = " is now really illegal syntax
+mixin_illegal_syntax_test/none: fail
+
 #
 # Please don't add new items here.
 # This is section for invalid tests.
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 2b551b0..815f7a5 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -24,6 +24,8 @@
 type_variable_conflict_test/05: Fail # Issue 13702
 type_variable_conflict_test/06: Fail # Issue 13702
 implicit_setter_test: Fail # Issue 13919
+redirecting_factory_default_values_test/01: MissingCompileTimeError # Issue 13663
+redirecting_factory_default_values_test/02: MissingCompileTimeError # Issue 13663
 
 # VM specific tests that should not be run by dart2js.
 vm/*: Skip # Issue 12699
diff --git a/tests/language/redirecting_factory_default_values_test.dart b/tests/language/redirecting_factory_default_values_test.dart
new file mode 100644
index 0000000..e0f8fd6
--- /dev/null
+++ b/tests/language/redirecting_factory_default_values_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that parameter default values are disallowed in a redirecting factory.
+
+import "package:expect/expect.dart";
+
+class A {
+  A(this.a, [this.b = 0]);
+  factory A.f(a) = A;
+  factory A.g(a, [b = 0]) = A;  /// 01: compile-time error
+  factory A.h(a, {b: 0}) = A;  /// 02: compile-time error
+
+ int a;
+ int b;
+}
+
+main() {
+  var x = new A.f(42);
+  Expect.equals(x.a, 42);
+  Expect.equals(x.b, 0);
+
+  var y = new A.f(42, 43);
+  Expect.equals(y.a, 42);
+  Expect.equals(y.b, 43);
+}
diff --git a/tests/language/typed_message_test.dart b/tests/language/typed_message_test.dart
index 0904fae..e034d3e 100644
--- a/tests/language/typed_message_test.dart
+++ b/tests/language/typed_message_test.dart
@@ -6,12 +6,15 @@
 // VMOptions=--checked
 
 library TypedMessageTest;
+import "dart:async";
 import "package:expect/expect.dart";
 import "dart:isolate";
 
-void logMessages() {
+void logMessages(SendPort replyTo) {
   print("Starting log server.");
-  port.receive((List<int> message, SendPort replyTo) {
+  ReceivePort port = new ReceivePort();
+  replyTo.send(port.sendPort);
+  port.first.then((List<int> message) {
     print("Log $message");
     Expect.equals(5, message.length);
     Expect.equals(0, message[0]);
@@ -20,18 +23,25 @@
     Expect.equals(3, message[3]);
     Expect.equals(4, message[4]);
     port.close();
-    replyTo.send(1, null);
+    replyTo.send(1);
     print("Stopping log server.");
   });
 }
 
 main() {
-  SendPort remote = spawnFunction(logMessages);
+  ReceivePort receivePort = new ReceivePort();
+  Future<Isolate> remote = Isolate.spawn(logMessages, receivePort.sendPort);
   List<int> msg = new List<int>(5);
   for (int i = 0; i < 5; i++) {
     msg[i] = i;
   }
-  remote.call(msg).then((int message) {
-    Expect.equals(1, message);
+  StreamIterator iterator = new StreamIterator(receivePort);
+  iterator.moveNext().then((b) {
+    SendPort sendPort = iterator.current;
+    sendPort.send(msg);
+    return iterator.moveNext();
+  }).then((b) {
+    Expect.equals(1, iterator.current);
+    receivePort.close();
   });
 }
diff --git a/tests/lib/analyzer/analyze_tests.status b/tests/lib/analyzer/analyze_tests.status
index 58217a9..4fe235a 100644
--- a/tests/lib/analyzer/analyze_tests.status
+++ b/tests/lib/analyzer/analyze_tests.status
@@ -30,9 +30,7 @@
 standalone/package/package_test: fail
 standalone/typed_data_view_test: fail
 standalone/typed_data_test: fail
-
-# https://code.google.com/p/dart/issues/detail?id=11647
-standalone/package/package_isolate_test: fail
+standalone/issue14236_test: Skip # Analyzer can't handle Script snapshots.
 
 
 [ $compiler == dart2analyzer ]
@@ -57,6 +55,4 @@
 standalone/package/package_test: fail
 standalone/typed_data_view_test: fail
 standalone/typed_data_test: fail
-
-# https://code.google.com/p/dart/issues/detail?id=11647
-standalone/package/package_isolate_test: fail
\ No newline at end of file
+standalone/issue14236_test: Skip # Analyzer can't handle Script snapshots.
diff --git a/tests/lib/async/catch_errors.dart b/tests/lib/async/catch_errors.dart
index b7c5d60..c84c9aa 100644
--- a/tests/lib/async/catch_errors.dart
+++ b/tests/lib/async/catch_errors.dart
@@ -46,8 +46,8 @@
     };
   }
   ZoneSpecification specification =
-    new ZoneSpecification(handleUncaughtError: errorHandler,
-                        scheduleMicrotask: asyncHandler);
+      new ZoneSpecification(handleUncaughtError: errorHandler,
+                            scheduleMicrotask: asyncHandler);
   Zone zone = Zone.current.fork(specification: specification);
   if (onError != null) {
     return zone.runGuarded(body);
diff --git a/tests/lib/async/schedule_microtask4_test.dart b/tests/lib/async/schedule_microtask4_test.dart
deleted file mode 100644
index 5b5a2ee..0000000
--- a/tests/lib/async/schedule_microtask4_test.dart
+++ /dev/null
@@ -1,43 +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.
-
-library run_async_test;
-
-import 'package:async_helper/async_helper.dart';
-import 'dart:async';
-import 'dart:isolate';
-
-void startTest(SendPort finishPort, replyPort) {
-  int invokedCallbacks = 0;
-
-  for (int i = 0; i < 100; i++) {
-    scheduleMicrotask(() {
-      invokedCallbacks++;
-      if (invokedCallbacks == 100) finishPort.send("done");
-      if (i == 50) throw new UnsupportedError("ignore exception");
-    });
-  }
-}
-
-runTest() {
-  port.receive(startTest);
-}
-
-bool globalErrorHandler(IsolateUnhandledException e) {
-  return e.source is UnsupportedError && e.source.message == "ignore exception";
-}
-
-main() {
-  asyncStart();
-  var port = new ReceivePort();
-  var timer;
-  SendPort otherIsolate = spawnFunction(runTest, globalErrorHandler);
-  otherIsolate.send(port.toSendPort());
-  port.receive((msg, replyPort) {
-    port.close();
-    timer.cancel();
-    asyncEnd();
-  });
-  timer = new Timer(const Duration(seconds: 2), () { throw "failed"; });
-}
diff --git a/tests/lib/async/schedule_microtask6_test.dart b/tests/lib/async/schedule_microtask6_test.dart
deleted file mode 100644
index 91dccdb..0000000
--- a/tests/lib/async/schedule_microtask6_test.dart
+++ /dev/null
@@ -1,22 +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.
-
-library run_async_test;
-
-import 'dart:async';
-import '../../../pkg/unittest/lib/unittest.dart';
-
-bool _unhandledExceptionCallback(exception) => true;
-
-main() {
-  test('run async test', () {
-    var callback = expectAsync0(() {});
-    scheduleMicrotask(() {
-      scheduleMicrotask(() {
-        callback();
-      });
-      throw new Exception('exception');
-    });
-  });
-}
diff --git a/tests/lib/async/timer_isolate_test.dart b/tests/lib/async/timer_isolate_test.dart
index 80d2220..31776c5 100644
--- a/tests/lib/async/timer_isolate_test.dart
+++ b/tests/lib/async/timer_isolate_test.dart
@@ -10,11 +10,9 @@
 
 const Duration TIMEOUT = const Duration(milliseconds: 100);
 
-createTimer() {
-  port.receive((msg, replyTo) {
-    new Timer(TIMEOUT, () {
-      replyTo.send("timer_fired");
-    });
+createTimer(replyTo) {
+  new Timer(TIMEOUT, () {
+    replyTo.send("timer_fired");
   });
 }
 
@@ -23,15 +21,15 @@
     int startTime;
     int endTime;
 
-    port.receive(expectAsync2((msg, _) {
+    ReceivePort port = new ReceivePort();
+
+    port.first.then(expectAsync1((msg) {
       expect("timer_fired", msg);
       int endTime = (new DateTime.now()).millisecondsSinceEpoch;
       expect(endTime - startTime, greaterThanOrEqualTo(TIMEOUT.inMilliseconds));
-      port.close();
     }));
 
     startTime = (new DateTime.now()).millisecondsSinceEpoch;
-    var sendPort = spawnFunction(createTimer);
-    sendPort.send("sendPort", port.toSendPort());
+    var remote = Isolate.spawn(createTimer, port.sendPort);
   });
 }
diff --git a/tests/lib/json/json_test.dart b/tests/lib/json/json_test.dart
index bb171ea..f820273 100644
--- a/tests/lib/json/json_test.dart
+++ b/tests/lib/json/json_test.dart
@@ -4,66 +4,66 @@
 
 library json_tests;
 import 'package:unittest/unittest.dart';
-import 'dart:json' as json;
+import 'dart:convert';
 
 main() {
   test('Parse', () {
     // Scalars.
-    expect(json.parse(' 5 '), equals(5));
-    expect(json.parse(' -42 '), equals(-42));
-    expect(json.parse(' 3e0 '), equals(3));
-    expect(json.parse(' 3.14 '), equals(3.14));
-    expect(json.parse('true '), isTrue);
-    expect(json.parse(' false'), isFalse);
-    expect(json.parse(' null '), isNull);
-    expect(json.parse('\n\rnull\t'), isNull);
-    expect(json.parse(' "hi there\\" bob" '), equals('hi there" bob'));
-    expect(json.parse(' "" '), isEmpty);
+    expect(JSON.decode(' 5 '), equals(5));
+    expect(JSON.decode(' -42 '), equals(-42));
+    expect(JSON.decode(' 3e0 '), equals(3));
+    expect(JSON.decode(' 3.14 '), equals(3.14));
+    expect(JSON.decode('true '), isTrue);
+    expect(JSON.decode(' false'), isFalse);
+    expect(JSON.decode(' null '), isNull);
+    expect(JSON.decode('\n\rnull\t'), isNull);
+    expect(JSON.decode(' "hi there\\" bob" '), equals('hi there" bob'));
+    expect(JSON.decode(' "" '), isEmpty);
 
     // Lists.
-    expect(json.parse(' [] '), isEmpty);
-    expect(json.parse('[ ]'), isEmpty);
-    expect(json.parse(' [3, -4.5, true, "hi", false] '),
+    expect(JSON.decode(' [] '), isEmpty);
+    expect(JSON.decode('[ ]'), isEmpty);
+    expect(JSON.decode(' [3, -4.5, true, "hi", false] '),
       equals([3, -4.5, true, 'hi', false]));
     // Nulls are tricky.
-    expect(json.parse('[null]'), orderedEquals([null]));
-    expect(json.parse(' [3, -4.5, null, true, "hi", false] '),
+    expect(JSON.decode('[null]'), orderedEquals([null]));
+    expect(JSON.decode(' [3, -4.5, null, true, "hi", false] '),
       equals([3, -4.5, null, true, 'hi', false]));
-    expect(json.parse('[[null]]'), equals([[null]]));
-    expect(json.parse(' [ [3], [], [null], ["hi", true]] '),
+    expect(JSON.decode('[[null]]'), equals([[null]]));
+    expect(JSON.decode(' [ [3], [], [null], ["hi", true]] '),
       equals([[3], [], [null], ['hi', true]]));
 
     // Maps.
-    expect(json.parse(' {} '), isEmpty);
-    expect(json.parse('{ }'), isEmpty);
+    expect(JSON.decode(' {} '), isEmpty);
+    expect(JSON.decode('{ }'), isEmpty);
 
-    expect(json.parse(
+    expect(JSON.decode(
         ' {"x":3, "y": -4.5,  "z" : "hi","u" : true, "v": false } '),
         equals({"x":3, "y": -4.5,  "z" : "hi", "u" : true, "v": false }));
 
-    expect(json.parse(' {"x":3, "y": -4.5,  "z" : "hi" } '),
+    expect(JSON.decode(' {"x":3, "y": -4.5,  "z" : "hi" } '),
         equals({"x":3, "y": -4.5,  "z" : "hi" }));
 
-    expect(json.parse(' {"y": -4.5,  "z" : "hi" ,"x":3 } '),
+    expect(JSON.decode(' {"y": -4.5,  "z" : "hi" ,"x":3 } '),
         equals({"y": -4.5,  "z" : "hi" ,"x":3 }));
 
-    expect(json.parse('{ " hi bob " :3, "": 4.5}'),
+    expect(JSON.decode('{ " hi bob " :3, "": 4.5}'),
         equals({ " hi bob " :3, "": 4.5}));
 
-    expect(json.parse(' { "x" : { } } '), equals({ 'x' : {}}));
-    expect(json.parse('{"x":{}}'), equals({ 'x' : {}}));
+    expect(JSON.decode(' { "x" : { } } '), equals({ 'x' : {}}));
+    expect(JSON.decode('{"x":{}}'), equals({ 'x' : {}}));
 
     // Nulls are tricky.
-    expect(json.parse('{"w":null}'), equals({ 'w' : null}));
+    expect(JSON.decode('{"w":null}'), equals({ 'w' : null}));
 
-    expect(json.parse('{"x":{"w":null}}'), equals({"x":{"w":null}}));
+    expect(JSON.decode('{"x":{"w":null}}'), equals({"x":{"w":null}}));
 
-    expect(json.parse(' {"x":3, "y": -4.5,  "z" : "hi",'
+    expect(JSON.decode(' {"x":3, "y": -4.5,  "z" : "hi",'
                    '"w":null, "u" : true, "v": false } '),
         equals({"x":3, "y": -4.5,  "z" : "hi",
                    "w":null, "u" : true, "v": false }));
 
-    expect(json.parse('{"x": {"a":3, "b": -4.5}, "y":[{}], '
+    expect(JSON.decode('{"x": {"a":3, "b": -4.5}, "y":[{}], '
                    '"z":"hi","w":{"c":null,"d":true}, "v":null}'),
         equals({"x": {"a":3, "b": -4.5}, "y":[{}],
                    "z":"hi","w":{"c":null,"d":true}, "v":null}));
@@ -71,34 +71,34 @@
 
   test('stringify', () {
     // Scalars.
-    expect(json.stringify(5), equals('5'));
-    expect(json.stringify(-42), equals('-42'));
+    expect(JSON.encode(5), equals('5'));
+    expect(JSON.encode(-42), equals('-42'));
     // Dart does not guarantee a formatting for doubles,
     // so reparse and compare to the original.
     validateRoundTrip(3.14);
-    expect(json.stringify(true), equals('true'));
-    expect(json.stringify(false), equals('false'));
-    expect(json.stringify(null), equals('null'));
-    expect(json.stringify(' hi there" bob '), equals('" hi there\\" bob "'));
-    expect(json.stringify('hi\\there'), equals('"hi\\\\there"'));
+    expect(JSON.encode(true), equals('true'));
+    expect(JSON.encode(false), equals('false'));
+    expect(JSON.encode(null), equals('null'));
+    expect(JSON.encode(' hi there" bob '), equals('" hi there\\" bob "'));
+    expect(JSON.encode('hi\\there'), equals('"hi\\\\there"'));
     // TODO(devoncarew): these tests break the dartium build
-    //expect(json.stringify('hi\nthere'), equals('"hi\\nthere"'));
-    //expect(json.stringify('hi\r\nthere'), equals('"hi\\r\\nthere"'));
-    expect(json.stringify(''), equals('""'));
+    //expect(JSON.encode('hi\nthere'), equals('"hi\\nthere"'));
+    //expect(JSON.encode('hi\r\nthere'), equals('"hi\\r\\nthere"'));
+    expect(JSON.encode(''), equals('""'));
 
     // Lists.
-    expect(json.stringify([]), equals('[]'));
-    expect(json.stringify(new List(0)), equals('[]'));
-    expect(json.stringify(new List(3)), equals('[null,null,null]'));
+    expect(JSON.encode([]), equals('[]'));
+    expect(JSON.encode(new List(0)), equals('[]'));
+    expect(JSON.encode(new List(3)), equals('[null,null,null]'));
     validateRoundTrip([3, -4.5, null, true, 'hi', false]);
-    expect(json.stringify([[3], [], [null], ['hi', true]]),
+    expect(JSON.encode([[3], [], [null], ['hi', true]]),
       equals('[[3],[],[null],["hi",true]]'));
 
     // Maps.
-    expect(json.stringify({}), equals('{}'));
-    expect(json.stringify(new Map()), equals('{}'));
-    expect(json.stringify({'x':{}}), equals('{"x":{}}'));
-    expect(json.stringify({'x':{'a':3}}), equals('{"x":{"a":3}}'));
+    expect(JSON.encode({}), equals('{}'));
+    expect(JSON.encode(new Map()), equals('{}'));
+    expect(JSON.encode({'x':{}}), equals('{"x":{}}'));
+    expect(JSON.encode({'x':{'a':3}}), equals('{"x":{"a":3}}'));
 
     // Dart does not guarantee an order on the keys
     // of a map literal, so reparse and compare to the original Map.
@@ -110,17 +110,17 @@
         {'x':{'a':3, 'b':-4.5}, 'y':[{}], 'z':'hi', 'w':{'c':null, 'd':true},
                   'v':null});
 
-    expect(json.stringify(new ToJson(4)), "4");
-    expect(json.stringify(new ToJson([4, "a"])), '[4,"a"]');
-    expect(json.stringify(new ToJson([4, new ToJson({"x":42})])),
+    expect(JSON.encode(new ToJson(4)), "4");
+    expect(JSON.encode(new ToJson([4, "a"])), '[4,"a"]');
+    expect(JSON.encode(new ToJson([4, new ToJson({"x":42})])),
            '[4,{"x":42}]');
 
     expect(() {
-      json.stringify([new ToJson(new ToJson(4))]);
+      JSON.encode([new ToJson(new ToJson(4))]);
     }, throwsJsonError);
 
     expect(() {
-      json.stringify([new Object()]);
+      JSON.encode([new Object()]);
     }, throwsJsonError);
 
   });
@@ -130,16 +130,16 @@
      * Checks that we get an exception (rather than silently returning null) if
      * we try to stringify something that cannot be converted to json.
      */
-    expect(() => json.stringify(new TestClass()), throwsJsonError);
+    expect(() => JSON.encode(new TestClass()), throwsJsonError);
   });
 
   test('stringify throws if toJson throws', () {
-    expect(() => json.stringify(new ToJsoner("bad", throws: true)),
+    expect(() => JSON.encode(new ToJsoner("bad", throws: true)),
            throwsJsonError);
   });
 
   test('stringify throws if toJson returns non-serializable value', () {
-    expect(() => json.stringify(new ToJsoner(new TestClass())),
+    expect(() => JSON.encode(new ToJsoner(new TestClass())),
            throwsJsonError);
   });
 
@@ -150,7 +150,7 @@
       b = [b];
     }
     a.add(b);
-    expect(() => json.stringify(a), throwsJsonError);
+    expect(() => JSON.encode(a), throwsJsonError);
   });
 }
 
@@ -178,12 +178,12 @@
 }
 
 var throwsJsonError =
-    throwsA(new isInstanceOf<json.JsonUnsupportedObjectError>());
+    throwsA(new isInstanceOf<JsonUnsupportedObjectError>());
 
 /**
  * Checks that the argument can be converted to a JSON string and
  * back, and produce something equivalent to the argument.
  */
 validateRoundTrip(expected) {
-  expect(json.parse(json.stringify(expected)), equals(expected));
+  expect(JSON.decode(JSON.encode(expected)), equals(expected));
 }
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 6961894..edff803 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -7,7 +7,6 @@
 
 [ $compiler == dart2js ]
 async/schedule_microtask3_test: RuntimeError # _enqueueImmediate runs after Timer. http://dartbug.com/9002
-async/schedule_microtask4_test: Pass, RuntimeError # no global exception handler in isolates. http://dartbug.com/9012
 async/schedule_microtask6_test: RuntimeError # global error handling is not supported. http://dartbug.com/5958
 
 math/double_pow_test: RuntimeError
@@ -15,6 +14,7 @@
 math/random_test: RuntimeError
 
 mirrors/basic_types_in_dart_core_test: RuntimeError # Issue 14025
+mirrors/class_declarations_test/none: RuntimeError # Issue 13440
 mirrors/closures_test/none: RuntimeError # Issue 6490
 mirrors/closure_mirror_find_in_context_test: Fail # Issue 6490
 mirrors/constructor_kinds_test: RuntimeError # Issue 13799
@@ -45,6 +45,7 @@
 mirrors/invoke_named_test/none: RuntimeError # Issue 12863
 mirrors/invoke_private_test: CompileTimeError # Issue 12164
 mirrors/invoke_throws_test: RuntimeError # Issue 11954
+mirrors/library_declarations_test/none: RuntimeError # Issue 13439, Issue 13733
 mirrors/library_metadata2_test/01: CompileTimeError # Issue 13633
 mirrors/library_uri_io_test: Skip # Not intended for dart2js as it uses dart:io.
 mirrors/method_mirror_name_test: RuntimeError # Issue 6335
@@ -69,7 +70,7 @@
 mirrors/typedef_metadata_test: RuntimeError # Issue 12785
 mirrors/typevariable_mirror_metadata_test: CompileTimeError # Issue 10905
 mirrors/type_variable_owner_test/01: RuntimeError # Issue 12785
-mirrors/unnamed_library_test: RuntimeError # Issue 10580
+mirrors/generic_type_mirror_test/01: RuntimeError # 6490
 
 [ $compiler == dart2js && $unchecked ]
 mirrors/generic_bounded_test/02: RuntimeError # Issue 12087
@@ -128,6 +129,10 @@
 mirrors/*: Skip # http://dartbug.com/11511
 async/schedule_microtask6_test: Fail             # Issue 10957 - may be related to issue 10910
 async/schedule_microtask3_test: RuntimeError # Issue 13719: Please triage this failure.
+platform/package_root_test: Fail # Issue 14451
+platform/script_test: Fail # Issue 14451
+platform/isolate_test: Fail # Issue 14451
+
 
 [ $compiler == dart2dart && $minified ]
 json/json_test: Fail                            # Issue 10961
@@ -177,7 +182,6 @@
 mirrors/generic_f_bounded_test/01: RuntimeError # Issue 14000
 mirrors/symbol_validation_test: RuntimeError # Issue 13596
 
-async/timer_isolate_test: Skip # See Issue 4997
 async/timer_not_available_test: SkipByDesign # only meant to test when there is no way to implement timer (currently only in d8)
 
 [ $compiler == none && ( $runtime == drt || $runtime == dartium ) ]
@@ -185,7 +189,10 @@
 mirrors/library_uri_io_test: Skip # Not intended for drt as it uses dart:io.
 mirrors/local_isolate_test: Skip # http://dartbug.com/12188
 async/schedule_microtask6_test: Fail # Issue 10910
-async/schedule_microtask4_test: Fail # Issue 13921
+platform/isolate_test: Skip # Issue 14444
+
+[ $compiler == none && $runtime == drt && $mode == debug ]
+mirrors/hierarchy_invariants_test: Pass, Slow # Issue 14449
 
 [ $compiler == none && $runtime == drt && $system == windows ]
 async/multiple_timer_test: Fail, Pass # See Issue 10982
@@ -210,24 +217,32 @@
 mirrors/generic_f_bounded_mixin_application_test: Fail # Issue 14116
 mirrors/generic_interface_test/none: Fail # Inexpressible in multitest
 mirrors/typevariable_mirror_metadata_test/none: Fail # Issue 13093
-mirrors/redirecting_factory_test/none: Fail # Issue 14285
 mirrors/type_variable_owner_test/none: Fail # Issue 14356
 
 [ $compiler == dart2analyzer ]
 mirrors/typedef_test/none: Fail # Issue 13093
 mirrors/generics_test/none: Fail # Issue 13432
 mirrors/generic_bounded_test/none: Fail # Issue 13432
+mirrors/generic_f_bounded_test/none: Fail # Issue 13432
 mirrors/generic_bounded_by_type_parameter_test/none: Fail # Issue 13432
 mirrors/generic_mixin_test/none: Fail # Issue 13432
 mirrors/invoke_named_test/none: Fail # http://dartbug.com/13612
 mirrors/generic_f_bounded_mixin_application_test: Fail # Issue 14116
 mirrors/generic_interface_test/none: Fail # Inexpressible in multitest
+mirrors/typevariable_mirror_metadata_test/none: Fail # Issue 13093
 mirrors/type_variable_owner_test/none: Fail # Issue 14356
 
 [ $compiler == none && $runtime == dartium ]
 async/schedule_microtask5_test: Pass, Timeout # Issue 13719: Please triage this failure.
 async/timer_cancel2_test: Pass, Timeout # Issue 13719: Please triage this failure.
 
+[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
+# Issue 13921: spawnFunction is not allowed on Dartium's DOM thread.
+async/timer_isolate_test: Fail
+
+[ $compiler == none && ($runtime == drt || $runtime == dartium) && $system == windows ]
+platform/uri_test: Fail # Issue 14504
+
 [ ($compiler != none && $runtime != none) || ($compiler == none && ($runtime != dartium && $runtime != drt)) ]
 async/schedule_microtask_test: Fail # Issue 9001, Issue 9002
 
diff --git a/tests/lib/math/rectangle_test.dart b/tests/lib/math/rectangle_test.dart
index 2b214d2..9e1c479 100644
--- a/tests/lib/math/rectangle_test.dart
+++ b/tests/lib/math/rectangle_test.dart
@@ -74,23 +74,23 @@
 
   test('containsRectangle', () {
     var r = new Rectangle(-10, 0, 20, 10);
-    expect(r.contains(r), isTrue);
+    expect(r.containsRectangle(r), isTrue);
 
-    expect(r.contains(
+    expect(r.containsRectangle(
         new Rectangle(double.NAN, double.NAN, double.NAN, double.NAN)), isFalse);
 
     var r2 = new Rectangle(0, 2, 5, 5);
-    expect(r.contains(r2), isTrue);
-    expect(r2.contains(r), isFalse);
+    expect(r.containsRectangle(r2), isTrue);
+    expect(r2.containsRectangle(r), isFalse);
 
     r2 = new Rectangle(-11, 2, 5, 5);
-    expect(r.contains(r2), isFalse);
+    expect(r.containsRectangle(r2), isFalse);
     r2 = new Rectangle(0, 2, 15, 5);
-    expect(r.contains(r2), isFalse);
+    expect(r.containsRectangle(r2), isFalse);
     r2 = new Rectangle(0, 2, 5, 10);
-    expect(r.contains(r2), isFalse);
+    expect(r.containsRectangle(r2), isFalse);
     r2 = new Rectangle(0, 0, 5, 10);
-    expect(r.contains(r2), isTrue);
+    expect(r.containsRectangle(r2), isTrue);
   });
 
   test('containsPoint', () {
diff --git a/tests/lib/mirrors/class_declarations_test.dart b/tests/lib/mirrors/class_declarations_test.dart
new file mode 100644
index 0000000..f957c10
--- /dev/null
+++ b/tests/lib/mirrors/class_declarations_test.dart
@@ -0,0 +1,332 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.declarations_test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'stringify.dart';
+import 'declarations_model.dart' as declarations_model;
+
+Set<DeclarationMirror> inheritedDeclarations(ClassMirror cm) {
+  var decls = new Set<DeclarationMirror>();
+  while (cm != null) {
+    decls.addAll(cm.declarations.values);
+    cm = cm.superclass;
+  }
+  return decls;
+}
+
+main() {
+  ClassMirror cm = reflectClass(declarations_model.Class);
+
+  Expect.setEquals(
+   ['Variable(s(_instanceVariable) in s(Class), private)',
+    'Variable(s(_staticVariable) in s(Class), private, static)',
+    'Variable(s(instanceVariable) in s(Class))',
+    'Variable(s(staticVariable) in s(Class), static)'],
+    cm.declarations.values
+        .where((dm) => dm is VariableMirror).map(stringify),
+    'variables');
+
+  Expect.setEquals(
+   ['Method(s(_instanceGetter) in s(Class), private, getter)',
+    'Method(s(_staticGetter) in s(Class), private, static, getter)',
+    'Method(s(instanceGetter) in s(Class), getter)',
+    'Method(s(staticGetter) in s(Class), static, getter)'],
+    cm.declarations.values
+        .where((dm) => dm is MethodMirror && dm.isGetter).map(stringify),
+    'getters');
+
+  Expect.setEquals(
+   ['Method(s(_instanceSetter=) in s(Class), private, setter)',
+    'Method(s(_staticSetter=) in s(Class), private, static, setter)',
+    'Method(s(instanceSetter=) in s(Class), setter)',
+    'Method(s(staticSetter=) in s(Class), static, setter)'],
+    cm.declarations.values
+        .where((dm) => dm is MethodMirror && dm.isSetter).map(stringify),
+    'setters');
+
+  // dart2js stops testing here.
+  return;  /// 01: ok
+
+  Expect.setEquals(
+   ['Method(s(+) in s(Class))',
+    'Method(s(_instanceMethod) in s(Class), private)',
+    'Method(s(_staticMethod) in s(Class), private, static)',
+    'Method(s(abstractMethod) in s(Class), abstract)',
+    'Method(s(instanceMethod) in s(Class))',
+    'Method(s(staticMethod) in s(Class), static)'],
+    cm.declarations.values
+        .where((dm) => dm is MethodMirror && dm.isRegularMethod).map(stringify),
+    'regular methods');
+
+  Expect.setEquals(
+   ['Method(s(Class._generativeConstructor) in s(Class), private, constructor)',
+    'Method(s(Class._normalFactory) in s(Class), private, static, constructor)',
+    'Method(s(Class._redirectingConstructor)'
+        ' in s(Class), private, constructor)',
+    'Method(s(Class._redirectingFactory)'
+        ' in s(Class), private, static, constructor)',
+    'Method(s(Class.generativeConstructor) in s(Class), constructor)',
+    'Method(s(Class.normalFactory) in s(Class), static, constructor)',
+    'Method(s(Class.redirectingConstructor) in s(Class), constructor)',
+    'Method(s(Class.redirectingFactory) in s(Class), static, constructor)'],
+    cm.declarations.values
+        .where((dm) => dm is MethodMirror && dm.isConstructor).map(stringify),
+    'constructors and factories');
+
+  Expect.setEquals(
+   ['Method(s(Class._normalFactory) in s(Class), private, static, constructor)',
+    'Method(s(Class._redirectingFactory)'
+        ' in s(Class), private, static, constructor)',
+    'Method(s(Class.normalFactory) in s(Class), static, constructor)',
+    'Method(s(Class.redirectingFactory) in s(Class), static, constructor)',
+    'Method(s(_staticGetter) in s(Class), private, static, getter)',
+    'Method(s(_staticMethod) in s(Class), private, static)',
+    'Method(s(_staticSetter=) in s(Class), private, static, setter)',
+    'Variable(s(_staticVariable) in s(Class), private, static)',
+    'Method(s(staticGetter) in s(Class), static, getter)',
+    'Method(s(staticMethod) in s(Class), static)',
+    'Method(s(staticSetter=) in s(Class), static, setter)',
+    'Variable(s(staticVariable) in s(Class), static)'],
+    cm.declarations.values.where((dm) => dm.isStatic).map(stringify),
+    'statics');
+
+  Expect.setEquals(
+   ['Method(s(+) in s(Class))',
+    'TypeVariable(s(C) in s(Class),'
+        ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+    'Method(s(Class._generativeConstructor) in s(Class), private, constructor)',
+    'Method(s(Class._redirectingConstructor)'
+        ' in s(Class), private, constructor)',
+    'Method(s(Class.generativeConstructor) in s(Class), constructor)',
+    'Method(s(Class.redirectingConstructor) in s(Class), constructor)',
+    'Method(s(_instanceGetter) in s(Class), private, getter)',
+    'Method(s(_instanceMethod) in s(Class), private)',
+    'Method(s(_instanceSetter=) in s(Class), private, setter)',
+    'Variable(s(_instanceVariable) in s(Class), private)',
+    'Method(s(abstractMethod) in s(Class), abstract)',
+    'Method(s(instanceGetter) in s(Class), getter)',
+    'Method(s(instanceMethod) in s(Class))',
+    'Method(s(instanceSetter=) in s(Class), setter)',
+    'Variable(s(instanceVariable) in s(Class))'],
+    cm.declarations.values.where((dm) => !dm.isStatic).map(stringify),
+    'non-statics');
+
+  Expect.setEquals(
+   ['Method(s(+) in s(Class))',
+    'TypeVariable(s(C) in s(Class),'
+        ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+    'Method(s(Class.generativeConstructor) in s(Class), constructor)',
+    'Method(s(Class.normalFactory) in s(Class), static, constructor)',
+    'Method(s(Class.redirectingConstructor) in s(Class), constructor)',
+    'Method(s(Class.redirectingFactory) in s(Class), static, constructor)',
+    'Method(s(abstractMethod) in s(Class), abstract)',
+    'Method(s(instanceGetter) in s(Class), getter)',
+    'Method(s(instanceMethod) in s(Class))',
+    'Method(s(instanceSetter=) in s(Class), setter)',
+    'Variable(s(instanceVariable) in s(Class))',
+    'Method(s(staticGetter) in s(Class), static, getter)',
+    'Method(s(staticMethod) in s(Class), static)',
+    'Method(s(staticSetter=) in s(Class), static, setter)',
+    'Variable(s(staticVariable) in s(Class), static)'],
+    cm.declarations.values.where((dm) => !dm.isPrivate).map(stringify),
+    'public');
+
+  Expect.setEquals(
+   ['Method(s(*) in s(Mixin))',
+    'Method(s(+) in s(Class))',
+    'Method(s(-) in s(Superclass))',
+    'Method(s(==) in s(Object))',
+    'TypeVariable(s(C) in s(Class),'
+        ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+    'Method(s(Class.generativeConstructor) in s(Class), constructor)',
+    'Method(s(Class.normalFactory) in s(Class), static, constructor)',
+    'Method(s(Class.redirectingConstructor) in s(Class), constructor)',
+    'Method(s(Class.redirectingFactory) in s(Class), static, constructor)',
+    'Method(s(Object) in s(Object), constructor)',
+    'TypeVariable(s(S) in s(Superclass),'
+        ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+    'Method(s(Superclass.inheritedGenerativeConstructor)'
+        ' in s(Superclass), constructor)',
+    'Method(s(Superclass.inheritedNormalFactory)'
+        ' in s(Superclass), static, constructor)',
+    'Method(s(Superclass.inheritedRedirectingConstructor)'
+        ' in s(Superclass), constructor)',
+    'Method(s(Superclass.inheritedRedirectingFactory)'
+        ' in s(Superclass), static, constructor)',
+    'Method(s(abstractMethod) in s(Class), abstract)',
+    'Method(s(hashCode) in s(Object), getter)',
+    'Method(s(inheritedInstanceGetter) in s(Superclass), getter)',
+    'Method(s(inheritedInstanceMethod) in s(Superclass))',
+    'Method(s(inheritedInstanceSetter=) in s(Superclass), setter)',
+    'Variable(s(inheritedInstanceVariable) in s(Superclass))',
+    'Method(s(inheritedStaticGetter) in s(Superclass), static, getter)',
+    'Method(s(inheritedStaticMethod) in s(Superclass), static)',
+    'Method(s(inheritedStaticSetter=) in s(Superclass), static, setter)',
+    'Variable(s(inheritedStaticVariable) in s(Superclass), static)',
+    'Method(s(instanceGetter) in s(Class), getter)',
+    'Method(s(instanceMethod) in s(Class))',
+    'Method(s(instanceSetter=) in s(Class), setter)',
+    'Variable(s(instanceVariable) in s(Class))',
+    'Method(s(mixinInstanceGetter) in s(Mixin), getter)',
+    'Method(s(mixinInstanceMethod) in s(Mixin))',
+    'Method(s(mixinInstanceSetter=) in s(Mixin), setter)',
+    'Variable(s(mixinInstanceVariable) in s(Mixin))',
+    'Method(s(noSuchMethod) in s(Object))',
+    'Method(s(runtimeType) in s(Object), getter)',
+    'Method(s(staticGetter) in s(Class), static, getter)',
+    'Method(s(staticMethod) in s(Class), static)',
+    'Method(s(staticSetter=) in s(Class), static, setter)',
+    'Variable(s(staticVariable) in s(Class), static)',
+    'Method(s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin.inheritedGenerativeConstructor)'
+        ' in s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin), constructor)',
+    'Method(s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin.inheritedRedirectingConstructor)'
+        ' in s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin), constructor)',
+    'Method(s(toString) in s(Object))'],
+    inheritedDeclarations(cm).where((dm) => !dm.isPrivate).map(stringify),
+    'transitive public');
+  // The public members of Object should be the same in all implementations, so
+  // we don't exclude Object here.
+
+  Expect.setEquals(
+   ['Method(s(+) in s(Class))',
+    'TypeVariable(s(C) in s(Class),'
+        ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+    'Method(s(Class._generativeConstructor) in s(Class), private, constructor)',
+    'Method(s(Class._normalFactory) in s(Class), private, static, constructor)',
+    'Method(s(Class._redirectingConstructor)'
+        ' in s(Class), private, constructor)',
+    'Method(s(Class._redirectingFactory)'
+        ' in s(Class), private, static, constructor)',
+    'Method(s(Class.generativeConstructor) in s(Class), constructor)',
+    'Method(s(Class.normalFactory) in s(Class), static, constructor)',
+    'Method(s(Class.redirectingConstructor) in s(Class), constructor)',
+    'Method(s(Class.redirectingFactory) in s(Class), static, constructor)',
+    'Method(s(_instanceGetter) in s(Class), private, getter)',
+    'Method(s(_instanceMethod) in s(Class), private)',
+    'Method(s(_instanceSetter=) in s(Class), private, setter)',
+    'Variable(s(_instanceVariable) in s(Class), private)',
+    'Method(s(_staticGetter) in s(Class), private, static, getter)',
+    'Method(s(_staticMethod) in s(Class), private, static)',
+    'Method(s(_staticSetter=) in s(Class), private, static, setter)',
+    'Variable(s(_staticVariable) in s(Class), private, static)',
+    'Method(s(abstractMethod) in s(Class), abstract)',
+    'Method(s(instanceGetter) in s(Class), getter)',
+    'Method(s(instanceMethod) in s(Class))',
+    'Method(s(instanceSetter=) in s(Class), setter)',
+    'Variable(s(instanceVariable) in s(Class))',
+    'Method(s(staticGetter) in s(Class), static, getter)',
+    'Method(s(staticMethod) in s(Class), static)',
+    'Method(s(staticSetter=) in s(Class), static, setter)',
+    'Variable(s(staticVariable) in s(Class), static)'],
+    cm.declarations.values.map(stringify),
+    'declarations');
+
+  Expect.setEquals(
+   ['Method(s(*) in s(Mixin))',
+    'Method(s(+) in s(Class))',
+    'Method(s(-) in s(Superclass))',
+    'TypeVariable(s(C) in s(Class),'
+        ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+    'Method(s(Class._generativeConstructor) in s(Class), private, constructor)',
+    'Method(s(Class._normalFactory) in s(Class), private, static, constructor)',
+    'Method(s(Class._redirectingConstructor)'
+        ' in s(Class), private, constructor)',
+    'Method(s(Class._redirectingFactory)'
+        ' in s(Class), private, static, constructor)',
+    'Method(s(Class.generativeConstructor) in s(Class), constructor)',
+    'Method(s(Class.normalFactory) in s(Class), static, constructor)',
+    'Method(s(Class.redirectingConstructor) in s(Class), constructor)',
+    'Method(s(Class.redirectingFactory) in s(Class), static, constructor)',
+    'TypeVariable(s(S) in s(Superclass),'
+        ' upperBound = Class(s(Object) in s(dart.core), top-level))',
+    'Method(s(Superclass._inheritedGenerativeConstructor)'
+        ' in s(Superclass), private, constructor)',
+    'Method(s(Superclass._inheritedNormalFactory)'
+        ' in s(Superclass), private, static, constructor)',
+    'Method(s(Superclass._inheritedRedirectingConstructor)'
+        ' in s(Superclass), private, constructor)',
+    'Method(s(Superclass._inheritedRedirectingFactory)'
+        ' in s(Superclass), private, static, constructor)',
+    'Method(s(Superclass.inheritedGenerativeConstructor)'
+        ' in s(Superclass), constructor)',
+    'Method(s(Superclass.inheritedNormalFactory)'
+        ' in s(Superclass), static, constructor)',
+    'Method(s(Superclass.inheritedRedirectingConstructor)'
+        ' in s(Superclass), constructor)',
+    'Method(s(Superclass.inheritedRedirectingFactory)'
+        ' in s(Superclass), static, constructor)',
+    'Method(s(_inheritedInstanceGetter) in s(Superclass), private, getter)',
+    'Method(s(_inheritedInstanceMethod) in s(Superclass), private)',
+    'Method(s(_inheritedInstanceSetter=) in s(Superclass), private, setter)',
+    'Variable(s(_inheritedInstanceVariable) in s(Superclass), private)',
+    'Method(s(_inheritedStaticGetter)'
+        ' in s(Superclass), private, static, getter)',
+    'Method(s(_inheritedStaticMethod) in s(Superclass), private, static)',
+    'Method(s(_inheritedStaticSetter=)'
+        ' in s(Superclass), private, static, setter)',
+    'Variable(s(_inheritedStaticVariable) in s(Superclass), private, static)',
+    'Method(s(_instanceGetter) in s(Class), private, getter)',
+    'Method(s(_instanceMethod) in s(Class), private)',
+    'Method(s(_instanceSetter=) in s(Class), private, setter)',
+    'Variable(s(_instanceVariable) in s(Class), private)',
+    'Method(s(_mixinInstanceGetter) in s(Mixin), private, getter)',
+    'Method(s(_mixinInstanceMethod) in s(Mixin), private)',
+    'Method(s(_mixinInstanceSetter=) in s(Mixin), private, setter)',
+    'Variable(s(_mixinInstanceVariable) in s(Mixin), private)',
+    'Method(s(_staticGetter) in s(Class), private, static, getter)',
+    'Method(s(_staticMethod) in s(Class), private, static)',
+    'Method(s(_staticSetter=) in s(Class), private, static, setter)',
+    'Variable(s(_staticVariable) in s(Class), private, static)',
+    'Method(s(abstractMethod) in s(Class), abstract)',
+    'Method(s(inheritedInstanceGetter) in s(Superclass), getter)',
+    'Method(s(inheritedInstanceMethod) in s(Superclass))',
+    'Method(s(inheritedInstanceSetter=) in s(Superclass), setter)',
+    'Variable(s(inheritedInstanceVariable) in s(Superclass))',
+    'Method(s(inheritedStaticGetter) in s(Superclass), static, getter)',
+    'Method(s(inheritedStaticMethod) in s(Superclass), static)',
+    'Method(s(inheritedStaticSetter=) in s(Superclass), static, setter)',
+    'Variable(s(inheritedStaticVariable) in s(Superclass), static)',
+    'Method(s(instanceGetter) in s(Class), getter)',
+    'Method(s(instanceMethod) in s(Class))',
+    'Method(s(instanceSetter=) in s(Class), setter)',
+    'Variable(s(instanceVariable) in s(Class))',
+    'Method(s(mixinInstanceGetter) in s(Mixin), getter)',
+    'Method(s(mixinInstanceMethod) in s(Mixin))',
+    'Method(s(mixinInstanceSetter=) in s(Mixin), setter)',
+    'Variable(s(mixinInstanceVariable) in s(Mixin))',
+    'Method(s(staticGetter) in s(Class), static, getter)',
+    'Method(s(staticMethod) in s(Class), static)',
+    'Method(s(staticSetter=) in s(Class), static, setter)',
+    'Variable(s(staticVariable) in s(Class), static)',
+    'Method(s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin._inheritedGenerativeConstructor)'
+        ' in s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin), private, constructor)',
+    'Method(s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin._inheritedRedirectingConstructor)'
+        ' in s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin), private, constructor)',
+    'Method(s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin.inheritedGenerativeConstructor)'
+        ' in s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin), constructor)',
+    'Method(s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin.inheritedRedirectingConstructor)'
+        ' in s(test.declarations_model.Superclass'
+        ' with test.declarations_model.Mixin), constructor)'],
+    inheritedDeclarations(cm)
+        .difference(reflectClass(Object).declarations.values.toSet())
+        .map(stringify),
+    'transitive less Object');
+  // The private members of Object may vary across implementations, so we
+  // exclude the declarations of Object in this test case.
+}
diff --git a/tests/lib/mirrors/class_mirror_type_variables_test.dart b/tests/lib/mirrors/class_mirror_type_variables_test.dart
index 9694ee4..51da82e 100644
--- a/tests/lib/mirrors/class_mirror_type_variables_test.dart
+++ b/tests/lib/mirrors/class_mirror_type_variables_test.dart
@@ -66,16 +66,16 @@
 
   Expect.equals(b, bZ.owner);
   Expect.equals(c, cZ.owner);
-  Expect.equals(b, bZBoundTypeVariable.owner); /// 01: ok
-  Expect.equals(b, cZBoundTypeVariable.owner); /// 01: ok
+  Expect.equals(b, bZBoundTypeVariable.owner);
+  Expect.equals(b, cZBoundTypeVariable.owner);
   Expect.equals(b, bZBoundTypeArgument.owner);
   Expect.equals(c, cZBoundTypeArgument.owner);
 
   Expect.notEquals(bZ, cZ);
   Expect.equals(bZ, bZBoundTypeArgument);
   Expect.equals(cZ, cZBoundTypeArgument);
-  Expect.equals(bZ, bZBoundTypeVariable); /// 01: ok
-  Expect.equals(bZ, cZBoundTypeVariable); /// 01: ok
+  Expect.equals(bZ, bZBoundTypeVariable);
+  Expect.equals(bZ, cZBoundTypeVariable);
 }
 
 testD() {
diff --git a/tests/lib/mirrors/declarations_model.dart b/tests/lib/mirrors/declarations_model.dart
new file mode 100644
index 0000000..353fe13
--- /dev/null
+++ b/tests/lib/mirrors/declarations_model.dart
@@ -0,0 +1,166 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.declarations_model;
+
+var libraryVariable;
+get libraryGetter => null;
+set librarySetter(x) => x;
+libraryMethod() => null;
+
+var _libraryVariable;
+get _libraryGetter => null;
+set _librarySetter(x) => x;
+_libraryMethod() => null;
+
+typedef bool Predicate(dynamic);
+
+abstract class Interface<I> {
+  operator /(x) => null;
+
+  var interfaceInstanceVariable;
+  get interfaceInstanceGetter;
+  set interfaceInstanceSetter(x);
+  interfaceInstanceMethod();
+
+  var _interfaceInstanceVariable;
+  get _interfaceInstanceGetter;
+  set _interfaceInstanceSetter(x);
+  _interfaceInstanceMethod();
+
+  static var interfaceStaticVariable;
+  static get interfaceStaticGetter => null;
+  static set interfaceStaticSetter(x) => x;
+  static interfaceStaticMethod() => null;
+
+  static var _interfaceStaticVariable;
+  static get _interfaceStaticGetter => null;
+  static set _interfaceStaticSetter(x) => x;
+  static _interfaceStaticMethod() => null;
+}
+
+class Mixin<M> {
+  operator *(x) => null;
+
+  var mixinInstanceVariable;
+  get mixinInstanceGetter => null;
+  set mixinInstanceSetter(x) => x;
+  mixinInstanceMethod() => null;
+
+  var _mixinInstanceVariable;
+  get _mixinInstanceGetter => null;
+  set _mixinInstanceSetter(x) => x;
+  _mixinInstanceMethod() => null;
+
+  static var mixinStaticVariable;
+  static get mixinStaticGetter => null;
+  static set mixinStaticSetter(x) => x;
+  static mixinStaticMethod() => null;
+
+  static var _mixinStaticVariable;
+  static get _mixinStaticGetter => null;
+  static set _mixinStaticSetter(x) => x;
+  static _mixinStaticMethod() => null;
+}
+
+class Superclass<S> {
+  operator -(x) => null;
+
+  var inheritedInstanceVariable;
+  get inheritedInstanceGetter => null;
+  set inheritedInstanceSetter(x) => x;
+  inheritedInstanceMethod() => null;
+
+  var _inheritedInstanceVariable;
+  get _inheritedInstanceGetter => null;
+  set _inheritedInstanceSetter(x) => x;
+  _inheritedInstanceMethod() => null;
+
+  static var inheritedStaticVariable;
+  static get inheritedStaticGetter => null;
+  static set inheritedStaticSetter(x) => x;
+  static inheritedStaticMethod() => null;
+
+  static var _inheritedStaticVariable;
+  static get _inheritedStaticGetter => null;
+  static set _inheritedStaticSetter(x) => x;
+  static _inheritedStaticMethod() => null;
+
+  Superclass.inheritedGenerativeConstructor(this.inheritedInstanceVariable);
+  Superclass.inheritedRedirectingConstructor(x)
+      : this.inheritedGenerativeConstructor(x*2);
+  factory Superclass.inheritedNormalFactory(y)
+      => new Superclass.inheritedRedirectingConstructor(y*3);
+  factory Superclass.inheritedRedirectingFactory(z)
+      = Superclass.inheritedNormalFactory;
+
+  Superclass._inheritedGenerativeConstructor(this._inheritedInstanceVariable);
+  Superclass._inheritedRedirectingConstructor(x)
+      : this._inheritedGenerativeConstructor(x*2);
+  factory Superclass._inheritedNormalFactory(y)
+      => new Superclass._inheritedRedirectingConstructor(y*3);
+  factory Superclass._inheritedRedirectingFactory(z)
+      = Superclass._inheritedNormalFactory;
+}
+
+abstract class Class<C>
+    extends Superclass<C> with Mixin<C> implements Interface<C> {
+  operator +(x) => null;
+
+  abstractMethod();
+
+  var instanceVariable;
+  get instanceGetter => null;
+  set instanceSetter(x) => x;
+  instanceMethod() => null;
+
+  var _instanceVariable;
+  get _instanceGetter => null;
+  set _instanceSetter(x) => x;
+  _instanceMethod() => null;
+
+  static var staticVariable;
+  static get staticGetter => null;
+  static set staticSetter(x) => x;
+  static staticMethod() => null;
+
+  static var _staticVariable;
+  static get _staticGetter => null;
+  static set _staticSetter(x) => x;
+  static _staticMethod() => null;
+
+  Class.generativeConstructor(this.instanceVariable)
+      : super.inheritedGenerativeConstructor(0);
+  Class.redirectingConstructor(x)
+      : this.generativeConstructor(x*2);
+  factory Class.normalFactory(y) => new ConcreteClass(y*3);
+  factory Class.redirectingFactory(z) = Class.normalFactory;
+
+  Class._generativeConstructor(this._instanceVariable)
+      : super._inheritedGenerativeConstructor(0);
+  Class._redirectingConstructor(x) : this._generativeConstructor(x*2);
+  factory Class._normalFactory(y) => new ConcreteClass(y*3);
+  factory Class._redirectingFactory(z) = Class._normalFactory;
+}
+
+// This is just here as a target of Class's factories to appease the analyzer.
+class ConcreteClass<CC> extends Class<CC> {
+  abstractMethod() {}
+
+  operator /(x) => null;
+
+  var interfaceInstanceVariable;
+  get interfaceInstanceGetter => null;
+  set interfaceInstanceSetter(x) => null;
+  interfaceInstanceMethod() => null;
+
+  var _interfaceInstanceVariable;
+  get _interfaceInstanceGetter => null;
+  set _interfaceInstanceSetter(x) => null;
+  _interfaceInstanceMethod() => null;
+
+  ConcreteClass(x) : super.generativeConstructor(x);
+}
+
+class _PrivateClass {}
diff --git a/tests/lib/mirrors/generic_type_mirror_test.dart b/tests/lib/mirrors/generic_type_mirror_test.dart
new file mode 100644
index 0000000..6b25a39
--- /dev/null
+++ b/tests/lib/mirrors/generic_type_mirror_test.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+class Foo<W, V> {
+  V field;
+  V get bar => field;
+  set bar(V v) {}
+  W m() {}
+  V n() {}
+  o(W w) {}
+}
+
+class Bar {}
+class Baz {}
+
+main() {
+  testInstance();
+  testOriginalDeclaration();
+}
+
+void testInstance() {
+  ClassMirror foo = reflect((new Foo<Bar, Baz>())).type;
+  ClassMirror bar = reflect(new Bar()).type;
+  ClassMirror baz = reflect(new Baz()).type;
+  VariableMirror field = foo.variables.values.single;
+  MethodMirror getter = foo.getters.values.single;
+  MethodMirror setter = foo.setters.values.single;
+  MethodMirror m = foo.methods[const Symbol('m')];
+  MethodMirror n = foo.methods[const Symbol('n')];
+  MethodMirror o = foo.methods[const Symbol('o')];
+
+  Expect.equals(foo, field.owner);
+  Expect.equals(foo, getter.owner);
+  Expect.equals(foo, setter.owner);
+  Expect.equals(foo, m.owner);
+  Expect.equals(foo, n.owner);
+  Expect.equals(foo, o.owner);
+
+  Expect.equals(baz, field.type); /// 01: ok
+  Expect.equals(baz, getter.returnType);
+  Expect.equals(bar, m.returnType);
+  Expect.equals(baz, n.returnType);
+  Expect.equals(bar, o.parameters.single.type);
+  Expect.equals(baz, setter.parameters.single.type);
+
+}
+
+void testOriginalDeclaration() {
+  ClassMirror foo = reflectClass(Foo);
+
+  VariableMirror field = foo.variables.values.single;
+  MethodMirror getter = foo.getters.values.single;
+  MethodMirror setter = foo.setters.values.single;
+  MethodMirror m = foo.methods[const Symbol('m')];
+  MethodMirror n = foo.methods[const Symbol('n')];
+  MethodMirror o = foo.methods[const Symbol('o')];
+  TypeVariableMirror w = foo.typeVariables[0];
+  TypeVariableMirror v = foo.typeVariables[1];
+
+  Expect.equals(foo, field.owner);
+  Expect.equals(foo, getter.owner);
+  Expect.equals(foo, setter.owner);
+  Expect.equals(foo, m.owner);
+  Expect.equals(foo, n.owner);
+  Expect.equals(foo, o.owner);
+
+  Expect.equals(v, field.type); /// 01: ok
+  Expect.equals(v, getter.returnType);
+  Expect.equals(w, m.returnType);
+  Expect.equals(v, n.returnType);
+  Expect.equals(w, o.parameters.single.type);
+  Expect.equals(v, setter.parameters.single.type);
+
+}
\ No newline at end of file
diff --git a/tests/lib/mirrors/library_declarations_test.dart b/tests/lib/mirrors/library_declarations_test.dart
new file mode 100644
index 0000000..d91e727
--- /dev/null
+++ b/tests/lib/mirrors/library_declarations_test.dart
@@ -0,0 +1,122 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.library_declarations_test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'stringify.dart';
+import 'declarations_model.dart' as declarations_model;
+
+main() {
+  LibraryMirror lm =
+      currentMirrorSystem().findLibrary(#test.declarations_model).single;
+
+  Expect.setEquals(
+   ['Variable(s(_libraryVariable)'
+        ' in s(test.declarations_model), private, top-level, static)',
+    'Variable(s(libraryVariable)'
+        ' in s(test.declarations_model), top-level, static)'],
+    lm.declarations.values.where((dm) => dm is VariableMirror).map(stringify),
+    'variables');
+
+  // dart2js stops testing here.
+  return;  /// 01: ok
+
+  Expect.setEquals(
+   ['Method(s(_libraryGetter)'
+        ' in s(test.declarations_model), private, top-level, static, getter)',
+    'Method(s(libraryGetter)'
+        ' in s(test.declarations_model), top-level, static, getter)'],
+    lm.declarations.values
+        .where((dm) => dm is MethodMirror && dm.isGetter).map(stringify),
+    'getters');
+
+  Expect.setEquals(
+   ['Method(s(_librarySetter=)'
+        ' in s(test.declarations_model), private, top-level, static, setter)',
+    'Method(s(librarySetter=)'
+        ' in s(test.declarations_model), top-level, static, setter)'],
+    lm.declarations.values
+        .where((dm) => dm is MethodMirror && dm.isSetter).map(stringify),
+    'setters');
+
+  Expect.setEquals(
+   ['Method(s(_libraryMethod)'
+        ' in s(test.declarations_model), private, top-level, static)',
+    'Method(s(libraryMethod)'
+        ' in s(test.declarations_model), top-level, static)'],
+    lm.declarations.values
+        .where((dm) => dm is MethodMirror && dm.isRegularMethod).map(stringify),
+    'regular methods');
+
+  Expect.setEquals(
+   ['Class(s(Class) in s(test.declarations_model), top-level)',
+    'Class(s(ConcreteClass) in s(test.declarations_model), top-level)',
+    'Class(s(Interface) in s(test.declarations_model), top-level)',
+    'Class(s(Mixin) in s(test.declarations_model), top-level)',
+    'Class(s(Superclass) in s(test.declarations_model), top-level)',
+    'Class(s(_PrivateClass)'
+        ' in s(test.declarations_model), private, top-level)'],
+    lm.declarations.values
+        .where((dm) => dm is ClassMirror).map(stringify),
+    'classes');
+
+  Expect.setEquals(
+   ['Class(s(Class) in s(test.declarations_model), top-level)',
+    'Class(s(ConcreteClass) in s(test.declarations_model), top-level)',
+    'Class(s(Interface) in s(test.declarations_model), top-level)',
+    'Class(s(Mixin) in s(test.declarations_model), top-level)',
+    'Type(s(Predicate) in s(test.declarations_model), top-level)',
+    'Class(s(Superclass) in s(test.declarations_model), top-level)',
+    'Class(s(_PrivateClass)'
+        ' in s(test.declarations_model), private, top-level)'],
+    lm.declarations.values.where((dm) => dm is TypeMirror).map(stringify),
+    'types');
+
+  Expect.setEquals(
+   ['Class(s(Class) in s(test.declarations_model), top-level)',
+    'Class(s(ConcreteClass) in s(test.declarations_model), top-level)',
+    'Class(s(Interface) in s(test.declarations_model), top-level)',
+    'Class(s(Mixin) in s(test.declarations_model), top-level)',
+    'Type(s(Predicate) in s(test.declarations_model), top-level)',
+    'Class(s(Superclass) in s(test.declarations_model), top-level)',
+    'Method(s(libraryGetter)'
+      ' in s(test.declarations_model), top-level, static, getter)',
+    'Method(s(libraryMethod)'
+      ' in s(test.declarations_model), top-level, static)',
+    'Method(s(librarySetter=)'
+      ' in s(test.declarations_model), top-level, static, setter)',
+    'Variable(s(libraryVariable)'
+      ' in s(test.declarations_model), top-level, static)'],
+    lm.declarations.values.where((dm) => !dm.isPrivate).map(stringify),
+    'public');
+
+  Expect.setEquals(
+   ['Class(s(Class) in s(test.declarations_model), top-level)',
+    'Class(s(ConcreteClass) in s(test.declarations_model), top-level)',
+    'Class(s(Interface) in s(test.declarations_model), top-level)',
+    'Class(s(Mixin) in s(test.declarations_model), top-level)',
+    'Type(s(Predicate) in s(test.declarations_model), top-level)',
+    'Class(s(Superclass) in s(test.declarations_model), top-level)',
+    'Class(s(_PrivateClass) in s(test.declarations_model), private, top-level)',
+    'Method(s(_libraryGetter)'
+        ' in s(test.declarations_model), private, top-level, static, getter)',
+    'Method(s(_libraryMethod)'
+        ' in s(test.declarations_model), private, top-level, static)',
+    'Method(s(_librarySetter=)'
+        ' in s(test.declarations_model), private, top-level, static, setter)',
+    'Variable(s(_libraryVariable)'
+        ' in s(test.declarations_model), private, top-level, static)',
+    'Method(s(libraryGetter)'
+        ' in s(test.declarations_model), top-level, static, getter)',
+    'Method(s(libraryMethod) in s(test.declarations_model), top-level, static)',
+    'Method(s(librarySetter=)'
+        ' in s(test.declarations_model), top-level, static, setter)',
+    'Variable(s(libraryVariable)'
+        ' in s(test.declarations_model), top-level, static)'],
+    lm.declarations.values.map(stringify),
+    'all declarations');
+}
diff --git a/tests/lib/mirrors/redirecting_factory_test.dart b/tests/lib/mirrors/redirecting_factory_test.dart
index 6509069..6f0ddf2 100644
--- a/tests/lib/mirrors/redirecting_factory_test.dart
+++ b/tests/lib/mirrors/redirecting_factory_test.dart
@@ -14,28 +14,28 @@
   factory Class.redirectingFactoryNoOptional(a, b) = Class.factoryNoOptional;
 
   factory Class.factoryUnnamedOptional(a, [b = 42]) => new Class<T1, T2>(a - b);
-  factory Class.redirectingFactoryUnnamedOptional(a, [b = 5]) =
+  factory Class.redirectingFactoryUnnamedOptional(a, [b]) =
       Class.factoryUnnamedOptional;
 
   factory Class.factoryNamedOptional(a, {b: 42}) {
     return new Class<T1, T2>(a - b);
   }
 
-  factory Class.redirectingFactoryNamedOptional(a, {b: 5}) =
+  factory Class.redirectingFactoryNamedOptional(a, {b}) =
       Class.factoryNamedOptional;
 
   factory Class.factoryMoreNamedOptional(a, {b: 0, c: 2}) {
     return new Class<T1, T2>(a - b - c);
   }
 
-  factory Class.redirectingFactoryMoreNamedOptional(a, {b: 42}) =
+  factory Class.redirectingFactoryMoreNamedOptional(a, {b}) =
       Class.factoryMoreNamedOptional;
 
   factory Class.factoryMoreUnnamedOptional(a, [b = 0, c = 2]) {
     return new Class<T1, T2>(a - b - c);
   }
 
-  factory Class.redirectingFactoryMoreUnnamedOptional(a, [b = 42]) =
+  factory Class.redirectingFactoryMoreUnnamedOptional(a, [b]) =
       Class.factoryMoreUnnamedOptional;
 
   factory Class.redirectingFactoryStringIntTypeParameters(a, b) =
diff --git a/tests/lib/mirrors/regress_14304_test.dart b/tests/lib/mirrors/regress_14304_test.dart
new file mode 100644
index 0000000..e63cae0
--- /dev/null
+++ b/tests/lib/mirrors/regress_14304_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for Issue 14304.
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+class A<T> {
+  T m() {}
+}
+
+main() {
+  ClassMirror a = reflectClass(A);
+  TypeVariableMirror t = a.typeVariables[0];
+  MethodMirror m = a.methods.values.single;
+  
+  Expect.equals(t, m.returnType);
+}
\ No newline at end of file
diff --git a/tests/lib/mirrors/stringify.dart b/tests/lib/mirrors/stringify.dart
index 369f2c1..364bdcf 100644
--- a/tests/lib/mirrors/stringify.dart
+++ b/tests/lib/mirrors/stringify.dart
@@ -105,6 +105,7 @@
 stringifyMethod(MethodMirror method) {
   var buffer = new StringBuffer();
   writeDeclarationOn(method, buffer);
+  if (method.isAbstract) buffer.write(', abstract');
   if (method.isStatic) buffer.write(', static');
   if (method.isGetter) buffer.write(', getter');
   if (method.isSetter) buffer.write(', setter');
diff --git a/tests/lib/mirrors/unnamed_library_test.dart b/tests/lib/mirrors/unnamed_library_test.dart
index 1e81eaa..b967689 100644
--- a/tests/lib/mirrors/unnamed_library_test.dart
+++ b/tests/lib/mirrors/unnamed_library_test.dart
@@ -8,8 +8,14 @@
 
 import 'package:expect/expect.dart';
 
-class C {}
+class Class {}
 
 main() {
-  Expect.equals(const Symbol(""), reflectClass(C).owner.simpleName);
+  ClassMirror cm = reflectClass(Class);
+  LibraryMirror lm = cm.owner;
+
+  Expect.equals('Class', MirrorSystem.getName(cm.simpleName));
+  Expect.equals('.Class', MirrorSystem.getName(cm.qualifiedName));
+  Expect.equals('', MirrorSystem.getName(lm.simpleName));
+  Expect.equals('', MirrorSystem.getName(lm.qualifiedName));
 }
diff --git a/tests/lib/platform/environment_test.dart b/tests/lib/platform/environment_test.dart
new file mode 100644
index 0000000..3d2da6a
--- /dev/null
+++ b/tests/lib/platform/environment_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.
+
+import "dart:platform" as platform;
+
+import "package:unittest/unittest.dart";
+
+main() {
+  if (platform.operatingSystem != null) {
+    expect(platform.environment, new isInstanceOf<Map<String, String>>());
+  } else {
+    expect(platform.environment, isNull);
+  }
+}
+
diff --git a/tests/lib/platform/executable_arguments_test.dart b/tests/lib/platform/executable_arguments_test.dart
new file mode 100644
index 0000000..8fbf032
--- /dev/null
+++ b/tests/lib/platform/executable_arguments_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:platform" as platform;
+
+import "package:unittest/unittest.dart";
+
+main() {
+  expect(platform.executableArguments is List<String>, true);
+}
diff --git a/tests/lib/platform/executable_test.dart b/tests/lib/platform/executable_test.dart
new file mode 100644
index 0000000..fee4539
--- /dev/null
+++ b/tests/lib/platform/executable_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.
+
+import "dart:platform" as platform;
+
+import "package:unittest/unittest.dart";
+
+main() {
+  if (platform.operatingSystem != null) {
+    expect(platform.executable, contains('dart'));
+  } else {
+    expect(platform.executable, isNull);
+  }
+}
+
diff --git a/tests/lib/platform/import_test.dart b/tests/lib/platform/import_test.dart
new file mode 100644
index 0000000..fcd326f
--- /dev/null
+++ b/tests/lib/platform/import_test.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:platform";
+
+void main() {
+}
diff --git a/tests/lib/platform/isolate_test.dart b/tests/lib/platform/isolate_test.dart
new file mode 100644
index 0000000..b53f088
--- /dev/null
+++ b/tests/lib/platform/isolate_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 "dart:platform" as platform;
+
+import "dart:isolate";
+import "package:unittest/unittest.dart";
+
+sendReceive(SendPort port, msg) {
+  var response = new ReceivePort();
+  port.send([msg, response.sendPort]);
+  return response.first;
+}
+
+main() {
+  test("platform in isolate", () {
+    var response = new ReceivePort();
+    Isolate.spawn(f, response.sendPort);
+    response.first.then(expectAsync1((sendPort) {
+      expect(sendReceive(sendPort, "platform.executable"),
+            completion(platform.executable));
+      if (platform.script != null) {
+        expect(sendReceive(sendPort, "platform.script").then((s) => s.path),
+              completion(endsWith('tests/lib/platform/isolate_test.dart')));
+      }
+      expect(sendReceive(sendPort, "platform.packageRoot"),
+            completion(platform.packageRoot));
+      expect(sendReceive(sendPort, "platform.executableArguments"),
+            completion(platform.executableArguments));
+    }));
+  });
+}
+
+void f(initialReplyTo) {
+  var port = new ReceivePort();
+  initialReplyTo.send(port.sendPort);
+  int count = 0;
+  port.listen((msg) {
+    var data = msg[0];
+    var replyTo = msg[1];
+    if (data == "platform.executable") {
+      replyTo.send(platform.executable);
+    }
+    if (data == "platform.script") {
+      replyTo.send(platform.script);
+    }
+    if (data == "platform.packageRoot") {
+      replyTo.send(platform.packageRoot);
+    }
+    if (data == "platform.executableArguments") {
+      replyTo.send(platform.executableArguments);
+    }
+    count++;
+    if (count == 4) {
+      port.close();
+    }
+  });
+}
diff --git a/tests/lib/platform/local_hostname_test.dart b/tests/lib/platform/local_hostname_test.dart
new file mode 100644
index 0000000..2095ce0
--- /dev/null
+++ b/tests/lib/platform/local_hostname_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.
+
+import "dart:platform" as platform;
+
+import "package:unittest/unittest.dart";
+
+main() {
+  if (platform.operatingSystem != null) {
+    expect(platform.localHostname, new isInstanceOf<String>());
+    expect(platform.localHostname, isNot(''));
+  } else {
+    expect(platform.localHostname, isNull);
+  }
+}
diff --git a/tests/lib/platform/number_of_processors_test.dart b/tests/lib/platform/number_of_processors_test.dart
new file mode 100644
index 0000000..043914d
--- /dev/null
+++ b/tests/lib/platform/number_of_processors_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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:platform" as platform;
+
+import "package:unittest/unittest.dart";
+
+main() {
+  if (platform.operatingSystem != null) {
+    expect(platform.numberOfProcessors, isPositive);
+  } else {
+    expect(platform.numberOfProcessors, isNull);
+  }
+}
diff --git a/tests/lib/platform/operating_system_test.dart b/tests/lib/platform/operating_system_test.dart
new file mode 100644
index 0000000..b121833
--- /dev/null
+++ b/tests/lib/platform/operating_system_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:platform" as platform;
+
+import "package:unittest/unittest.dart";
+
+main() {
+  if (platform.operatingSystem != null) {
+    expect(platform.operatingSystem,
+           isIn(['linux', 'macos', 'windows', 'android']));
+  }
+}
diff --git a/tests/lib/platform/package_root_test.dart b/tests/lib/platform/package_root_test.dart
new file mode 100644
index 0000000..7d5de6a
--- /dev/null
+++ b/tests/lib/platform/package_root_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.
+
+import "dart:platform" as platform;
+
+import "package:unittest/unittest.dart";
+
+main() {
+  if (platform.operatingSystem != null) {
+    expect(platform.packageRoot is String, true);
+    expect(platform.packageRoot, isNot(''));
+  } else {
+    expect(platform.packageRoot, isNull);
+  }
+}
diff --git a/tests/lib/platform/path_separator_test.dart b/tests/lib/platform/path_separator_test.dart
new file mode 100644
index 0000000..2a7a595
--- /dev/null
+++ b/tests/lib/platform/path_separator_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for 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:platform" as platform;
+
+import "package:unittest/unittest.dart";
+
+main() {
+  if (platform.operatingSystem == 'windows') {
+    expect(platform.pathSeparator, '\\');
+  } else {
+    expect(platform.pathSeparator, isIn(['/', null]));
+  }
+}
diff --git a/tests/lib/platform/script_test.dart b/tests/lib/platform/script_test.dart
new file mode 100644
index 0000000..e7ce111
--- /dev/null
+++ b/tests/lib/platform/script_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.
+
+import "dart:platform" as platform;
+
+import "package:unittest/unittest.dart";
+
+main() {
+  if (platform.operatingSystem != null) {
+    expect(platform.script.path,
+           endsWith('tests/lib/platform/script_test.dart'));
+  } else {
+    expect(platform.script, isNull);
+  }
+}
diff --git a/tests/lib/platform/uri_test.dart b/tests/lib/platform/uri_test.dart
new file mode 100644
index 0000000..bca7b6d
--- /dev/null
+++ b/tests/lib/platform/uri_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:platform" as platform;
+
+main() {
+  if (platform.operatingSystem == 'windows') {
+    Expect.equals("a\\b", Uri.parse("a/b").toFilePath());
+    Expect.equals("a\\b\\", Uri.parse("a/b/").toFilePath());
+    Expect.equals("a b", Uri.parse("a%20b").toFilePath());
+    Expect.equals("\\a b", Uri.parse("file:///a%20b").toFilePath());
+    Expect.equals("\\a\\b", Uri.parse("file:///a/b").toFilePath());
+    Expect.equals("C:\\", Uri.parse("file:///C:").toFilePath());
+    Expect.equals("C:\\", Uri.parse("file:///C:/").toFilePath());
+    Expect.equals("\\\\host\\a\\b", Uri.parse("file://host/a/b").toFilePath());
+
+    Expect.equals("a\\b", new Uri.file("a/b").toFilePath());
+    Expect.equals("a\\b", new Uri.file("a\\b").toFilePath());
+    Expect.equals("\\a\\b", new Uri.file("/a/b").toFilePath());
+    Expect.equals("\\a\\b", new Uri.file("\\a\\b").toFilePath());
+    Expect.equals("\\a\\b", new Uri.file("\\a/b").toFilePath());
+    Expect.equals("\\a\\b", new Uri.file("/a\\b").toFilePath());
+  } else {
+    Expect.equals("a/b", Uri.parse("a/b").toFilePath());
+    Expect.equals("a/b/", Uri.parse("a/b/").toFilePath());
+    Expect.equals("a b", Uri.parse("a%20b").toFilePath());
+    Expect.equals("/a b", Uri.parse("file:///a%20b").toFilePath());
+    Expect.equals("/a/b", Uri.parse("file:///a/b").toFilePath());
+    Expect.equals("/C:", Uri.parse("file:///C:").toFilePath());
+    Expect.equals("/C:/", Uri.parse("file:///C:/").toFilePath());
+    Expect.throws(() => Uri.parse("file://host/a/b").toFilePath(),
+                  (e) => e is UnsupportedError);
+
+    Expect.equals("a/b", new Uri.file("a/b").toFilePath());
+    Expect.equals("a\\b", new Uri.file("a\\b").toFilePath());
+  }
+}
diff --git a/tests/standalone/http_launch_data/http_isolate_main.dart b/tests/standalone/http_launch_data/http_isolate_main.dart
index ba7a59d..ad6306a 100644
--- a/tests/standalone/http_launch_data/http_isolate_main.dart
+++ b/tests/standalone/http_launch_data/http_isolate_main.dart
@@ -4,8 +4,7 @@
 
 import 'dart:isolate';
 
-main() {
-  port.receive((message, replyTo) {
-    replyTo.call(message);
-  });
+main(List<String> args, SendPort replyTo) {
+  var data = args[0];
+  replyTo.send(data);
 }
diff --git a/tests/standalone/http_launch_data/http_launch_main.dart b/tests/standalone/http_launch_data/http_launch_main.dart
index bd35bae..fb69fbb 100644
--- a/tests/standalone/http_launch_data/http_launch_main.dart
+++ b/tests/standalone/http_launch_data/http_launch_main.dart
@@ -3,11 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-library http_lanuch_main;
+library http_launch_main;
 
 import 'package:simple/simple.dart';
 
 main() {
   print(getSimpleString());
 }
-
diff --git a/tests/standalone/http_launch_data/http_spawn_main.dart b/tests/standalone/http_launch_data/http_spawn_main.dart
index 3960ea6..60fe473 100644
--- a/tests/standalone/http_launch_data/http_spawn_main.dart
+++ b/tests/standalone/http_launch_data/http_spawn_main.dart
@@ -2,17 +2,17 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library http_lanuch_main;
+library http_launch_main;
 
 import 'dart:isolate';
 import 'dart:io';
 
 main(List<String> arguments) {
   int port = int.parse(arguments[0]);
-  SendPort spawnedPort =
-      spawnUri('http://127.0.0.1:$port/http_isolate_main.dart');
-  spawnedPort.call('hello').then((response) {
+  ReceivePort receivePort = new ReceivePort();
+  Isolate.spawnUri(Uri.parse('http://127.0.0.1:$port/http_isolate_main.dart'),
+                   ['hello'], receivePort.sendPort);
+  receivePort.first.then((response) {
     print(response);
   });
 }
-
diff --git a/tests/standalone/io/async_catch_errors_test.dart b/tests/standalone/io/async_catch_errors_test.dart
index 0a9568d..4ebccb6 100644
--- a/tests/standalone/io/async_catch_errors_test.dart
+++ b/tests/standalone/io/async_catch_errors_test.dart
@@ -24,14 +24,14 @@
   return completer.future;
 }
 
-Future testFileException() {
+Future testFileSystemException() {
   var completer = new Completer();
   runZoned(() {
     new File("lol it's not a file\n").openRead().listen(null);
   }, onError: (err) {
-    if (err is! FileException) Expect.fail("Not expected error: $err");
+    if (err is! FileSystemException) Expect.fail("Not expected error: $err");
     completer.complete("file test, ok.");
-    events.add("FileException");
+    events.add("FileSystemException");
   });
   return completer.future;
 }
@@ -41,10 +41,10 @@
   // hang if the callbacks are not invoked and the test will time out.
   asyncStart();
   testSocketException()
-    .then((_) => testFileException())
+    .then((_) => testFileSystemException())
     .then((_) {
       asyncEnd();
-      Expect.listEquals(["SocketException", "FileException"],
+      Expect.listEquals(["SocketException", "FileSystemException"],
                         events);
     });
 }
diff --git a/tests/standalone/io/code_collection_test.dart b/tests/standalone/io/code_collection_test.dart
new file mode 100644
index 0000000..0cc3698
--- /dev/null
+++ b/tests/standalone/io/code_collection_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Dart test program testing code GC.
+
+import "package:expect/expect.dart";
+import "dart:async";
+import "dart:io";
+
+
+int foo(int x) {
+  x = x + 1;
+  return x;
+}
+
+
+List<int> bar() {
+  // A couple of big allocations trigger GC.
+  var l = new List.filled(700000, 7);
+  return l;
+}
+
+
+doTest() {
+ var i = 0;
+  foo(1);  // Initial call to compile.
+  // Time passes, GC runs, foo's code is dropped.
+  var ms = const Duration(milliseconds: 100);
+  var t = new Timer.periodic(ms, (timer) {
+    i++;
+    bar();
+    if (i > 1) {
+      timer.cancel();
+      // foo is called again to make sure we can still run it even after
+      // its code has been detached.
+      foo(2);
+    }
+  });
+}
+
+
+main() {
+  var opts = new Options();
+  if (opts.arguments.contains("--run")) {
+    doTest();
+  } else {
+    // Run the test and capture stdout.
+    var pr = Process.runSync(Platform.executable,
+        ["--collect-code",
+         "--code-collection-interval-in-us=100000",
+         "--log-code-drop",
+         "--optimization-counter-threshold=-1",
+         "--package-root=${Platform.packageRoot}",
+         Platform.script,
+         "--run"]);
+
+    // Code drops are logged with --log-code-drop. Look through stdout for the
+    // message that foo's code was dropped.
+    var found = false;
+    pr.stdout.split("\n").forEach((line) {
+      if (line.contains("Detaching code") && line.contains("foo")) {
+        found = true;
+      }
+    });
+    Expect.isTrue(found);
+  }
+}
\ No newline at end of file
diff --git a/tests/standalone/io/directory_chdir_test.dart b/tests/standalone/io/directory_chdir_test.dart
index 1833d54..3613aad 100644
--- a/tests/standalone/io/directory_chdir_test.dart
+++ b/tests/standalone/io/directory_chdir_test.dart
@@ -31,7 +31,7 @@
     Expect.throws(() {
       temp.deleteSync(recursive: true);
       Directory.current;
-    }, (e) => e is DirectoryException);
+    }, (e) => e is FileSystemException);
     Directory.current = initialCurrent;
     Directory.current;
     if (temp.existsSync()) temp.deleteSync(recursive: true);
diff --git a/tests/standalone/io/directory_error_test.dart b/tests/standalone/io/directory_error_test.dart
index 5271060..2fb6845 100644
--- a/tests/standalone/io/directory_error_test.dart
+++ b/tests/standalone/io/directory_error_test.dart
@@ -15,8 +15,8 @@
 }
 
 
-bool checkCreateInNonExistentFileException(e) {
-  Expect.isTrue(e is DirectoryException);
+bool checkCreateInNonExistentFileSystemException(e) {
+  Expect.isTrue(e is FileSystemException);
   Expect.isTrue(e.osError != null);
   Expect.isTrue(e.toString().indexOf("Creation failed") != -1);
   if (Platform.operatingSystem == "linux") {
@@ -34,17 +34,17 @@
 void testCreateInNonExistent(Directory temp, Function done) {
   Directory inNonExistent = new Directory("${temp.path}/nonExistent/xxx");
   Expect.throws(() => inNonExistent.createSync(),
-                (e) => checkCreateInNonExistentFileException(e));
+                (e) => checkCreateInNonExistentFileSystemException(e));
 
   inNonExistent.create().catchError((error) {
-    checkCreateInNonExistentFileException(error);
+    checkCreateInNonExistentFileSystemException(error);
     done();
   });
 }
 
 
-bool checkCreateTempInNonExistentFileException(e) {
-  Expect.isTrue(e is DirectoryException);
+bool checkCreateTempInNonExistentFileSystemException(e) {
+  Expect.isTrue(e is FileSystemException);
   Expect.isTrue(e.osError != null);
   if (Platform.operatingSystem == "linux") {
     Expect.equals(2, e.osError.errorCode);
@@ -61,17 +61,17 @@
 void testCreateTempInNonExistent(Directory temp, Function done) {
   Directory nonExistent = new Directory("${temp.path}/nonExistent/xxx");
   Expect.throws(() => nonExistent.createTempSync('tempdir'),
-                (e) => checkCreateTempInNonExistentFileException(e));
+                (e) => checkCreateTempInNonExistentFileSystemException(e));
 
   nonExistent.createTemp('tempdir').catchError((error) {
-    checkCreateTempInNonExistentFileException(error);
+    checkCreateTempInNonExistentFileSystemException(error);
     done();
   });
 }
 
 
-bool checkDeleteNonExistentFileException(e) {
-  Expect.isTrue(e is DirectoryException);
+bool checkDeleteNonExistentFileSystemException(e) {
+  Expect.isTrue(e is FileSystemException);
   Expect.isTrue(e.osError != null);
   // File not not found has error code 2 on all supported platforms.
   Expect.equals(2, e.osError.errorCode);
@@ -83,17 +83,17 @@
 void testDeleteNonExistent(Directory temp, Function done) {
   Directory nonExistent = new Directory("${temp.path}/nonExistent");
   Expect.throws(() => nonExistent.deleteSync(),
-                (e) => checkDeleteNonExistentFileException(e));
+                (e) => checkDeleteNonExistentFileSystemException(e));
 
   nonExistent.delete().catchError((error) {
-    checkDeleteNonExistentFileException(error);
+    checkDeleteNonExistentFileSystemException(error);
     done();
   });
 }
 
 
-bool checkDeleteRecursivelyNonExistentFileException(e) {
-  Expect.isTrue(e is DirectoryException);
+bool checkDeleteRecursivelyNonExistentFileSystemException(e) {
+  Expect.isTrue(e is FileSystemException);
   Expect.isTrue(e.osError != null);
   Expect.isTrue(e.toString().indexOf("Deletion failed") != -1);
   // File not not found has error code 2 on all supported platforms.
@@ -106,17 +106,17 @@
 void testDeleteRecursivelyNonExistent(Directory temp, Function done) {
   Directory nonExistent = new Directory("${temp.path}/nonExistent");
   Expect.throws(() => nonExistent.deleteSync(recursive: true),
-                (e) => checkDeleteRecursivelyNonExistentFileException(e));
+                (e) => checkDeleteRecursivelyNonExistentFileSystemException(e));
 
   nonExistent.delete(recursive: true).catchError((error) {
-    checkDeleteRecursivelyNonExistentFileException(error);
+    checkDeleteRecursivelyNonExistentFileSystemException(error);
     done();
   });
 }
 
 
-bool checkListNonExistentFileException(e) {
-  Expect.isTrue(e is DirectoryException);
+bool checkListNonExistentFileSystemException(e) {
+  Expect.isTrue(e is FileSystemException);
   Expect.isTrue(e.osError != null);
   Expect.isTrue(e.toString().indexOf("Directory listing failed") != -1);
   if (Platform.operatingSystem == "linux") {
@@ -131,18 +131,18 @@
 }
 
 
-bool checkAsyncListNonExistentFileException(error) {
-  return checkListNonExistentFileException(error);
+bool checkAsyncListNonExistentFileSystemException(error) {
+  return checkListNonExistentFileSystemException(error);
 }
 
 
 void testListNonExistent(Directory temp, Function done) {
   Directory nonExistent = new Directory("${temp.path}/nonExistent");
-  Expect.throws(() => nonExistent.listSync(), (e) => e is DirectoryException);
+  Expect.throws(() => nonExistent.listSync(), (e) => e is FileSystemException);
   nonExistent.list().listen(
       (_) => Expect.fail("listing should not succeed"),
       onError: (e) {
-        checkAsyncListNonExistentFileException(e);
+        checkAsyncListNonExistentFileSystemException(e);
         done();
       });
 }
@@ -152,11 +152,11 @@
   Directory nonExistent = new Directory("${temp.path}/nonExistent");
   var newPath = "${temp.path}/nonExistent2";
   Expect.throws(() => nonExistent.renameSync(newPath),
-                (e) => e is DirectoryException);
+                (e) => e is FileSystemException);
   var renameDone = nonExistent.rename(newPath);
   renameDone.then((ignore) => Expect.fail('rename non existent'))
             .catchError((error) {
-              Expect.isTrue(error is DirectoryException);
+              Expect.isTrue(error is FileSystemException);
             done();
   });
 }
@@ -168,11 +168,11 @@
   f.createSync();
   var d = new Directory(f.path);
   Expect.throws(() => d.renameSync(newPath),
-                (e) => e is DirectoryException);
+                (e) => e is FileSystemException);
   var renameDone = d.rename(newPath);
   renameDone.then((ignore) => Expect.fail('rename file as directory'))
             .catchError((error) {
-              Expect.isTrue(error is DirectoryException);
+              Expect.isTrue(error is FileSystemException);
               done();
             });
 }
@@ -183,11 +183,11 @@
   var fileName = '${temp.path}/x';
   new File(fileName).createSync();
   Expect.throws(() => temp1.renameSync(fileName),
-                (e) => e is DirectoryException);
+                (e) => e is FileSystemException);
   var renameDone = temp1.rename(fileName);
   renameDone.then((ignore) => Expect.fail('rename dir overwrite file'))
             .catchError((error) {
-              Expect.isTrue(error is DirectoryException);
+              Expect.isTrue(error is FileSystemException);
               temp1.deleteSync(recursive: true);
               done();
             });
diff --git a/tests/standalone/io/directory_list_nonexistent_test.dart b/tests/standalone/io/directory_list_nonexistent_test.dart
index 8e4043d..f33303d 100644
--- a/tests/standalone/io/directory_list_nonexistent_test.dart
+++ b/tests/standalone/io/directory_list_nonexistent_test.dart
@@ -16,9 +16,9 @@
   asyncStart();
   Directory.systemTemp.createTemp('dart_directory_list_nonexistent').then((d) {
     d.delete().then((ignore) {
-      Expect.throws(() => d.listSync(), (e) => e is DirectoryException);
+      Expect.throws(() => d.listSync(), (e) => e is FileSystemException);
       Expect.throws(() => d.listSync(recursive: true),
-                    (e) => e is DirectoryException);
+                    (e) => e is FileSystemException);
       asyncEnd();
     });
   });
@@ -39,9 +39,9 @@
       }
       var long = new Directory("${buffer.toString()}");
       Expect.throws(() => long.listSync(),
-                    (e) => e is DirectoryException);
+                    (e) => e is FileSystemException);
       Expect.throws(() => long.listSync(recursive: true),
-                    (e) => e is DirectoryException);
+                    (e) => e is FileSystemException);
       d.deleteSync(recursive: true);
       asyncEnd();
     });
diff --git a/tests/standalone/io/directory_test.dart b/tests/standalone/io/directory_test.dart
index bb6b7d1..4053666 100644
--- a/tests/standalone/io/directory_test.dart
+++ b/tests/standalone/io/directory_test.dart
@@ -111,7 +111,7 @@
       stream.listen(
           (_) => Expect.fail("Listing of non-existing directory should fail"),
           onError: (error) {
-            Expect.isTrue(error is DirectoryException);
+            Expect.isTrue(error is FileSystemException);
           });
     }
     Directory.systemTemp.createTemp('dart_directory').then((d) {
@@ -130,7 +130,7 @@
         stream.listen(
           (_) => Expect.fail("Listing of non-existing directory should fail"),
           onError: (error) {
-            Expect.isTrue(error is DirectoryException);
+            Expect.isTrue(error is FileSystemException);
             if (++errors == 2) {
               d.delete(recursive: true).then((_) {
                 asyncEnd();
@@ -161,7 +161,7 @@
       future.then((ignore) {
         Expect.fail("Deletion of non-existing directory should fail");
       }).catchError((error) {
-        Expect.isTrue(error is DirectoryException);
+        Expect.isTrue(error is FileSystemException);
       });
     }
 
@@ -189,7 +189,7 @@
           var long = new Directory("${buffer.toString()}");
           var errors = 0;
           onError(error) {
-            Expect.isTrue(error is DirectoryException);
+            Expect.isTrue(error is FileSystemException);
             if (++errors == 2) {
               d.delete(recursive: true).then((_) => asyncEnd());
             }
@@ -507,7 +507,7 @@
   var location = illegalTempDirectoryLocation();
   if (location != null) {
     Expect.throws(() => new Directory(location).createTempSync('dart_tempdir'),
-                  (e) => e is DirectoryException);
+                  (e) => e is FileSystemException);
   }
 }
 
@@ -568,7 +568,7 @@
   file.createSync();
   Expect.isTrue(file.existsSync());
   Expect.throws(new Directory(path).createSync,
-                (e) => e is DirectoryException);
+                (e) => e is FileSystemException);
   temp.deleteSync(recursive: true);
 }
 
@@ -584,7 +584,7 @@
       subDir.create()
         .then((_) { Expect.fail("dir create should fail on existing file"); })
         .catchError((error) {
-          Expect.isTrue(error is DirectoryException);
+          Expect.isTrue(error is FileSystemException);
           temp.delete(recursive: true).then((_) {
             asyncEnd();
           });
diff --git a/tests/standalone/io/echo_server_stream_test.dart b/tests/standalone/io/echo_server_stream_test.dart
index daf2c23..0684571 100644
--- a/tests/standalone/io/echo_server_stream_test.dart
+++ b/tests/standalone/io/echo_server_stream_test.dart
@@ -12,6 +12,7 @@
 library ServerTest;
 
 import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
 import "dart:async";
 import "dart:io";
 import "dart:isolate";
@@ -24,14 +25,11 @@
   static const FIRSTCHAR = 65;
 
   EchoServerGame.start()
-      : _receivePort = new ReceivePort(),
-        _sendPort = null,
-        _buffer = new List<int>(MSGSIZE),
+      : _buffer = new List<int>(MSGSIZE),
         _messages = 0 {
     for (int i = 0; i < MSGSIZE; i++) {
       _buffer[i] = FIRSTCHAR + i;
     }
-    _sendPort = spawnFunction(startEchoServer);
     initialize();
   }
 
@@ -80,30 +78,33 @@
   }
 
   void initialize() {
-    _receivePort.receive((var message, SendPort replyTo) {
-      _port = message;
+    var receivePort = new ReceivePort();
+    var remote = Isolate.spawn(startEchoServer, receivePort.sendPort);
+    receivePort.first.then((msg) {
+      this._port = msg[0];
+      this._closeSendPort = msg[1];
       sendData();
     });
-    _sendPort.send(TestingServer.INIT, _receivePort.toSendPort());
   }
 
   void shutdown() {
-    _sendPort.send(TestingServer.SHUTDOWN, _receivePort.toSendPort());
-    _receivePort.close();
+    _closeSendPort.send(null);
+    asyncEnd();
   }
 
   int _port;
-  ReceivePort _receivePort;
-  SendPort _sendPort;
+  SendPort _closeSendPort;
   Socket _socket;
   List<int> _buffer;
   int _messages;
 }
 
 
-void startEchoServer() {
+void startEchoServer(SendPort replyPort) {
   var server = new EchoServer();
-  port.receive(server.dispatch);
+  server.init().then((port) {
+    replyPort.send([port, server.closeSendPort]);
+  });
 }
 
 
@@ -143,5 +144,6 @@
 }
 
 main() {
+  asyncStart();
   EchoServerGame echoServerGame = new EchoServerGame.start();
 }
diff --git a/tests/standalone/io/file_error_test.dart b/tests/standalone/io/file_error_test.dart
index 70d87ed..713ac58 100644
--- a/tests/standalone/io/file_error_test.dart
+++ b/tests/standalone/io/file_error_test.dart
@@ -15,8 +15,8 @@
 }
 
 
-bool checkNonExistentFileException(e, str) {
-  Expect.isTrue(e is FileException);
+bool checkNonExistentFileSystemException(e, str) {
+  Expect.isTrue(e is FileSystemException);
   Expect.isTrue(e.osError != null);
   Expect.isTrue(e.toString().indexOf(str) != -1);
   // File not not found has error code 2 on all supported platforms.
@@ -25,18 +25,18 @@
 }
 
 
-bool checkOpenNonExistentFileException(e) {
-  return checkNonExistentFileException(e, "Cannot open file");
+bool checkOpenNonExistentFileSystemException(e) {
+  return checkNonExistentFileSystemException(e, "Cannot open file");
 }
 
 
-bool checkDeleteNonExistentFileException(e) {
-  return checkNonExistentFileException(e, "Cannot delete file");
+bool checkDeleteNonExistentFileSystemException(e) {
+  return checkNonExistentFileSystemException(e, "Cannot delete file");
 }
 
 
-bool checkLengthNonExistentFileException(e) {
-  return checkNonExistentFileException(e, "Cannot retrieve length of file");
+bool checkLengthNonExistentFileSystemException(e) {
+  return checkNonExistentFileSystemException(e, "Cannot retrieve length of file");
 }
 
 
@@ -47,12 +47,12 @@
 
   // Non-existing file should throw exception.
   Expect.throws(() => file.openSync(),
-                (e) => checkOpenNonExistentFileException(e));
+                (e) => checkOpenNonExistentFileSystemException(e));
 
   var openFuture = file.open(mode: FileMode.READ);
   openFuture.then((raf) => Expect.fail("Unreachable code"))
             .catchError((error) {
-              checkOpenNonExistentFileException(error);
+              checkOpenNonExistentFileSystemException(error);
               temp.deleteSync(recursive: true);
               asyncEnd();
             });
@@ -66,12 +66,12 @@
 
   // Non-existing file should throw exception.
   Expect.throws(() => file.deleteSync(),
-                (e) => checkDeleteNonExistentFileException(e));
+                (e) => checkDeleteNonExistentFileSystemException(e));
 
   var delete = file.delete();
   delete.then((ignore) => Expect.fail("Unreachable code"))
         .catchError((error) {
-          checkDeleteNonExistentFileException(error);
+          checkDeleteNonExistentFileSystemException(error);
           temp.deleteSync(recursive: true);
           asyncEnd();
         });
@@ -85,20 +85,20 @@
 
   // Non-existing file should throw exception.
   Expect.throws(() => file.lengthSync(),
-                (e) => checkLengthNonExistentFileException(e));
+                (e) => checkLengthNonExistentFileSystemException(e));
 
   var lenFuture = file.length();
   lenFuture.then((len) => Expect.fail("Unreachable code"))
            .catchError((error) {
-             checkLengthNonExistentFileException(error);
+             checkLengthNonExistentFileSystemException(error);
              temp.deleteSync(recursive: true);
              asyncEnd();
            });
 }
 
 
-bool checkCreateInNonExistentDirectoryException(e) {
-  Expect.isTrue(e is FileException);
+bool checkCreateInNonExistentFileSystemException(e) {
+  Expect.isTrue(e is FileSystemException);
   Expect.isTrue(e.osError != null);
   Expect.isTrue(e.toString().indexOf("Cannot create file") != -1);
   if (Platform.operatingSystem == "linux") {
@@ -119,19 +119,19 @@
 
   // Create in non-existent directory should throw exception.
   Expect.throws(() => file.createSync(),
-                (e) => checkCreateInNonExistentDirectoryException(e));
+                (e) => checkCreateInNonExistentFileSystemException(e));
 
   var create = file.create();
   create.then((ignore) => Expect.fail("Unreachable code"))
   .catchError((error) {
-    checkCreateInNonExistentDirectoryException(error);
+    checkCreateInNonExistentFileSystemException(error);
     temp.deleteSync(recursive: true);
     asyncEnd();
   });
 }
 
-bool checkResolveSymbolicLinksOnNonExistentDirectoryException(e) {
-  Expect.isTrue(e is FileException);
+bool checkResolveSymbolicLinksOnNonExistentFileSystemException(e) {
+  Expect.isTrue(e is FileSystemException);
   Expect.isTrue(e.osError != null);
   Expect.isTrue(e.toString().indexOf("Cannot resolve symbolic links") != -1);
   // File not not found has error code 2 on all supported platforms.
@@ -147,12 +147,12 @@
 
   // Full path non-existent directory should throw exception.
   Expect.throws(() => file.resolveSymbolicLinksSync(),
-      (e) => checkResolveSymbolicLinksOnNonExistentDirectoryException(e));
+      (e) => checkResolveSymbolicLinksOnNonExistentFileSystemException(e));
 
   var resolvedFuture = file.resolveSymbolicLinks();
   resolvedFuture.then((path) => Expect.fail("Unreachable code $path"))
   .catchError((error) {
-    checkResolveSymbolicLinksOnNonExistentDirectoryException(error);
+    checkResolveSymbolicLinksOnNonExistentFileSystemException(error);
     temp.deleteSync(recursive: true);
     asyncEnd();
   });
@@ -165,12 +165,12 @@
 
   // Non-existing file should throw exception.
   Expect.throws(() => file.readAsBytesSync(),
-                (e) => checkOpenNonExistentFileException(e));
+                (e) => checkOpenNonExistentFileSystemException(e));
 
   var readAsBytesFuture = file.readAsBytes();
   readAsBytesFuture.then((data) => Expect.fail("Unreachable code"))
   .catchError((error) {
-    checkOpenNonExistentFileException(error);
+    checkOpenNonExistentFileSystemException(error);
     temp.deleteSync(recursive: true);
     asyncEnd();
   });
@@ -183,12 +183,12 @@
 
   // Non-existing file should throw exception.
   Expect.throws(() => file.readAsStringSync(),
-                (e) => checkOpenNonExistentFileException(e));
+                (e) => checkOpenNonExistentFileSystemException(e));
 
   var readAsStringFuture = file.readAsString(encoding: ASCII);
   readAsStringFuture.then((data) => Expect.fail("Unreachable code"))
   .catchError((error) {
-    checkOpenNonExistentFileException(error);
+    checkOpenNonExistentFileSystemException(error);
     temp.deleteSync(recursive: true);
     asyncEnd();
   });
@@ -201,19 +201,19 @@
 
   // Non-existing file should throw exception.
   Expect.throws(() => file.readAsLinesSync(),
-                (e) => checkOpenNonExistentFileException(e));
+                (e) => checkOpenNonExistentFileSystemException(e));
 
   var readAsLinesFuture = file.readAsLines(encoding: ASCII);
   readAsLinesFuture.then((data) => Expect.fail("Unreachable code"))
   .catchError((error) {
-    checkOpenNonExistentFileException(error);
+    checkOpenNonExistentFileSystemException(error);
     temp.deleteSync(recursive: true);
     asyncEnd();
   });
 }
 
-bool checkWriteReadOnlyFileException(e) {
-  Expect.isTrue(e is FileException);
+bool checkWriteReadOnlyFileSystemException(e) {
+  Expect.isTrue(e is FileSystemException);
   Expect.isTrue(e.osError != null);
   Expect.isTrue(e.osError.errorCode != OSError.noErrorCode);
   return true;
@@ -241,11 +241,11 @@
 
     // Writing to read only file should throw an exception.
     Expect.throws(() => openedFile.writeByteSync(0),
-                  (e) => checkWriteReadOnlyFileException(e));
+                  (e) => checkWriteReadOnlyFileSystemException(e));
 
     var writeByteFuture = openedFile.writeByte(0);
     writeByteFuture.catchError((error) {
-      checkWriteReadOnlyFileException(error);
+      checkWriteReadOnlyFileSystemException(error);
       openedFile.close().then((_) => done());
     });
   });
@@ -258,11 +258,11 @@
     List data = [0, 1, 2, 3];
     // Writing to read only file should throw an exception.
     Expect.throws(() => openedFile.writeFromSync(data, 0, data.length),
-                  (e) => checkWriteReadOnlyFileException(e));
+                  (e) => checkWriteReadOnlyFileSystemException(e));
 
     var writeFromFuture = openedFile.writeFrom(data, 0, data.length);
     writeFromFuture.catchError((error) {
-      checkWriteReadOnlyFileException(error);
+      checkWriteReadOnlyFileSystemException(error);
       openedFile.close().then((_) => done());
     });
   });
@@ -277,19 +277,19 @@
 
     // Truncating read only file should throw an exception.
     Expect.throws(() => openedFile.truncateSync(0),
-                  (e) => checkWriteReadOnlyFileException(e));
+                  (e) => checkWriteReadOnlyFileSystemException(e));
 
     var truncateFuture = openedFile.truncate(0);
     truncateFuture.then((ignore) => Expect.fail("Unreachable code"))
     .catchError((error) {
-      checkWriteReadOnlyFileException(error);
+      checkWriteReadOnlyFileSystemException(error);
       openedFile.close().then((_) => done());
     });
   });
 }
 
 bool checkFileClosedException(e) {
-  Expect.isTrue(e is FileException);
+  Expect.isTrue(e is FileSystemException);
   Expect.isTrue(e.toString().indexOf("File closed") != -1);
   Expect.isTrue(e.osError == null);
   return true;
@@ -381,7 +381,7 @@
       var closeFuture = openedFile.close();
       closeFuture.then((ignore) => null)
       .catchError((error) {
-        Expect.isTrue(error is FileException);
+        Expect.isTrue(error is FileSystemException);
         done();
       });
     });
@@ -393,7 +393,7 @@
     var openedFile = file.openSync();
     openedFile.closeSync();
     Expect.throws(openedFile.closeSync,
-                  (e) => e is FileException);
+                  (e) => e is FileSystemException);
     done();
   });
 }
@@ -403,7 +403,7 @@
     var bigint = 100000000000000000000000000000000000000000;
     var openedFile = file.openSync();
     Expect.throws(() => openedFile.readSync(bigint),
-                  (e) => e is FileException);
+                  (e) => e is FileSystemException);
     openedFile.closeSync();
     done();
   });
@@ -414,7 +414,7 @@
     var openedFile = file.openSync();
     openedFile.closeSync();
     Expect.throws(() => openedFile.readSync(1),
-                  (e) => e is FileException);
+                  (e) => e is FileSystemException);
     done();
   });
 }
diff --git a/tests/standalone/io/file_read_encoded_test.dart b/tests/standalone/io/file_read_encoded_test.dart
index 75d4be6..984b366 100644
--- a/tests/standalone/io/file_read_encoded_test.dart
+++ b/tests/standalone/io/file_read_encoded_test.dart
@@ -14,7 +14,7 @@
 
   file.writeAsBytesSync([0xb0]);
 
-  Expect.throws(file.readAsStringSync, (e) => e is FileException);
+  Expect.throws(file.readAsStringSync, (e) => e is FileSystemException);
 
   asyncStart();
   file.readAsString().then((_) {
@@ -22,7 +22,7 @@
   }).catchError((e) {
     tmp.deleteSync(recursive: true);
     asyncEnd();
-  }, test: (e) => e is FileException);
+  }, test: (e) => e is FileSystemException);
 }
 
 void testReadAsLines() {
@@ -33,7 +33,7 @@
 
   file.writeAsBytesSync([0xb0]);
 
-  Expect.throws(file.readAsLinesSync, (e) => e is FileException);
+  Expect.throws(file.readAsLinesSync, (e) => e is FileSystemException);
 
   asyncStart();
   file.readAsLines().then((_) {
@@ -41,7 +41,7 @@
   }).catchError((e) {
     tmp.deleteSync(recursive: true);
     asyncEnd();
-  }, test: (e) => e is FileException);
+  }, test: (e) => e is FileSystemException);
 }
 
 void main() {
diff --git a/tests/standalone/io/file_system_watcher_test.dart b/tests/standalone/io/file_system_watcher_test.dart
index 6b37799..4540b60 100644
--- a/tests/standalone/io/file_system_watcher_test.dart
+++ b/tests/standalone/io/file_system_watcher_test.dart
@@ -111,6 +111,24 @@
 }
 
 
+void testWatchDeleteDir() {
+  var dir = Directory.systemTemp.createTempSync('dart_file_system_watcher');
+  var watcher = dir.watch(events: 0);
+
+  asyncStart();
+  var sub;
+  sub = watcher.listen((event) {
+    if (event is FileSystemDeleteEvent) {
+      Expect.isTrue(event.path == dir.path);
+    }
+  }, onDone: () {
+    asyncEnd();
+  });
+
+  dir.deleteSync();
+}
+
+
 void testWatchOnlyModifyFile() {
   var dir = Directory.systemTemp.createTempSync('dart_file_system_watcher');
   var file = new File(dir.path + '/file');
@@ -244,6 +262,7 @@
   testWatchModifyFile();
   testWatchMoveFile();
   testWatchDeleteFile();
+  testWatchDeleteDir();
   testWatchOnlyModifyFile();
   testMultipleEvents();
   testWatchNonRecursive();
diff --git a/tests/standalone/io/file_test.dart b/tests/standalone/io/file_test.dart
index 2827e1d..3ecb081 100644
--- a/tests/standalone/io/file_test.dart
+++ b/tests/standalone/io/file_test.dart
@@ -707,7 +707,7 @@
     openedFile.closeSync();
     try {
       openedFile.readByteSync();
-    } on FileException catch (ex) {
+    } on FileSystemException catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
       wrongExceptionCaught = true;
@@ -717,7 +717,7 @@
     exceptionCaught = false;
     try {
       openedFile.writeByteSync(1);
-    } on FileException catch (ex) {
+    } on FileSystemException catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
       wrongExceptionCaught = true;
@@ -727,7 +727,7 @@
     exceptionCaught = false;
     try {
       openedFile.writeStringSync("Test");
-    } on FileException catch (ex) {
+    } on FileSystemException catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
       wrongExceptionCaught = true;
@@ -738,7 +738,7 @@
     try {
       List<int> buffer = new List<int>(100);
       openedFile.readIntoSync(buffer, 0, 10);
-    } on FileException catch (ex) {
+    } on FileSystemException catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
       wrongExceptionCaught = true;
@@ -749,7 +749,7 @@
     try {
       List<int> buffer = new List<int>(100);
       openedFile.writeFromSync(buffer, 0, 10);
-    } on FileException catch (ex) {
+    } on FileSystemException catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
       wrongExceptionCaught = true;
@@ -759,7 +759,7 @@
     exceptionCaught = false;
     try {
       openedFile.positionSync();
-    } on FileException catch (ex) {
+    } on FileSystemException catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
       wrongExceptionCaught = true;
@@ -769,7 +769,7 @@
     exceptionCaught = false;
     try {
       openedFile.lengthSync();
-    } on FileException catch (ex) {
+    } on FileSystemException catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
       wrongExceptionCaught = true;
@@ -779,7 +779,7 @@
     exceptionCaught = false;
     try {
       openedFile.flushSync();
-    } on FileException catch (ex) {
+    } on FileSystemException catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
       wrongExceptionCaught = true;
@@ -916,7 +916,7 @@
       f.openSync();
       Expect.fail("Expected exception opening directory as file");
     } catch (e) {
-      Expect.isTrue(e is FileException);
+      Expect.isTrue(e is FileSystemException);
     }
   }
 
@@ -1005,7 +1005,7 @@
     Expect.listEquals(expected, text.codeUnits);
     // First character is not ASCII. The default ASCII decoder will throw.
     Expect.throws(() => new File(name).readAsStringSync(encoding: ASCII),
-                  (e) => e is FileException);
+                  (e) => e is FileSystemException);
     // We can use an ASCII decoder that inserts the replacement character.
     var lenientAscii = const AsciiCodec(allowInvalid: true);
     text = new File(name).readAsStringSync(encoding: lenientAscii);
@@ -1055,9 +1055,9 @@
   static void testReadAsErrors() {
     asyncTestStarted();
     var f = new File('.');
-    Expect.throws(f.readAsBytesSync, (e) => e is FileException);
-    Expect.throws(f.readAsStringSync, (e) => e is FileException);
-    Expect.throws(f.readAsLinesSync, (e) => e is FileException);
+    Expect.throws(f.readAsBytesSync, (e) => e is FileSystemException);
+    Expect.throws(f.readAsStringSync, (e) => e is FileSystemException);
+    Expect.throws(f.readAsLinesSync, (e) => e is FileSystemException);
     var readAsBytesFuture = f.readAsBytes();
     readAsBytesFuture.then((bytes) => Expect.fail("no bytes expected"))
     .catchError((e) {
@@ -1232,7 +1232,7 @@
             .then((_) => file.rename("xxx"))
             .then((_) { throw "Rename of broken link succeeded"; })
             .catchError((e) {
-              Expect.isTrue(e is FileException);
+              Expect.isTrue(e is FileSystemException);
               asyncTestDone("testRename$targetExists");
             });
         } else {
diff --git a/tests/standalone/io/http_advanced_test.dart b/tests/standalone/io/http_advanced_test.dart
index deab970..63a3be8 100644
--- a/tests/standalone/io/http_advanced_test.dart
+++ b/tests/standalone/io/http_advanced_test.dart
@@ -15,39 +15,43 @@
 class IsolatedHttpServer {
   IsolatedHttpServer()
       : _statusPort = new ReceivePort(),
-        _serverPort = null {
-    _serverPort = spawnFunction(startIsolatedHttpServer);
-  }
+        _serverPort = null;
 
   void setServerStartedHandler(void startedCallback(int port)) {
     _startedCallback = startedCallback;
   }
 
   void start() {
+    ReceivePort receivePort = new ReceivePort();
+    var remote = Isolate.spawn(startIsolatedHttpServer, receivePort.sendPort);
+    receivePort.first.then((port) {
+      _serverPort = port;
+
+      // Send server start message to the server.
+      var command = new IsolatedHttpServerCommand.start();
+      port.send([command, _statusPort.sendPort]);
+    });
+
     // Handle status messages from the server.
-    _statusPort.receive((var status, SendPort replyTo) {
+    _statusPort.listen((var status) {
       if (status.isStarted) {
         _startedCallback(status.port);
       }
     });
-
-    // Send server start message to the server.
-    var command = new IsolatedHttpServerCommand.start();
-    _serverPort.send(command, _statusPort.toSendPort());
   }
 
   void shutdown() {
     // Send server stop message to the server.
-    _serverPort.send(new IsolatedHttpServerCommand.stop(),
-                     _statusPort.toSendPort());
+    _serverPort.send([new IsolatedHttpServerCommand.stop(),
+                      _statusPort.sendPort]);
     _statusPort.close();
   }
 
   void chunkedEncoding() {
     // Send chunked encoding message to the server.
-    _serverPort.send(
+    _serverPort.send([
         new IsolatedHttpServerCommand.chunkedEncoding(),
-        _statusPort.toSendPort());
+        _statusPort.sendPort]);
   }
 
   ReceivePort _statusPort;  // Port for receiving messages from the server.
@@ -93,10 +97,10 @@
 }
 
 
-void startIsolatedHttpServer() {
+void startIsolatedHttpServer(SendPort replyTo) {
   var server = new TestServer();
   server.init();
-  port.receive(server.dispatch);
+  replyTo.send(server.dispatchSendPort);
 }
 
 
@@ -201,10 +205,16 @@
     _requestHandlers["/contenttype2"] = _contentType2Handler;
     _requestHandlers["/cookie1"] = _cookie1Handler;
     _requestHandlers["/cookie2"] = _cookie2Handler;
+    _dispatchPort = new ReceivePort();
+    _dispatchPort.listen(dispatch);
   }
 
-  void dispatch(message, replyTo) {
-    if (message.isStart) {
+  SendPort get dispatchSendPort => _dispatchPort.sendPort;
+
+  void dispatch(message) {
+    IsolatedHttpServerCommand command = message[0];
+    SendPort replyTo = message[1];
+    if (command.isStart) {
       try {
         HttpServer.bind("127.0.0.1", 0).then((server) {
           _server = server;
@@ -215,11 +225,11 @@
       } catch (e) {
         replyTo.send(new IsolatedHttpServerStatus.error(), null);
       }
-    } else if (message.isStop) {
+    } else if (command.isStop) {
       _server.close();
-      port.close();
+      _dispatchPort.close();
       replyTo.send(new IsolatedHttpServerStatus.stopped(), null);
-    } else if (message.isChunkedEncoding) {
+    } else if (command.isChunkedEncoding) {
       _chunkedEncoding = true;
     }
   }
@@ -234,6 +244,7 @@
   }
 
   HttpServer _server;  // HTTP server instance.
+  ReceivePort _dispatchPort;
   Map _requestHandlers;
   bool _chunkedEncoding = false;
 }
diff --git a/tests/standalone/io/http_basic_test.dart b/tests/standalone/io/http_basic_test.dart
index 6d9caaf..2d7eebd 100644
--- a/tests/standalone/io/http_basic_test.dart
+++ b/tests/standalone/io/http_basic_test.dart
@@ -14,39 +14,44 @@
 class TestServerMain {
   TestServerMain()
       : _statusPort = new ReceivePort(),
-        _serverPort = null {
-    _serverPort = spawnFunction(startTestServer);
-  }
+        _serverPort = null;
 
   void setServerStartedHandler(void startedCallback(int port)) {
     _startedCallback = startedCallback;
   }
 
-  void start() {
+  void start([bool chunkedEncoding = false]) {
+    ReceivePort receivePort = new ReceivePort();
+    var remote = Isolate.spawn(startTestServer, receivePort.sendPort);
+    receivePort.first.then((port) {
+      _serverPort = port;
+
+      if (chunkedEncoding) {
+        // Send chunked encoding message to the server.
+        port.send(
+            [new TestServerCommand.chunkedEncoding(), _statusPort.sendPort]);
+      }
+
+      // Send server start message to the server.
+      var command = new TestServerCommand.start();
+      port.send([command, _statusPort.sendPort]);
+    });
+
     // Handle status messages from the server.
-    _statusPort.receive((var status, SendPort replyTo) {
+    _statusPort.listen((var status) {
       if (status.isStarted) {
         _startedCallback(status.port);
       }
     });
 
-    // Send server start message to the server.
-    var command = new TestServerCommand.start();
-    _serverPort.send(command, _statusPort.toSendPort());
   }
 
   void close() {
     // Send server stop message to the server.
-    _serverPort.send(new TestServerCommand.stop(), _statusPort.toSendPort());
+    _serverPort.send([new TestServerCommand.stop(), _statusPort.sendPort]);
     _statusPort.close();
   }
 
-  void chunkedEncoding() {
-    // Send chunked encoding message to the server.
-    _serverPort.send(
-        new TestServerCommand.chunkedEncoding(), _statusPort.toSendPort());
-  }
-
   ReceivePort _statusPort;  // Port for receiving messages from the server.
   SendPort _serverPort;  // Port for sending messages to the server.
   var _startedCallback;
@@ -90,10 +95,10 @@
 }
 
 
-void startTestServer() {
+void startTestServer(SendPort replyTo) {
   var server = new TestServer();
   server.init();
-  port.receive(server.dispatch);
+  replyTo.send(server.dispatchSendPort);
 }
 
 
@@ -151,10 +156,16 @@
     _requestHandlers["/0123456789"] = _zeroToTenHandler;
     _requestHandlers["/reasonformoving"] = _reasonForMovingHandler;
     _requestHandlers["/host"] = _hostHandler;
+    _dispatchPort = new ReceivePort();
+    _dispatchPort.listen(dispatch);
   }
 
-  void dispatch(var message, SendPort replyTo) {
-    if (message.isStart) {
+  SendPort get dispatchSendPort => _dispatchPort.sendPort;
+
+  void dispatch(var message) {
+    TestServerCommand command = message[0];
+    SendPort replyTo = message[1];
+    if (command.isStart) {
       try {
         HttpServer.bind("127.0.0.1", 0).then((server) {
           _server = server;
@@ -164,11 +175,11 @@
       } catch (e) {
         replyTo.send(new TestServerStatus.error(), null);
       }
-    } else if (message.isStop) {
+    } else if (command.isStop) {
       _server.close();
-      port.close();
+      _dispatchPort.close();
       replyTo.send(new TestServerStatus.stopped(), null);
-    } else if (message.isChunkedEncoding) {
+    } else if (command.isChunkedEncoding) {
       _chunkedEncoding = true;
     }
   }
@@ -183,6 +194,7 @@
   }
 
   HttpServer _server;  // HTTP server instance.
+  ReceivePort _dispatchPort;
   Map _requestHandlers;
   bool _chunkedEncoding = false;
 }
@@ -259,10 +271,7 @@
   }
 
   testServerMain.setServerStartedHandler(runTest);
-  if (chunkedEncoding) {
-    testServerMain.chunkedEncoding();
-  }
-  testServerMain.start();
+  testServerMain.start(chunkedEncoding);
 }
 
 void test404() {
diff --git a/tests/standalone/io/http_read_test.dart b/tests/standalone/io/http_read_test.dart
index e5f543e..2a0ad52 100644
--- a/tests/standalone/io/http_read_test.dart
+++ b/tests/standalone/io/http_read_test.dart
@@ -14,41 +14,44 @@
 class IsolatedHttpServer {
   IsolatedHttpServer()
       : _statusPort = new ReceivePort(),
-        _serverPort = null {
-    _serverPort = spawnFunction(startIsolatedHttpServer);
-  }
+        _serverPort = null;
 
   void setServerStartedHandler(void startedCallback(int port)) {
     _startedCallback = startedCallback;
   }
 
-  void start() {
+  void start([bool chunkedEncoding = false]) {
+    ReceivePort receivePort = new ReceivePort();
+    var remote = Isolate.spawn(startIsolatedHttpServer, receivePort.sendPort);
+    receivePort.first.then((port) {
+      _serverPort = port;
+
+      if (chunkedEncoding) {
+        // Send chunked encoding message to the server.
+        port.send([new IsolatedHttpServerCommand.chunkedEncoding(),
+                   _statusPort.sendPort]);
+      }
+
+      // Send server start message to the server.
+      var command = new IsolatedHttpServerCommand.start();
+      port.send([command, _statusPort.sendPort]);
+    });
+
     // Handle status messages from the server.
-    _statusPort.receive((var status, SendPort replyTo) {
+    _statusPort.listen((var status) {
       if (status.isStarted) {
         _startedCallback(status.port);
       }
     });
-
-    // Send server start message to the server.
-    var command = new IsolatedHttpServerCommand.start();
-    _serverPort.send(command, _statusPort.toSendPort());
   }
 
   void shutdown() {
     // Send server stop message to the server.
-    _serverPort.send(new IsolatedHttpServerCommand.stop(),
-                     _statusPort.toSendPort());
+    _serverPort.send([new IsolatedHttpServerCommand.stop(),
+                     _statusPort.sendPort]);
     _statusPort.close();
   }
 
-  void chunkedEncoding() {
-    // Send chunked encoding message to the server.
-    _serverPort.send(
-        new IsolatedHttpServerCommand.chunkedEncoding(),
-        _statusPort.toSendPort());
-  }
-
   ReceivePort _statusPort;  // Port for receiving messages from the server.
   SendPort _serverPort;  // Port for sending messages to the server.
   var _startedCallback;
@@ -92,10 +95,10 @@
 }
 
 
-void startIsolatedHttpServer() {
+void startIsolatedHttpServer(SendPort replyTo) {
   var server = new TestServer();
   server.init();
-  port.receive(server.dispatch);
+  replyTo.send(server.dispatchSendPort);
 }
 
 class TestServer {
@@ -121,10 +124,16 @@
     // Setup request handlers.
     _requestHandlers = new Map();
     _requestHandlers["/echo"] = _echoHandler;
+    _dispatchPort = new ReceivePort();
+    _dispatchPort.listen(dispatch);
   }
 
-  void dispatch(message, SendPort replyTo) {
-    if (message.isStart) {
+  SendPort get dispatchSendPort => _dispatchPort.sendPort;
+
+  void dispatch(message) {
+    IsolatedHttpServerCommand command = message[0];
+    SendPort replyTo = message[1];
+    if (command.isStart) {
       try {
         HttpServer.bind("127.0.0.1", 0).then((server) {
           _server = server;
@@ -135,11 +144,11 @@
       } catch (e) {
         replyTo.send(new IsolatedHttpServerStatus.error(), null);
       }
-    } else if (message.isStop) {
+    } else if (command.isStop) {
       _server.close();
-      port.close();
+      _dispatchPort.close();
       replyTo.send(new IsolatedHttpServerStatus.stopped(), null);
-    } else if (message.isChunkedEncoding) {
+    } else if (command.isChunkedEncoding) {
       _chunkedEncoding = true;
     }
   }
@@ -154,6 +163,7 @@
   }
 
   HttpServer _server;  // HTTP server instance.
+  ReceivePort _dispatchPort;
   Map _requestHandlers;
   bool _chunkedEncoding = false;
 }
@@ -200,10 +210,7 @@
   }
 
   server.setServerStartedHandler(runTest);
-  if (chunkedEncoding) {
-    server.chunkedEncoding();
-  }
-  server.start();
+  server.start(chunkedEncoding);
 }
 
 void main() {
diff --git a/tests/standalone/io/link_test.dart b/tests/standalone/io/link_test.dart
index ddcb0ee..ff9f70f 100644
--- a/tests/standalone/io/link_test.dart
+++ b/tests/standalone/io/link_test.dart
@@ -204,7 +204,7 @@
   Expect.throws(() =>
       new Link('some-dir-that-doent exist/some link file/bla/fisk').createSync(
           'bla bla bla/b lalal/blfir/sdfred/es'),
-      (e) => e is LinkException);
+      (e) => e is FileSystemException);
 }
 
 checkExists(String filePath) => Expect.isTrue(new File(filePath).existsSync());
diff --git a/tests/standalone/io/pipe_server_test.dart b/tests/standalone/io/pipe_server_test.dart
index 3f858db..6481a91 100644
--- a/tests/standalone/io/pipe_server_test.dart
+++ b/tests/standalone/io/pipe_server_test.dart
@@ -10,6 +10,7 @@
 library ServerTest;
 
 import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
 import "dart:async";
 import "dart:io";
 import "dart:isolate";
@@ -38,10 +39,7 @@
   int count = 0;
 
   PipeServerGame.start()
-      : _receivePort = new ReceivePort(),
-        _sendPort = null,
-        _messages = 0 {
-    _sendPort = spawnFunction(startPipeServer);
+      : _messages = 0 {
     initialize();
   }
 
@@ -83,29 +81,32 @@
   }
 
   void initialize() {
-    _receivePort.receive((var message, SendPort replyTo) {
-      _port = message;
+    var receivePort = new ReceivePort();
+    var remote = Isolate.spawn(startPipeServer, receivePort.sendPort);
+    receivePort.first.then((msg) {
+      this._port = msg[0];
+      this._closeSendPort = msg[1];
       runTest();
     });
-    _sendPort.send(TestingServer.INIT, _receivePort.toSendPort());
   }
 
   void shutdown() {
-    _sendPort.send(TestingServer.SHUTDOWN, _receivePort.toSendPort());
-    _receivePort.close();
+    _closeSendPort.send(null);
+    asyncEnd();
   }
 
   int _port;
-  ReceivePort _receivePort;
-  SendPort _sendPort;
+  SendPort _closeSendPort;
   Socket _socket;
   int _messages;
 }
 
 
-void startPipeServer() {
+void startPipeServer(SendPort replyPort) {
   var server = new PipeServer();
-  port.receive(server.dispatch);
+  server.init().then((port) {
+    replyPort.send([port, server.closeSendPort]);
+  });
 }
 
 
@@ -119,5 +120,6 @@
 
 
 main() {
+  asyncStart();
   PipeServerGame echoServerGame = new PipeServerGame.start();
 }
diff --git a/tests/standalone/io/platform_test.dart b/tests/standalone/io/platform_test.dart
index 1bcfbd7..7e9f77c 100644
--- a/tests/standalone/io/platform_test.dart
+++ b/tests/standalone/io/platform_test.dart
@@ -34,42 +34,29 @@
       (arg) => arg.contains(Platform.packageRoot)));
 }
 
-void f() {
-  port.receive((msg, reply) {
-    if (msg == "Platform.executable") {
-      reply.send(Platform.executable);
-    }
-    if (msg == "Platform.script") {
-      reply.send(Platform.script);
-    }
-    if (msg == "Platform.packageRoot") {
-      reply.send(Platform.packageRoot);
-    }
-    if (msg == "Platform.executableArguments") {
-      reply.send(Platform.executableArguments);
-    }
-    if (msg == "close") {
-      reply.send("closed");
-      port.close();
-    }
-  });
+void f(reply) {
+  reply.send({"Platform.executable": Platform.executable,
+              "Platform.script": Platform.script,
+              "Platform.packageRoot": Platform.packageRoot,
+              "Platform.executableArguments": Platform.executableArguments});
 }
 
 testIsolate() {
   asyncStart();
-  var sendPort = spawnFunction(f);
-  Future.wait([sendPort.call("Platform.executable"),
-               sendPort.call("Platform.script"),
-               sendPort.call("Platform.packageRoot"),
-               sendPort.call("Platform.executableArguments")])
-  .then((results) {
-    Expect.equals(Platform.executable, results[0]);
-    Uri uri = Uri.parse(results[1]);
-    Expect.equals("file", uri.scheme);
+  ReceivePort port = new ReceivePort();
+  var remote = Isolate.spawn(f, port.sendPort);
+  port.first.then((results) {
+    Expect.equals(Platform.executable, results["Platform.executable"]);
+
+    Uri uri = Uri.parse(results["Platform.script"]);
+    // SpawnFunction retains the script url of the parent which in this
+    // case was a relative path.
+    Expect.equals("", uri.scheme);
     Expect.isTrue(uri.path.endsWith('tests/standalone/io/platform_test.dart'));
-    Expect.equals(Platform.packageRoot, results[2]);
-    Expect.listEquals(Platform.executableArguments, results[3]);
-    sendPort.call("close").then((_) => asyncEnd());
+    Expect.equals(Platform.packageRoot, results["Platform.packageRoot"]);
+    Expect.listEquals(Platform.executableArguments,
+                      results["Platform.executableArguments"]);
+    asyncEnd();
   });
 }
 
diff --git a/tests/standalone/io/process_shell_test.dart b/tests/standalone/io/process_shell_test.dart
index e461a8d..4e6593d 100644
--- a/tests/standalone/io/process_shell_test.dart
+++ b/tests/standalone/io/process_shell_test.dart
@@ -3,11 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:path/path.dart";
+import "package:async_helper/async_helper.dart";
 import "dart:io";
+import "dart:async";
 import "dart:isolate";
 
 void testRunShell() {
   test(args) {
+    asyncStart();
     var path = join(dirname(Platform.script), "process_echo_util.dart");
     Process.run(Platform.executable,
                 [path]..addAll(args),
@@ -26,6 +29,7 @@
               throw "bad result at $i: '${args[i]}' vs '${result[i]}'";
             }
           }
+          asyncEnd();
         });
   }
   test(["\""]);
@@ -43,12 +47,13 @@
 
 void testBadRunShell() {
   test(exe, [args = const []]) {
+    asyncStart();
     Process.run(exe, args, runInShell: true)
         .then((result) {
-          port.close();
           if (result.exitCode == 0) {
             throw "error expected";
           }
+          asyncEnd();
         });
   }
   test("'\"'");
diff --git a/tests/standalone/io/socket_close_test.dart b/tests/standalone/io/socket_close_test.dart
index 39905e3..475d97a 100644
--- a/tests/standalone/io/socket_close_test.dart
+++ b/tests/standalone/io/socket_close_test.dart
@@ -20,17 +20,21 @@
 const ITERATIONS = 10;
 
 
+Future sendReceive(SendPort port, message) {
+  ReceivePort receivePort = new ReceivePort();
+  port.send([message, receivePort.sendPort]);
+  return receivePort.first;
+}
+
 class SocketClose {
 
   SocketClose.start(this._mode, this._done)
-      : _receivePort = new ReceivePort(),
-        _sendPort = null,
+      : _sendPort = null,
         _readBytes = 0,
         _dataEvents = 0,
         _closeEvents = 0,
         _errorEvents = 0,
         _iterations = 0 {
-    _sendPort = spawnFunction(startSocketCloseServer);
     initialize();
   }
 
@@ -142,19 +146,20 @@
   }
 
   void initialize() {
-    _receivePort.receive((var message, SendPort replyTo) {
-      _port = message;
-      proceed();
+    ReceivePort receivePort = new ReceivePort();
+    var remote = Isolate.spawn(startSocketCloseServer, receivePort.sendPort);
+
+    receivePort.first.then((message) {
+      this._sendPort = message;
+      sendReceive(_sendPort, _mode).then((int port) {
+        this._port = port;
+        proceed();
+      });
     });
-    _sendPort.send(_mode, _receivePort.toSendPort());
   }
 
   void shutdown() {
-    _sendPort.send(SERVERSHUTDOWN, _receivePort.toSendPort());
-    _receivePort.receive((message, ignore) {
-      _done();
-      _receivePort.close();
-    });
+    sendReceive(_sendPort, SERVERSHUTDOWN).then((_) { _done(); });
 
     switch (_mode) {
       case 0:
@@ -184,7 +189,6 @@
   }
 
   int _port;
-  ReceivePort _receivePort;
   SendPort _sendPort;
   List<int> _buffer;
   int _readBytes;
@@ -204,16 +208,18 @@
 }
 
 
-void startSocketCloseServer() {
+void startSocketCloseServer(SendPort replyTo) {
   var server = new SocketCloseServer();
-  port.receive(server.dispatch);
+  replyTo.send(server.dispatchSendPort);
 }
 
 class SocketCloseServer {
 
   static const HOST = "127.0.0.1";
 
-  SocketCloseServer() : super() {}
+  SocketCloseServer() : _dispatchPort = new ReceivePort() {
+    _dispatchPort.listen(dispatch);
+  }
 
   void connectionHandler(ConnectionData data) {
     var connection = data.connection;
@@ -325,22 +331,26 @@
       }
       Expect.equals(0, _errorEvents);
       _server.close();
-      port.close();
+      _dispatchPort.close();
       _donePort.send(null);
     } else {
       new Timer(new Duration(milliseconds: 100), waitForResult);
     }
   }
 
-  void dispatch(message, SendPort replyTo) {
+  SendPort get dispatchSendPort => _dispatchPort.sendPort;
+
+  void dispatch(message) {
+    var command = message[0];
+    SendPort replyTo = message[1];
     _donePort = replyTo;
-    if (message != SERVERSHUTDOWN) {
+    if (command != SERVERSHUTDOWN) {
       _readBytes = 0;
       _errorEvents = 0;
       _dataEvents = 0;
       _closeEvents = 0;
       _iterations = 0;
-      _mode = message;
+      _mode = command;
       ServerSocket.bind("127.0.0.1", 0).then((server) {
         _server = server;
         _server.listen(
@@ -358,6 +368,7 @@
   }
 
   ServerSocket _server;
+  final ReceivePort _dispatchPort;
   SendPort _donePort;
   int _readBytes;
   int _errorEvents;
diff --git a/tests/standalone/io/socket_many_connections_test.dart b/tests/standalone/io/socket_many_connections_test.dart
index bda8031..d6ddcbd 100644
--- a/tests/standalone/io/socket_many_connections_test.dart
+++ b/tests/standalone/io/socket_many_connections_test.dart
@@ -6,6 +6,7 @@
 library ServerTest;
 
 import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
 import "dart:async";
 import "dart:io";
 import "dart:isolate";
@@ -16,11 +17,8 @@
 class SocketManyConnectionsTest {
 
   SocketManyConnectionsTest.start()
-      : _receivePort = new ReceivePort(),
-        _sendPort = null,
-        _connections = 0,
+      : _connections = 0,
         _sockets = new List<Socket>(CONNECTIONS) {
-    _sendPort = spawnFunction(startTestServer);
     initialize();
   }
 
@@ -46,29 +44,32 @@
   }
 
   void initialize() {
-    _receivePort.receive((var message, SendPort replyTo) {
-      _port = message;
+    var receivePort = new ReceivePort();
+    var remote = Isolate.spawn(startTestServer, receivePort.sendPort);
+    receivePort.first.then((msg) {
+      this._port = msg[0];
+      this._closeSendPort = msg[1];
       run();
     });
-    _sendPort.send(TestingServer.INIT, _receivePort.toSendPort());
   }
 
   void close() {
-    _sendPort.send(TestingServer.SHUTDOWN, _receivePort.toSendPort());
-    _receivePort.close();
+    _closeSendPort.send(null);
+    asyncEnd();
   }
 
   int _port;
-  ReceivePort _receivePort;
-  SendPort _sendPort;
+  SendPort _closeSendPort;
   List<Socket> _sockets;
   int _connections;
 }
 
 
-void startTestServer() {
+void startTestServer(SendPort replyPort) {
   var server = new TestServer();
-  port.receive(server.dispatch);
+  server.init().then((port) {
+    replyPort.send([port, server.closeSendPort]);
+  });
 }
 
 class TestServer extends TestingServer {
@@ -99,5 +100,6 @@
 }
 
 main() {
+  asyncStart();
   SocketManyConnectionsTest test = new SocketManyConnectionsTest.start();
 }
diff --git a/tests/standalone/io/stdin_sync_script.dart b/tests/standalone/io/stdin_sync_script.dart
index 42b648e..c29de2f 100644
--- a/tests/standalone/io/stdin_sync_script.dart
+++ b/tests/standalone/io/stdin_sync_script.dart
@@ -4,13 +4,14 @@
 
 import "dart:convert";
 import "dart:io";
-import "dart:json";
 
 void main(List<String> arguments) {
   int i = 0;
   String line;
   while ((line = stdin.readLineSync(encoding: UTF8)) != null) {
-    if (parse(arguments[i]) != line) throw "bad line at $i: ${line.codeUnits}";
+    if (JSON.decode(arguments[i]) != line) {
+      throw "bad line at $i: ${line.codeUnits}";
+    }
     i++;
   }
   if (i != arguments.length) throw "expect ${arguments.length} lines";
diff --git a/tests/standalone/io/stdin_sync_test.dart b/tests/standalone/io/stdin_sync_test.dart
index c0477c0..5d14509 100644
--- a/tests/standalone/io/stdin_sync_test.dart
+++ b/tests/standalone/io/stdin_sync_test.dart
@@ -4,7 +4,6 @@
 
 import "dart:convert";
 import "dart:io";
-import "dart:json";
 
 import "package:path/path.dart";
 
@@ -13,7 +12,7 @@
     var script = join(dirname(Platform.script), "stdin_sync_script.dart");
     Process.start(Platform.executable,
                   ["--checked", script]..addAll(
-                      expected.map(stringify))).then((process) {
+                      expected.map(JSON.encode))).then((process) {
       process.stdin.write(line);
       process.stdin.close();
       process.stderr
diff --git a/tests/standalone/io/testing_server.dart b/tests/standalone/io/testing_server.dart
index c8bd2b6..76eba42 100644
--- a/tests/standalone/io/testing_server.dart
+++ b/tests/standalone/io/testing_server.dart
@@ -19,48 +19,24 @@
     Expect.fail(msg);
   }
 
-  void dispatch(message, SendPort replyTo) {
-    if (message == INIT) {
-      ServerSocket.bind(HOST, 0).then((server) {
-        _server = server;
-        _server.listen(
-            onConnection,
-            onError: errorHandlerServer);
-        replyTo.send(_server.port, null);
-      });
-    } else if (message == SHUTDOWN) {
-      _server.close();
-      port.close();
-    }
+  SendPort get closeSendPort => _closePort.sendPort;
+
+  Future<int> init() {
+    _closePort = new ReceivePort();
+    _closePort.first.then((_) { close(); });
+    return ServerSocket.bind(HOST, 0).then((server) {
+      _server = server;
+      _server.listen(
+          onConnection,
+          onError: errorHandlerServer);
+      return _server.port;
+    });
+  }
+
+  void close() {
+    _server.close();
   }
 
   ServerSocket _server;
-}
-
-abstract class TestingServerTest {
-
-  TestingServerTest.start(SendPort port)
-      : _receivePort = new ReceivePort(),
-        _sendPort = port {
-    initialize();
-  }
-
-  void run();  // Abstract.
-
-  void initialize() {
-    _receivePort.receive((var message, SendPort replyTo) {
-      _port = message;
-      run();
-    });
-    _sendPort.send(TestingServer.INIT, _receivePort.toSendPort());
-  }
-
-  void shutdown() {
-    _sendPort.send(TestingServer.SHUTDOWN, _receivePort.toSendPort());
-    _receivePort.close();
-  }
-
-  int _port;
-  ReceivePort _receivePort;
-  SendPort _sendPort;
+  ReceivePort _closePort;
 }
diff --git a/tests/standalone/io/uri_platform_test.dart b/tests/standalone/io/uri_platform_test.dart
index cc67760..586e7f3 100644
--- a/tests/standalone/io/uri_platform_test.dart
+++ b/tests/standalone/io/uri_platform_test.dart
@@ -4,39 +4,9 @@
 
 import "package:expect/expect.dart";
 import "dart:io";
+import "dart:platform" as platform;
 
 main() {
-  if (Platform.isWindows) {
-    Expect.equals("a\\b", Uri.parse("a/b").toFilePath());
-    Expect.equals("a\\b\\", Uri.parse("a/b/").toFilePath());
-    Expect.equals("a b", Uri.parse("a%20b").toFilePath());
-    Expect.equals("\\a b", Uri.parse("file:///a%20b").toFilePath());
-    Expect.equals("\\a\\b", Uri.parse("file:///a/b").toFilePath());
-    Expect.equals("C:\\", Uri.parse("file:///C:").toFilePath());
-    Expect.equals("C:\\", Uri.parse("file:///C:/").toFilePath());
-    Expect.equals("\\\\host\\a\\b", Uri.parse("file://host/a/b").toFilePath());
-
-    Expect.equals("a\\b", new Uri.file("a/b").toFilePath());
-    Expect.equals("a\\b", new Uri.file("a\\b").toFilePath());
-    Expect.equals("\\a\\b", new Uri.file("/a/b").toFilePath());
-    Expect.equals("\\a\\b", new Uri.file("\\a\\b").toFilePath());
-    Expect.equals("\\a\\b", new Uri.file("\\a/b").toFilePath());
-    Expect.equals("\\a\\b", new Uri.file("/a\\b").toFilePath());
-  } else {
-    Expect.equals("a/b", Uri.parse("a/b").toFilePath());
-    Expect.equals("a/b/", Uri.parse("a/b/").toFilePath());
-    Expect.equals("a b", Uri.parse("a%20b").toFilePath());
-    Expect.equals("/a b", Uri.parse("file:///a%20b").toFilePath());
-    Expect.equals("/a/b", Uri.parse("file:///a/b").toFilePath());
-    Expect.equals("/C:", Uri.parse("file:///C:").toFilePath());
-    Expect.equals("/C:/", Uri.parse("file:///C:/").toFilePath());
-    Expect.throws(() => Uri.parse("file://host/a/b").toFilePath(),
-                  (e) => e is UnsupportedError);
-
-    Expect.equals("a/b", new Uri.file("a/b").toFilePath());
-    Expect.equals("a\\b", new Uri.file("a\\b").toFilePath());
-  }
-
   Expect.equals(Uri.base,
-                new Uri.file(Directory.current.path + Platform.pathSeparator));
+                new Uri.file(Directory.current.path + platform.pathSeparator));
 }
diff --git a/tests/standalone/issue14236_source.dart b/tests/standalone/issue14236_source.dart
new file mode 100644
index 0000000..edb18a8
--- /dev/null
+++ b/tests/standalone/issue14236_source.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.
+//
+// This is the original dart program that was used to generate the snapshot
+// in file issue14236_test.dart
+// The original test/main has been commented out and we have a test/main which
+// throws an error to ensure that this file is not executed as part of the
+// test.
+
+library test.issue14236;
+import 'dart:isolate';
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart"; 
+
+/*
+test(SendPort replyTo) {
+  replyTo.send("from Isolate");
+}
+
+main() {
+  asyncStart();
+  ReceivePort port = new ReceivePort();
+  Isolate.spawn(test, port.sendPort);
+  port.first.then((msg) {
+    Expect.equals("from Isolate", msg);
+    asyncEnd();
+  });
+}
+*/
+
+test() {
+  Expect.fail("Don't expect this to run at all");
+}
+main() {
+  Expect.fail("Don't expect this to run at all");
+}
diff --git a/tests/standalone/issue14236_test.dart b/tests/standalone/issue14236_test.dart
new file mode 100644
index 0000000..7790795
--- /dev/null
+++ b/tests/standalone/issue14236_test.dart
Binary files differ
diff --git a/tests/standalone/package/package_isolate_test.dart b/tests/standalone/package/package_isolate_test.dart
index f826c5f..f3a6bec 100644
--- a/tests/standalone/package/package_isolate_test.dart
+++ b/tests/standalone/package/package_isolate_test.dart
@@ -7,44 +7,44 @@
 library package_isolate_test;
 import 'package:shared.dart' as shared;
 import 'dart:isolate';
-import '../../../pkg/unittest/lib/unittest.dart';
+import '../../../pkg/async_helper/lib/async_helper.dart';
+import '../../../pkg/expect/lib/expect.dart';
 
 expectResponse() {
+  asyncStart();
   var receivePort = new ReceivePort();
-  receivePort.receive(expectAsync2((msg, r) {
-    expect('isolate', msg);
-    expect('main', shared.output);
-    receivePort.close();
-  }));
+  receivePort.first.then((msg) {
+    Expect.equals('isolate', msg);
+    Expect.equals('main', shared.output);
+    asyncEnd();
+  });
   return receivePort;
 }
 
 void main() {
-  test("package in spawnFunction()", () {
-    var replyPort = expectResponse().toSendPort();
+  {
+    var replyPort = expectResponse().sendPort;
     shared.output = 'main';
-    var sendPort = spawnFunction(isolate_main);
-    sendPort.send("sendPort", replyPort);
-  });
-  
-  test("package in spawnUri() of sibling file", () {
-    var replyPort = expectResponse().toSendPort();
-    shared.output = 'main';
-    var sendPort = spawnUri('sibling_isolate.dart');
-    sendPort.send('sendPort', replyPort);
-  });
+    Isolate.spawn(isolate_main, replyPort);
+  }
 
-  test("package in spawnUri() of file in folder", () {
-    var replyPort = expectResponse().toSendPort();
+  {
+    // Package in spawnUri() of sibling file.
+    var replyPort = expectResponse().sendPort;
     shared.output = 'main';
-    var sendPort = spawnUri('test_folder/folder_isolate.dart');
-    sendPort.send('sendPort', replyPort);
-  });
+    Isolate.spawnUri(Uri.parse('sibling_isolate.dart'), [], replyPort);
+  }
+
+  {
+    // Package in spawnUri() of file in folder.
+    var replyPort = expectResponse().sendPort;
+    shared.output = 'main';
+    Isolate.spawnUri(Uri.parse('test_folder/folder_isolate.dart'),
+                     [], replyPort);
+  }
 }
 
-void isolate_main() {
+void isolate_main(SendPort replyTo) {
   shared.output = 'isolate';
-  port.receive((msg, replyTo) {
-    replyTo.send(shared.output);
-  });
+  replyTo.send(shared.output);
 }
diff --git a/tests/standalone/package/sibling_isolate.dart b/tests/standalone/package/sibling_isolate.dart
index 14b400d..a2e8332 100644
--- a/tests/standalone/package/sibling_isolate.dart
+++ b/tests/standalone/package/sibling_isolate.dart
@@ -9,9 +9,7 @@
 import 'dart:isolate';
 
 // This file is spawned from package_isolate_test.dart
-main() {
+main(List<String args>, SendPort reply) {
   shared.output = 'isolate';
-  port.receive((msg, replyTo) {
-    replyTo.send(shared.output);
-  });
+  reply.send(shared.output);
 }
diff --git a/tests/standalone/package/test_folder/folder_isolate.dart b/tests/standalone/package/test_folder/folder_isolate.dart
index 9f822ce..4a56448 100644
--- a/tests/standalone/package/test_folder/folder_isolate.dart
+++ b/tests/standalone/package/test_folder/folder_isolate.dart
@@ -4,14 +4,12 @@
 
 library folder_isolate;
 
-// this is a package that's not available to the main isolate
+// This is a package that's not available to the main isolate
 import 'package:folder_lib.dart' as isolate_package;
 import 'dart:isolate';
 
 // This file is spawned from package_isolate_test.dart
-main() {
+main(List<String> args, Sendport replyTo) {
   isolate_package.count = 1;
-  port.receive((msg, replyTo) {
-    replyTo.send('isolate');
-  });
+  replyTo.send('isolate');
 }
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 5478aab..0b2316a 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -11,9 +11,23 @@
 
 [ $runtime == vm && $system == windows ]
 io/file_system_watcher_test: Pass, Timeout # Issue 13228
+io/platform_test: Pass, Fail # Issue 14399
 
 [ $runtime == vm ]
-package/package_isolate_test: Fail # http://dartbug.com/7520.
+package/package_isolate_test: Fail # Issue 12474
+vmservice/isolate_bad_class_test: Skip # Issue 14448
+vmservice/isolate_bad_object_test: Skip # Issue 14448
+vmservice/isolate_class_field_test: Skip # Issue 14448
+vmservice/isolate_class_test: Skip # Issue 14448
+vmservice/isolate_code_test: Skip # Issue 14448
+vmservice/isolate_echo_test: Skip # Issue 14448
+vmservice/isolate_function_test: Skip # Issue 14448
+vmservice/isolate_library_test: Skip # Issue 14448
+vmservice/isolate_list_test: Skip # Issue 14448
+vmservice/isolate_stacktrace_command_test: Skip # Issue 14448
+vmservice/multiple_isolate_list_test: Skip # Issue 14448
+vmservice/unknown_command_test: Skip # Issue 14448
+vmservice/unknown_isolate_command_test: Skip # Issue 14448
 
 
 [ $runtime == vm && $checked ]
@@ -55,10 +69,12 @@
 coverage_test: Skip
 http_launch_test: Skip
 vmservice/*: Skip # Do not run standalone vm service tests in browser.
+issue14236_test: Skip # Issue 14236 Script snapshots do not work in the browser.
 
 
 [ $compiler == dartanalyzer ]
 javascript_int_overflow_literal_test/01: fail, ok
+issue14236_test: Skip # Analyzer can't handle Script snapshots.
 
 # test issue https://code.google.com/p/dart/issues/detail?id=11518
 io/file_constructor_test: fail
@@ -75,12 +91,10 @@
 # This is runtime test.
 io/process_exit_negative_test: Skip
 
-# https://code.google.com/p/dart/issues/detail?id=11647
-package/package_isolate_test: fail
-
 [ $compiler == dart2analyzer ]
 javascript_int_overflow_literal_test/01: fail, ok
 package/package_isolate_test: fail # issue 11647
+issue14236_test: Skip # Analyzer can't handle Script snapshots.
 
 # test issue https://code.google.com/p/dart/issues/detail?id=11518
 io/file_constructor_test: fail
@@ -97,9 +111,6 @@
 # This is runtime test.
 io/process_exit_negative_test: Skip
 
-# https://code.google.com/p/dart/issues/detail?id=11647
-package/package_isolate_test: fail
-
 [ $compiler == dart2js ]
 number_identity_test: Skip # Bigints and int/double diff. not supported.
 typed_data_test: Skip # dart:typed_data support needed.
@@ -123,13 +134,7 @@
 javascript_int_overflow_literal_test: Skip
 oom_error_stacktrace_test: RuntimeError, OK # (OOM on JS may produce a stacktrace).
 vmservice/*: Skip # Do not run standalone vm service tests with dart2js.
-
-# Suppress tests that use main(List<String> args) until issue 14200 is fixed.
-io/secure_builtin_roots_test: Fail # Issue 14200
-io/test_runner_test: Fail # Issue 14200
-io/http_cross_process_test: Fail # Issue 14200
-io/socket_cross_process_test: Fail # Issue 14200
-io/raw_socket_cross_process_test: Fail # Issue 14200
+issue14236_test: Skip # dart2js does not deal with Script snapshots.
 
 [ $compiler == dart2js && $jscl ]
 assert_test: RuntimeError, OK # Assumes unspecified fields on the AssertionError.
@@ -145,9 +150,6 @@
 [ $compiler == dart2js && $browser ]
 *: Skip
 
-[ $compiler == dart2js && $checked ]
-io/http_read_test: Skip # Timeout TODO(ngeoffray): investigate
-
 [ $compiler == dart2dart ]
 # Skip until we stabilize language tests.
 *: Skip
@@ -176,7 +178,9 @@
 io/dart_std_io_pipe_test: Fail
 io/file_read_special_device_test: Fail
 
-[ $compiler == none && $runtime == dartium ]
+[ $compiler == none && $runtime == dartium && $unchecked ]
 assert_test: Fail # Issue 13719: Please triage this failure.
+
+[ $compiler == none && $runtime == dartium ]
 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/standalone/typed_array_int64_uint64_test.dart b/tests/standalone/typed_array_int64_uint64_test.dart
index 92137c1..3decb92 100644
--- a/tests/standalone/typed_array_int64_uint64_test.dart
+++ b/tests/standalone/typed_array_int64_uint64_test.dart
@@ -25,8 +25,9 @@
 Int64List int64 = initInt64();
 
 void int64_receiver() {
-  var sp = spawnFunction(int64_sender);
-  sp.call(int64.length).then((a) {
+  var response = new ReceivePort();
+  var remote = Isolate.spawn(int64_sender, [int64.length, response.sendPort]);
+  response.first.then((a) {
     Expect.equals(int64.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(int64[i], a[i]);
@@ -35,15 +36,15 @@
   });
 }
 
-int64_sender() {
-  port.receive((len, r) {
-    Expect.equals(int64.length, len);
-    var a = new Int64List(len);
-    for (int i = 0; i < len; i++) {
-      a[i] = int64[i];
-    }
-    r.send(a);
-  });
+int64_sender(message) {
+  var len = message[0];
+  var r = message[1];
+  Expect.equals(int64.length, len);
+  var a = new Int64List(len);
+  for (int i = 0; i < len; i++) {
+    a[i] = int64[i];
+  }
+  r.send(a);
 }
 
 
@@ -57,8 +58,9 @@
 Uint64List uint64 = initUint64();
 
 void uint64_receiver() {
-  var sp = spawnFunction(uint64_sender);
-  sp.call(uint64.length).then((a) {
+  var response = new ReceivePort();
+  var remote = Isolate.spawn(uint64_sender, [uint64.length, response.sendPort]);
+  response.first.then((a) {
     Expect.equals(uint64.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(uint64[i], a[i]);
@@ -67,13 +69,13 @@
   });
 }
 
-uint64_sender() {
-  port.receive((len, r) {
-    Expect.equals(uint64.length, len);
-    var a = new Uint64List(len);
-    for (int i = 0; i < len; i++) {
-      a[i] = uint64[i];
-    }
-    r.send(a);
-  });
+uint64_sender(message) {
+  var len = message[0];
+  var r = message[1];
+  Expect.equals(uint64.length, len);
+  var a = new Uint64List(len);
+  for (int i = 0; i < len; i++) {
+    a[i] = uint64[i];
+  }
+  r.send(a);
 }
diff --git a/tests/standalone/typed_array_test.dart b/tests/standalone/typed_array_test.dart
index e58c352..9643e13e 100644
--- a/tests/standalone/typed_array_test.dart
+++ b/tests/standalone/typed_array_test.dart
@@ -33,8 +33,9 @@
 Int8List int8 = initInt8();
 
 void int8_receiver() {
-  var sp = spawnFunction(int8_sender);
-  sp.call(int8.length).then((a) {
+  var response = new ReceivePort();
+  var remote = Isolate.spawn(int8_sender, [int8.length, response.sendPort]);
+  response.first.then((a) {
     Expect.equals(int8.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(int8[i], a[i]);
@@ -43,15 +44,15 @@
   });
 }
 
-int8_sender() {
-  port.receive((len, r) {
-    Expect.equals(int8.length, len);
-    var a = new Int8List(len);
-    for (int i = 0; i < len; i++) {
-      a[i] = int8[i];
-    }
-    r.send(a);
-  });
+int8_sender(message) {
+  var len = message[0];
+  var r = message[1];
+  Expect.equals(int8.length, len);
+  var a = new Int8List(len);
+  for (int i = 0; i < len; i++) {
+    a[i] = int8[i];
+  }
+  r.send(a);
 }
 
 
@@ -65,8 +66,9 @@
 Uint8List uint8 = initUint8();
 
 void uint8_receiver() {
-  var sp = spawnFunction(uint8_sender);
-  sp.call(uint8.length).then((a) {
+  var response = new ReceivePort();
+  var remote = Isolate.spawn(uint8_sender, [uint8.length, response.sendPort]);
+  response.first.then((a) {
     Expect.equals(uint8.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(uint8[i], a[i]);
@@ -75,15 +77,15 @@
   });
 }
 
-uint8_sender() {
-  port.receive((len, r) {
-    Expect.equals(uint8.length, len);
-    var a = new Uint8List(len);
-    for (int i = 0; i < len; i++) {
-      a[i] = uint8[i];
-    }
-    r.send(a);
-  });
+uint8_sender(message) {
+  var len = message[0];
+  var r = message[1];
+  Expect.equals(uint8.length, len);
+  var a = new Uint8List(len);
+  for (int i = 0; i < len; i++) {
+    a[i] = uint8[i];
+  }
+  r.send(a);
 }
 
 
@@ -97,8 +99,9 @@
 Int16List int16 = initInt16();
 
 void int16_receiver() {
-  var sp = spawnFunction(int16_sender);
-  sp.call(int16.length).then((a) {
+  var response = new ReceivePort();
+  var remote = Isolate.spawn(int16_sender, [int16.length, response.sendPort]);
+  response.first.then((a) {
     Expect.equals(int16.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(int16[i], a[i]);
@@ -107,15 +110,15 @@
   });
 }
 
-int16_sender() {
-  port.receive((len, r) {
-    Expect.equals(int16.length, len);
-    var a = new Int16List(len);
-    for (int i = 0; i < len; i++) {
-      a[i] = int16[i];
-    }
-    r.send(a);
-  });
+int16_sender(message) {
+  var len = message[0];
+  var r = message[1];
+  Expect.equals(int16.length, len);
+  var a = new Int16List(len);
+  for (int i = 0; i < len; i++) {
+    a[i] = int16[i];
+  }
+  r.send(a);
 }
 
 
@@ -129,8 +132,9 @@
 Uint16List uint16 = initUint16();
 
 void uint16_receiver() {
-  var sp = spawnFunction(uint16_sender);
-  sp.call(uint16.length).then((a) {
+  var response = new ReceivePort();
+  var remote = Isolate.spawn(uint16_sender, [uint16.length, response.sendPort]);
+  response.first.then((a) {
     Expect.equals(uint16.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(uint16[i], a[i]);
@@ -139,15 +143,15 @@
   });
 }
 
-uint16_sender() {
-  port.receive((len, r) {
-    Expect.equals(uint16.length, len);
-    var a = new Uint16List(len);
-    for (int i = 0; i < len; i++) {
-      a[i] = uint16[i];
-    }
-    r.send(a);
-  });
+uint16_sender(message) {
+  var len = message[0];
+  var r = message[1];
+  Expect.equals(uint16.length, len);
+  var a = new Uint16List(len);
+  for (int i = 0; i < len; i++) {
+    a[i] = uint16[i];
+  }
+  r.send(a);
 }
 
 
@@ -161,8 +165,9 @@
 Int32List int32 = initInt32();
 
 void int32_receiver() {
-  var sp = spawnFunction(int32_sender);
-  sp.call(int32.length).then((a) {
+  var response = new ReceivePort();
+  var remote = Isolate.spawn(int32_sender, [int32.length, response.sendPort]);
+  response.first.then((a) {
     Expect.equals(int32.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(int32[i], a[i]);
@@ -171,15 +176,15 @@
   });
 }
 
-int32_sender() {
-  port.receive((len, r) {
-    Expect.equals(int32.length, len);
-    var a = new Int32List(len);
-    for (int i = 0; i < len; i++) {
-      a[i] = int32[i];
-    }
-    r.send(a);
-  });
+int32_sender(message) {
+  var len = message[0];
+  var r = message[1];
+  Expect.equals(int32.length, len);
+  var a = new Int32List(len);
+  for (int i = 0; i < len; i++) {
+    a[i] = int32[i];
+  }
+  r.send(a);
 }
 
 
@@ -193,8 +198,9 @@
 Uint32List uint32 = initUint32();
 
 void uint32_receiver() {
-  var sp = spawnFunction(uint32_sender);
-  sp.call(uint32.length).then((a) {
+  var response = new ReceivePort();
+  var remote = Isolate.spawn(uint32_sender, [uint32.length, response.sendPort]);
+  response.first.then((a) {
     Expect.equals(uint32.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(uint32[i], a[i]);
@@ -203,15 +209,15 @@
   });
 }
 
-uint32_sender() {
-  port.receive((len, r) {
-    Expect.equals(uint32.length, len);
-    var a = new Uint32List(len);
-    for (int i = 0; i < len; i++) {
-      a[i] = uint32[i];
-    }
-    r.send(a);
-  });
+uint32_sender(message) {
+  var len = message[0];
+  var r = message[1];
+  Expect.equals(uint32.length, len);
+  var a = new Uint32List(len);
+  for (int i = 0; i < len; i++) {
+    a[i] = uint32[i];
+  }
+  r.send(a);
 }
 
 
@@ -225,8 +231,10 @@
 Float32List float32 = initFloat32();
 
 void float32_receiver() {
-  var sp = spawnFunction(float32_sender);
-  sp.call(float32.length).then((a) {
+  var response = new ReceivePort();
+  var remote =
+      Isolate.spawn(float32_sender, [float32.length, response.sendPort]);
+  response.first.then((a) {
     Expect.equals(float32.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(float32[i], a[i]);
@@ -235,15 +243,15 @@
   });
 }
 
-float32_sender() {
-  port.receive((len, r) {
-    Expect.equals(float32.length, len);
-    var a = new Float32List(len);
-    for (int i = 0; i < len; i++) {
-      a[i] = float32[i];
-    }
-    r.send(a);
-  });
+float32_sender(message) {
+  var len = message[0];
+  var r = message[1];
+  Expect.equals(float32.length, len);
+  var a = new Float32List(len);
+  for (int i = 0; i < len; i++) {
+    a[i] = float32[i];
+  }
+  r.send(a);
 }
 
 
@@ -257,8 +265,10 @@
 Float64List float64 = initFloat64();
 
 void float64_receiver() {
-  var sp = spawnFunction(float64_sender);
-  sp.call(float64.length).then((a) {
+  var response = new ReceivePort();
+  var remote =
+      Isolate.spawn(float64_sender, [float64.length, response.sendPort]);
+  response.first.then((a) {
     Expect.equals(float64.length, a.length);
     for (int i = 0; i < a.length; i++) {
       Expect.equals(float64[i], a[i]);
@@ -267,13 +277,13 @@
   });
 }
 
-float64_sender() {
-  port.receive((len, r) {
-    Expect.equals(float64.length, len);
-    var a = new Float64List(len);
-    for (int i = 0; i < len; i++) {
-      a[i] = float64[i];
-    }
-    r.send(a);
-  });
+float64_sender(message) {
+  var len = message[0];
+  var r = message[1];
+  Expect.equals(float64.length, len);
+  var a = new Float64List(len);
+  for (int i = 0; i < len; i++) {
+    a[i] = float64[i];
+  }
+  r.send(a);
 }
diff --git a/tests/standalone/typed_data_isolate_test.dart b/tests/standalone/typed_data_isolate_test.dart
index 852cc1e..37bf547 100644
--- a/tests/standalone/typed_data_isolate_test.dart
+++ b/tests/standalone/typed_data_isolate_test.dart
@@ -9,23 +9,25 @@
 
 import 'dart:io';
 import 'dart:isolate';
+import 'package:async_helper/async_helper.dart';
 
-second() {
- print('spawned');
- port.receive((data, replyTo) {
-   print('got data');
-   print(data);
-   print('printed data');
-   replyTo.send('OK');
-   port.close();
- });
+second(message) {
+  var data = message[0];
+  var replyTo = message[1];
+  print('got data');
+  print(data);
+  print('printed data');
+  replyTo.send('OK');
 }
 
 main() {
+ asyncStart();
  new File(Platform.script).readAsBytes().then((List<int> data) {
-   spawnFunction(second).call(data).then((reply) {
+   var response = new ReceivePort();
+   var remote = Isolate.spawn(second, [data, response.sendPort]);
+   response.first.then((reply) {
      print('got reply');
-     port.close();
+     asyncEnd();
    });
  });
 }
diff --git a/tests/standalone/vmservice/isolate_stacktrace_command_script.dart b/tests/standalone/vmservice/isolate_stacktrace_command_script.dart
index b9bbccf..6524ce5 100644
--- a/tests/standalone/vmservice/isolate_stacktrace_command_script.dart
+++ b/tests/standalone/vmservice/isolate_stacktrace_command_script.dart
@@ -25,12 +25,12 @@
   }
 }
 
-void myIsolateName() {
+void myIsolateName(_) {
   new C().c();
 }
 
 main() {
-  spawnFunction(myIsolateName);
+  Isolate.spawn(myIsolateName, null);
   // Wait until signaled from spawning test.
   stdin.first.then((_) => exit(0));
 }
diff --git a/tests/standalone/vmservice/multiple_isolate_list_script.dart b/tests/standalone/vmservice/multiple_isolate_list_script.dart
index 128f61a..fd83cc5 100644
--- a/tests/standalone/vmservice/multiple_isolate_list_script.dart
+++ b/tests/standalone/vmservice/multiple_isolate_list_script.dart
@@ -7,23 +7,19 @@
 import 'dart:io';
 import 'dart:isolate';
 
-void isolateMain1() {
+void isolateMain1(_) {
   // Spawn another isolate.
-  spawnFunction(myIsolateName);
-  // Kill this isolate.
-  port.close();
+  Isolate.spawn(myIsolateName, null);
 }
 
-void myIsolateName() {
+void myIsolateName(_) {
   // Stay running.
-  port.receive((a, b) {
-    port.close();
-  });
+  new ReceivePort().first.then((a) { });
   print(''); // Print blank line to signal that we are ready.
 }
 
 main() {
-  spawnFunction(isolateMain1);
+  Isolate.spawn(isolateMain1, null);
   // Wait until signaled from spawning test.
   stdin.first.then((_) => exit(0));
 }
diff --git a/tests/utils/json_test.dart b/tests/utils/json_test.dart
index 7d350e3..ad811d7 100644
--- a/tests/utils/json_test.dart
+++ b/tests/utils/json_test.dart
@@ -5,7 +5,7 @@
 library jsonTest;
 
 import "package:expect/expect.dart";
-import 'dart:json';
+import 'dart:convert';
 
 main() {
   testEscaping();
@@ -15,82 +15,82 @@
 
 void testParse() {
   // Scalars.
-  Expect.equals(5, parse(' 5 '));
-  Expect.equals(-42, parse(' -42 '));
-  Expect.equals(3, parse(' 3e0 '));
-  Expect.equals(3.14, parse(' 3.14 '));
-  Expect.equals(1.0E-06, parse(' 1.0E-06 '));
-  Expect.equals(0, parse("0"));
-  Expect.equals(1, parse("1"));
-  Expect.equals(0.1, parse("0.1"));
-  Expect.equals(1.1, parse("1.1"));
-  Expect.equals(1.1, parse("1.100000"));
-  Expect.equals(1.111111, parse("1.111111"));
-  Expect.equals(-0, parse("-0"));
-  Expect.equals(-1, parse("-1"));
-  Expect.equals(-0.1, parse("-0.1"));
-  Expect.equals(-1.1, parse("-1.1"));
-  Expect.equals(-1.1, parse("-1.100000"));
-  Expect.equals(-1.111111, parse("-1.111111"));
-  Expect.equals(11, parse("1.1e1"));
-  Expect.equals(11, parse("1.1e+1"));
-  Expect.equals(0.11, parse("1.1e-1"));
-  Expect.equals(11, parse("1.1E1"));
-  Expect.equals(11, parse("1.1E+1"));
-  Expect.equals(0.11, parse("1.1E-1"));
-  Expect.equals(1E0, parse(" 1E0"));
-  Expect.equals(1E+0, parse(" 1E+0"));
-  Expect.equals(1E-0, parse(" 1E-0"));
-  Expect.equals(1E00, parse(" 1E00"));
-  Expect.equals(1E+00, parse(" 1E+00"));
-  Expect.equals(1E-00, parse(" 1E-00"));
-  Expect.equals(1E+10, parse(" 1E+10"));
-  Expect.equals(1E+010, parse(" 1E+010"));
-  Expect.equals(1E+0010, parse(" 1E+0010"));
-  Expect.equals(1E10, parse(" 1E10"));
-  Expect.equals(1E010, parse(" 1E010"));
-  Expect.equals(1E0010, parse(" 1E0010"));
-  Expect.equals(1E-10, parse(" 1E-10"));
-  Expect.equals(1E-0010, parse(" 1E-0010"));
-  Expect.equals(1E0, parse(" 1e0"));
-  Expect.equals(1E+0, parse(" 1e+0"));
-  Expect.equals(1E-0, parse(" 1e-0"));
-  Expect.equals(1E00, parse(" 1e00"));
-  Expect.equals(1E+00, parse(" 1e+00"));
-  Expect.equals(1E-00, parse(" 1e-00"));
-  Expect.equals(1E+10, parse(" 1e+10"));
-  Expect.equals(1E+010, parse(" 1e+010"));
-  Expect.equals(1E+0010, parse(" 1e+0010"));
-  Expect.equals(1E10, parse(" 1e10"));
-  Expect.equals(1E010, parse(" 1e010"));
-  Expect.equals(1E0010, parse(" 1e0010"));
-  Expect.equals(1E-10, parse(" 1e-10"));
-  Expect.equals(1E-0010, parse(" 1e-0010"));
-  Expect.equals(true, parse(' true '));
-  Expect.equals(false, parse(' false'));
-  Expect.equals(null, parse(' null '));
-  Expect.equals(null, parse('\n\rnull\t'));
-  Expect.equals('hi there" bob', parse(' "hi there\\" bob" '));
-  Expect.equals('', parse(' "" '));
+  Expect.equals(5, JSON.decode(' 5 '));
+  Expect.equals(-42, JSON.decode(' -42 '));
+  Expect.equals(3, JSON.decode(' 3e0 '));
+  Expect.equals(3.14, JSON.decode(' 3.14 '));
+  Expect.equals(1.0E-06, JSON.decode(' 1.0E-06 '));
+  Expect.equals(0, JSON.decode("0"));
+  Expect.equals(1, JSON.decode("1"));
+  Expect.equals(0.1, JSON.decode("0.1"));
+  Expect.equals(1.1, JSON.decode("1.1"));
+  Expect.equals(1.1, JSON.decode("1.100000"));
+  Expect.equals(1.111111, JSON.decode("1.111111"));
+  Expect.equals(-0, JSON.decode("-0"));
+  Expect.equals(-1, JSON.decode("-1"));
+  Expect.equals(-0.1, JSON.decode("-0.1"));
+  Expect.equals(-1.1, JSON.decode("-1.1"));
+  Expect.equals(-1.1, JSON.decode("-1.100000"));
+  Expect.equals(-1.111111, JSON.decode("-1.111111"));
+  Expect.equals(11, JSON.decode("1.1e1"));
+  Expect.equals(11, JSON.decode("1.1e+1"));
+  Expect.equals(0.11, JSON.decode("1.1e-1"));
+  Expect.equals(11, JSON.decode("1.1E1"));
+  Expect.equals(11, JSON.decode("1.1E+1"));
+  Expect.equals(0.11, JSON.decode("1.1E-1"));
+  Expect.equals(1E0, JSON.decode(" 1E0"));
+  Expect.equals(1E+0, JSON.decode(" 1E+0"));
+  Expect.equals(1E-0, JSON.decode(" 1E-0"));
+  Expect.equals(1E00, JSON.decode(" 1E00"));
+  Expect.equals(1E+00, JSON.decode(" 1E+00"));
+  Expect.equals(1E-00, JSON.decode(" 1E-00"));
+  Expect.equals(1E+10, JSON.decode(" 1E+10"));
+  Expect.equals(1E+010, JSON.decode(" 1E+010"));
+  Expect.equals(1E+0010, JSON.decode(" 1E+0010"));
+  Expect.equals(1E10, JSON.decode(" 1E10"));
+  Expect.equals(1E010, JSON.decode(" 1E010"));
+  Expect.equals(1E0010, JSON.decode(" 1E0010"));
+  Expect.equals(1E-10, JSON.decode(" 1E-10"));
+  Expect.equals(1E-0010, JSON.decode(" 1E-0010"));
+  Expect.equals(1E0, JSON.decode(" 1e0"));
+  Expect.equals(1E+0, JSON.decode(" 1e+0"));
+  Expect.equals(1E-0, JSON.decode(" 1e-0"));
+  Expect.equals(1E00, JSON.decode(" 1e00"));
+  Expect.equals(1E+00, JSON.decode(" 1e+00"));
+  Expect.equals(1E-00, JSON.decode(" 1e-00"));
+  Expect.equals(1E+10, JSON.decode(" 1e+10"));
+  Expect.equals(1E+010, JSON.decode(" 1e+010"));
+  Expect.equals(1E+0010, JSON.decode(" 1e+0010"));
+  Expect.equals(1E10, JSON.decode(" 1e10"));
+  Expect.equals(1E010, JSON.decode(" 1e010"));
+  Expect.equals(1E0010, JSON.decode(" 1e0010"));
+  Expect.equals(1E-10, JSON.decode(" 1e-10"));
+  Expect.equals(1E-0010, JSON.decode(" 1e-0010"));
+  Expect.equals(true, JSON.decode(' true '));
+  Expect.equals(false, JSON.decode(' false'));
+  Expect.equals(null, JSON.decode(' null '));
+  Expect.equals(null, JSON.decode('\n\rnull\t'));
+  Expect.equals('hi there" bob', JSON.decode(' "hi there\\" bob" '));
+  Expect.equals('', JSON.decode(' "" '));
 
   // Lists.
-  Expect.listEquals([], parse(' [] '));
-  Expect.listEquals(["entry"], parse(' ["entry"] '));
-  Expect.listEquals([true, false], parse(' [true, false] '));
-  Expect.listEquals([1, 2, 3], parse(' [ 1 , 2 , 3 ] '));
+  Expect.listEquals([], JSON.decode(' [] '));
+  Expect.listEquals(["entry"], JSON.decode(' ["entry"] '));
+  Expect.listEquals([true, false], JSON.decode(' [true, false] '));
+  Expect.listEquals([1, 2, 3], JSON.decode(' [ 1 , 2 , 3 ] '));
 
   // Maps.
-  Expect.mapEquals({}, parse(' {} '));
-  Expect.mapEquals({"key": "value"}, parse(' {"key": "value" } '));
+  Expect.mapEquals({}, JSON.decode(' {} '));
+  Expect.mapEquals({"key": "value"}, JSON.decode(' {"key": "value" } '));
   Expect.mapEquals({"key1": 1, "key2": 2},
-                   parse(' {"key1": 1, "key2": 2} '));
+                   JSON.decode(' {"key1": 1, "key2": 2} '));
   Expect.mapEquals({"key1": 1},
-                   parse(' { "key1" : 1 } '));
+                   JSON.decode(' { "key1" : 1 } '));
 }
 
 void testParseInvalid() {
   void testString(String s) {
-    Expect.throws(() => parse(s), (e) => e is FormatException);
+    Expect.throws(() => JSON.decode(s), (e) => e is FormatException);
   }
   // Scalars
   testString("");
@@ -136,43 +136,43 @@
 }
 
 void testEscaping() {
-  Expect.stringEquals('""', stringify(''));
-  Expect.stringEquals('"\\u0000"', stringify('\u0000'));
-  Expect.stringEquals('"\\u0001"', stringify('\u0001'));
-  Expect.stringEquals('"\\u0002"', stringify('\u0002'));
-  Expect.stringEquals('"\\u0003"', stringify('\u0003'));
-  Expect.stringEquals('"\\u0004"', stringify('\u0004'));
-  Expect.stringEquals('"\\u0005"', stringify('\u0005'));
-  Expect.stringEquals('"\\u0006"', stringify('\u0006'));
-  Expect.stringEquals('"\\u0007"', stringify('\u0007'));
-  Expect.stringEquals('"\\b"', stringify('\u0008'));
-  Expect.stringEquals('"\\t"', stringify('\u0009'));
-  Expect.stringEquals('"\\n"', stringify('\u000a'));
-  Expect.stringEquals('"\\u000b"', stringify('\u000b'));
-  Expect.stringEquals('"\\f"', stringify('\u000c'));
-  Expect.stringEquals('"\\r"', stringify('\u000d'));
-  Expect.stringEquals('"\\u000e"', stringify('\u000e'));
-  Expect.stringEquals('"\\u000f"', stringify('\u000f'));
-  Expect.stringEquals('"\\u0010"', stringify('\u0010'));
-  Expect.stringEquals('"\\u0011"', stringify('\u0011'));
-  Expect.stringEquals('"\\u0012"', stringify('\u0012'));
-  Expect.stringEquals('"\\u0013"', stringify('\u0013'));
-  Expect.stringEquals('"\\u0014"', stringify('\u0014'));
-  Expect.stringEquals('"\\u0015"', stringify('\u0015'));
-  Expect.stringEquals('"\\u0016"', stringify('\u0016'));
-  Expect.stringEquals('"\\u0017"', stringify('\u0017'));
-  Expect.stringEquals('"\\u0018"', stringify('\u0018'));
-  Expect.stringEquals('"\\u0019"', stringify('\u0019'));
-  Expect.stringEquals('"\\u001a"', stringify('\u001a'));
-  Expect.stringEquals('"\\u001b"', stringify('\u001b'));
-  Expect.stringEquals('"\\u001c"', stringify('\u001c'));
-  Expect.stringEquals('"\\u001d"', stringify('\u001d'));
-  Expect.stringEquals('"\\u001e"', stringify('\u001e'));
-  Expect.stringEquals('"\\u001f"', stringify('\u001f'));
-  Expect.stringEquals('"\\\""', stringify('"'));
-  Expect.stringEquals('"\\\\"', stringify('\\'));
+  Expect.stringEquals('""', JSON.encode(''));
+  Expect.stringEquals('"\\u0000"', JSON.encode('\u0000'));
+  Expect.stringEquals('"\\u0001"', JSON.encode('\u0001'));
+  Expect.stringEquals('"\\u0002"', JSON.encode('\u0002'));
+  Expect.stringEquals('"\\u0003"', JSON.encode('\u0003'));
+  Expect.stringEquals('"\\u0004"', JSON.encode('\u0004'));
+  Expect.stringEquals('"\\u0005"', JSON.encode('\u0005'));
+  Expect.stringEquals('"\\u0006"', JSON.encode('\u0006'));
+  Expect.stringEquals('"\\u0007"', JSON.encode('\u0007'));
+  Expect.stringEquals('"\\b"', JSON.encode('\u0008'));
+  Expect.stringEquals('"\\t"', JSON.encode('\u0009'));
+  Expect.stringEquals('"\\n"', JSON.encode('\u000a'));
+  Expect.stringEquals('"\\u000b"', JSON.encode('\u000b'));
+  Expect.stringEquals('"\\f"', JSON.encode('\u000c'));
+  Expect.stringEquals('"\\r"', JSON.encode('\u000d'));
+  Expect.stringEquals('"\\u000e"', JSON.encode('\u000e'));
+  Expect.stringEquals('"\\u000f"', JSON.encode('\u000f'));
+  Expect.stringEquals('"\\u0010"', JSON.encode('\u0010'));
+  Expect.stringEquals('"\\u0011"', JSON.encode('\u0011'));
+  Expect.stringEquals('"\\u0012"', JSON.encode('\u0012'));
+  Expect.stringEquals('"\\u0013"', JSON.encode('\u0013'));
+  Expect.stringEquals('"\\u0014"', JSON.encode('\u0014'));
+  Expect.stringEquals('"\\u0015"', JSON.encode('\u0015'));
+  Expect.stringEquals('"\\u0016"', JSON.encode('\u0016'));
+  Expect.stringEquals('"\\u0017"', JSON.encode('\u0017'));
+  Expect.stringEquals('"\\u0018"', JSON.encode('\u0018'));
+  Expect.stringEquals('"\\u0019"', JSON.encode('\u0019'));
+  Expect.stringEquals('"\\u001a"', JSON.encode('\u001a'));
+  Expect.stringEquals('"\\u001b"', JSON.encode('\u001b'));
+  Expect.stringEquals('"\\u001c"', JSON.encode('\u001c'));
+  Expect.stringEquals('"\\u001d"', JSON.encode('\u001d'));
+  Expect.stringEquals('"\\u001e"', JSON.encode('\u001e'));
+  Expect.stringEquals('"\\u001f"', JSON.encode('\u001f'));
+  Expect.stringEquals('"\\\""', JSON.encode('"'));
+  Expect.stringEquals('"\\\\"', JSON.encode('\\'));
   Expect.stringEquals('"Got \\b, \\f, \\n, \\r, \\t, \\u0000, \\\\, and \\"."',
-      stringify('Got \b, \f, \n, \r, \t, \u0000, \\, and ".'));
+      JSON.encode('Got \b, \f, \n, \r, \t, \u0000, \\, and ".'));
   Expect.stringEquals('"Got \\b\\f\\n\\r\\t\\u0000\\\\\\"."',
-    stringify('Got \b\f\n\r\t\u0000\\".'));
+    JSON.encode('Got \b\f\n\r\t\u0000\\".'));
 }
diff --git a/tools/VERSION b/tools/VERSION
index 64d19d0..260a0bd 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 8
-BUILD 6
+BUILD 7
 PATCH 0
diff --git a/tools/bots/bot_utils.py b/tools/bots/bot_utils.py
index 9f3bccc..947beed 100644
--- a/tools/bots/bot_utils.py
+++ b/tools/bots/bot_utils.py
@@ -111,6 +111,10 @@
     return '/'.join([self.dartium_directory(revision),
       self.dartium_variant_zipfilename(name, system, arch, mode)])
 
+  def apidocs_zipfilepath(self, revision):
+    return '/'.join([self.apidocs_directory(revision),
+      self.apidocs_zipfilename()])
+
   # Functions for querying gs:// directories
 
   def dartium_directory(self, revision):
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index f70bdfc..c6c83c6 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -37,7 +37,6 @@
 # ......io/
 # ......isolate/
 # ......js/
-# ......json/
 # ......math/
 # ......mirrors/
 # ......utf/
@@ -189,7 +188,7 @@
   os.makedirs(LIB)
 
   #
-  # Create and populate lib/{core, crypto, isolate, json, utf, ...}.
+  # Create and populate lib/{core, crypto, isolate, utf, ...}.
   #
 
   os.makedirs(join(LIB, 'html'))
@@ -204,7 +203,7 @@
                   join('html', 'dart2js'), join('html', 'dartium'),
                   join('html', 'html_common'),
                   join('indexed_db', 'dart2js'), join('indexed_db', 'dartium'),
-                  'js', 'json', 'math', 'mirrors', 'typed_data',
+                  'js', 'math', 'mirrors', 'platform', 'typed_data',
                   join('svg', 'dart2js'), join('svg', 'dartium'),
                   'utf',
                   join('web_audio', 'dart2js'), join('web_audio', 'dartium'),
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index 7494d1f..a787d3c 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -530,6 +530,32 @@
     }
   },
   "dart.dom.web_gl": {
+    "WebGLContextAttributes": {
+      "comment": [
+        "/**",
+        " * The properties of a WebGL rendering context.",
+        " *",
+        " * If [alpha] is `true`, then the context has an alpha channel.",
+        " *",
+        " * If [antialias] is `true`, then antialiasing is performed by the browser, but",
+        " * only if the browser's implementation of WebGL supports antialiasing.",
+        " *",
+        " * If [depth] is `true`, then the context has a depth buffer of at least 16",
+        " * bits.",
+        " *",
+        " * If [premultipliedAlpha] is `true`, then the context's colors are assumed to",
+        " * be premultiplied. This means that color values are assumed to have  been",
+        " * multiplied by their alpha values. If [alpha] is `false`, then this flag is",
+        " * ignored.",
+        " *",
+        " * If [preserveDrawingBuffer] is `false`, then all contents of the context are",
+        " * cleared. If `true`, then all values will remain until changed or cleared.",
+        " *",
+        " * If [stencil] is `true`, then the context has a stencil buffer of at least 8",
+        " * bits.",
+        " */"
+      ]
+    },
     "WebGLRenderingContext": {
       "members": {
         "bufferData": [
diff --git a/tools/dom/dom.py b/tools/dom/dom.py
index c362f55..e0bbfdd 100755
--- a/tools/dom/dom.py
+++ b/tools/dom/dom.py
@@ -80,7 +80,6 @@
     dart2js_path,
     dart_file,
     '--library-root=sdk/',
-    '--disallow-unsafe-eval',
     '-o%s' % out_file
   ]
   if checked:
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
index 0dc0752..26ef569 100644
--- a/tools/dom/scripts/dartmetadata.py
+++ b/tools/dom/scripts/dartmetadata.py
@@ -207,6 +207,11 @@
       "@Returns('int|String|Null')",
     ],
 
+    'ImageData.data': [
+      "@Creates('Uint8ClampedList')",
+      "@Returns('Uint8ClampedList')",
+    ],
+
     'MediaStream.getAudioTracks': [
       "@Creates('JSExtendableArray')",
       "@Returns('JSExtendableArray')",
@@ -315,6 +320,10 @@
                 "|Uint32List|Framebuffer|Renderbuffer|Texture')",
     ],
 
+    'WebGLRenderingContext.getContextAttributes': [
+      "@Creates('ContextAttributes|=Object')",
+    ],
+
     'XMLHttpRequest.response': [
       "@Creates('ByteBuffer|Blob|Document|=Object|JSExtendableArray|String"
                 "|num')",
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index eb1539e..93a2474 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -97,6 +97,8 @@
     'ChannelMergerNode': 'ChannelMergerNode,AudioChannelMerger',
     'ChannelSplitterNode': 'ChannelSplitterNode,AudioChannelSplitter',
 
+    'ClientRect': 'ClientRect,DOMRect',
+
     'CSSStyleDeclaration':
         #                    IE                   Firefox
         'CSSStyleDeclaration,MSStyleCSSProperties,CSS2Properties',
@@ -534,6 +536,10 @@
       Conversion('_convertDartToNative_EventTarget', 'EventTarget',
                  'dynamic'),
 
+    'WebGLContextAttributes get':
+      Conversion('convertNativeToDart_ContextAttributes', 'dynamic',
+                 'ContextAttributes'),
+
     'ImageData get':
       Conversion('convertNativeToDart_ImageData', 'dynamic', 'ImageData'),
     'ImageData set':
@@ -1123,7 +1129,6 @@
         suppress_interface=True),
     'GLenum': TypeData(clazz='Primitive', dart_type='int',
         native_type='unsigned'),
-    'HTMLAllCollection': TypeData(clazz='Interface', item_type='Node'),
     'HTMLCollection': TypeData(clazz='Interface', item_type='Node'),
     'NamedNodeMap': TypeData(clazz='Interface', item_type='Node'),
     'NodeList': TypeData(clazz='Interface', item_type='Node',
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index c819d95..a862cb4 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -67,7 +67,9 @@
 # Interfaces that are suppressed, but need to still exist for Dartium and to
 # properly wrap DOM objects if/when encountered.
 _removed_html_interfaces = [
+  'CDataSection',
   'CSSPrimitiveValue',
+  'CSSUnknownRule',
   'CSSValue',
   'Counter',
   'DOMFileSystemSync', # Workers
@@ -79,6 +81,7 @@
   'FileEntrySync', # Workers
   'FileReaderSync', # Workers
   'FileWriterSync', # Workers
+  'HTMLAllCollection',
   'HTMLAppletElement',
   'HTMLBaseFontElement',
   'HTMLDirectoryElement',
@@ -87,6 +90,9 @@
   'HTMLFrameSetElement',
   'HTMLMarqueeElement',
   'IDBAny',
+  'MutationEvent',
+  'Notation',
+  'NotificationCenter',
   'PagePopupController',
   'RGBColor',
   'RadioNodeList',  # Folded onto NodeList in dart2js.
@@ -116,6 +122,10 @@
   'SVGVKernElement',
   'SharedWorker', # Workers
   'SubtleCrypto',
+  'WebKitCSSFilterValue',
+  'WebKitCSSMatrix',
+  'WebKitCSSMixFunctionValue',
+  'WebKitCSSTransformValue',
   'WebKitMediaSource',
   'WebKitSourceBuffer',
   'WebKitSourceBufferList',
@@ -317,6 +327,7 @@
   'WheelEvent.initWebKitWheelEvent',
   'WheelEvent.deltaX',
   'WheelEvent.deltaY',
+  'WorkerGlobalScope.webkitNotifications',
   'Window.getComputedStyle',
   'Window.clearInterval',
   'Window.clearTimeout',
diff --git a/tools/dom/src/WrappedList.dart b/tools/dom/src/WrappedList.dart
index 145c9ab..375ce7c 100644
--- a/tools/dom/src/WrappedList.dart
+++ b/tools/dom/src/WrappedList.dart
@@ -8,7 +8,8 @@
  * A list which just wraps another list, for either intercepting list calls or
  * retyping the list (for example, from List<A> to List<B> where B extends A).
  */
-class _WrappedList<E> extends ListBase<E> {
+class _WrappedList<E extends Node> extends ListBase<E>
+    implements NodeListWrapper {
   final List _list;
 
   _WrappedList(this._list);
@@ -58,6 +59,8 @@
   void fillRange(int start, int end, [E fillValue]) {
     _list.fillRange(start, end, fillValue);
   }
+
+  List<Node> get rawList => _list;
 }
 
 /**
diff --git a/tools/dom/src/dart2js_CustomElementSupport.dart b/tools/dom/src/dart2js_CustomElementSupport.dart
index 0f941fd..f38bae1 100644
--- a/tools/dom/src/dart2js_CustomElementSupport.dart
+++ b/tools/dom/src/dart2js_CustomElementSupport.dart
@@ -106,12 +106,6 @@
   JS('void', '#.attributeChangedCallback = #', properties,
       JS('=Object', '{value: #}', _makeCallbackMethod3(_callAttributeChanged)));
 
-  // TODO(blois): Bug 13220- remove once transition is complete
-  JS('void', '#.enteredDocumentCallback = #', properties,
-      JS('=Object', '{value: #}', _makeCallbackMethod(_callEnteredView)));
-  JS('void', '#.leftDocumentCallback = #', properties,
-      JS('=Object', '{value: #}', _makeCallbackMethod(_callLeftView)));
-
   var baseProto = JS('=Object', '#.prototype', baseConstructor);
   var proto = JS('=Object', 'Object.create(#, #)', baseProto, properties);
 
diff --git a/tools/dom/templates/html/impl/impl_ClientRect.darttemplate b/tools/dom/templates/html/impl/impl_ClientRect.darttemplate
index 03aeb73..d607a5a 100644
--- a/tools/dom/templates/html/impl/impl_ClientRect.darttemplate
+++ b/tools/dom/templates/html/impl/impl_ClientRect.darttemplate
@@ -72,7 +72,7 @@
   /**
    * Tests whether `this` entirely contains [another].
    */
-  bool contains(Rectangle<num> another) {
+  bool containsRectangle(Rectangle<num> another) {
     return left <= another.left &&
            left + width >= another.left + another.width &&
            top <= another.top &&
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index bd703e5..3bc56ef 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -4,7 +4,8 @@
 
 part of $LIBRARYNAME;
 
-class _ChildrenElementList extends ListBase<Element> {
+class _ChildrenElementList extends ListBase<Element>
+    implements NodeListWrapper {
   // Raw Element.
   final Element _element;
   final HtmlCollection _childElements;
@@ -157,6 +158,8 @@
     if (length > 1) throw new StateError("More than one element");
     return first;
   }
+
+  List<Node> get rawList => _childElements;
 }
 
 /**
@@ -255,7 +258,8 @@
 // a better option given that we cannot quite force NodeList to be an
 // ElementList as there are valid cases where a NodeList JavaScript object
 // contains Node objects that are not Elements.
-class _FrozenElementList<T extends Element> extends ListBase<T> implements ElementList {
+class _FrozenElementList<T extends Element> extends ListBase<T>
+    implements ElementList, NodeListWrapper {
   final List<Node> _nodeList;
   // The subset of _nodeList that are Elements.
   List<Element> _elementList;
@@ -306,6 +310,9 @@
   CssRect get borderEdge => _elementList.first.borderEdge;
 
   CssRect get marginEdge => _elementList.first.marginEdge;
+
+  List<Node> get rawList => _nodeList;
+
 $!ELEMENT_STREAM_GETTERS
 }
 
@@ -962,6 +969,8 @@
       return JS('bool', '#.mozMatchesSelector(#)', this, selectors);
     } else if (JS('bool', '!!#.msMatchesSelector', this)) {
       return JS('bool', '#.msMatchesSelector(#)', this, selectors);
+    } else if (JS('bool', '!!#.oMatchesSelector', this)) {
+      return JS('bool', '#.oMatchesSelector(#)', this, selectors);
     } else {
       throw new UnsupportedError("Not supported on this platform");
     }
diff --git a/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate b/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate
index d412536..203068c 100644
--- a/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate
+++ b/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate
@@ -19,6 +19,16 @@
 $endif
   }
 
+  /**
+   * Observes the target for the specified changes.
+   *
+   * Some requirements for the optional parameters:
+   *
+   * * Either childList, attributes or characterData must be true.
+   * * If attributeOldValue is true then attributes must also be true.
+   * * If attributeFilter is specified then attributes must be true.
+   * * If characterDataOldValue is true then characterData must be true.
+   */
   void observe(Node target,
                {bool childList,
                 bool attributes,
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index 1220467..2f7b2d7 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -9,7 +9,7 @@
  * the actual child nodes of an element until strictly necessary greatly
  * improving performance for the typical cases where it is not required.
  */
-class _ChildNodeListLazy extends ListBase<Node> {
+class _ChildNodeListLazy extends ListBase<Node> implements NodeListWrapper {
   final Node _this;
 
   _ChildNodeListLazy(this._this);
@@ -180,6 +180,8 @@
   }
 
   Node operator[](int index) => _this.childNodes[index];
+
+  List<Node> get rawList => _this.childNodes;
 }
 
 
@@ -258,12 +260,5 @@
    * Print out a String representation of this Node.
    */
   String toString() => nodeValue == null ? super.toString() : nodeValue;
-
-  /**
-   * Use ownerDocument instead.
-   */
-  @deprecated
-  Document get document => ownerDocument;
-
 $!MEMBERS
 }
diff --git a/tools/test.dart b/tools/test.dart
index aa9b362..d319bdae 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -132,6 +132,10 @@
   List<Future> serverFutures = [];
   var testSuites = new List<TestSuite>();
   var maxBrowserProcesses = maxProcesses;
+  // If the server ports are fixed, then we can only have one configuration.
+  assert(((configurations[0]['test_server_port'] == 0) &&
+          (configurations[0]['test_server_cross_origin_port'] == 0)) ||
+         (configurations.length == 1));
   for (var conf in configurations) {
     Map<String, RegExp> selectors = conf['selectors'];
     var useContentSecurityPolicy = conf['csp'];
@@ -143,7 +147,9 @@
       var servers = new TestingServers(new Path(TestUtils.buildDir(conf)),
                                        useContentSecurityPolicy,
                                        conf['runtime']);
-      serverFutures.add(servers.startServers(conf['local_ip']));
+      serverFutures.add(servers.startServers(conf['local_ip'],
+          port: conf['test_server_port'],
+          crossOriginPort: conf['test_server_cross_origin_port']));
       conf['_servers_'] = servers;
       if (verbose) {
         serverFutures.last.then((_) {
diff --git a/tools/testing/dart/android.dart b/tools/testing/dart/android.dart
index 60dcc48..940d47c 100644
--- a/tools/testing/dart/android.dart
+++ b/tools/testing/dart/android.dart
@@ -265,6 +265,13 @@
   }
 
   /**
+   * Set system property name to value.
+   */
+  Future setProp(String name, String value) {
+    return _adbCommand(['shell', 'setprop', name, value]);
+  }
+
+  /**
    * Kill all background processes.
    */
   Future killAll() {
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index 4c1043f..f45263d 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -54,13 +54,15 @@
 
   Browser();
 
-  factory Browser.byName(String name, [Map globalConfiguration = const {}]) {
+  factory Browser.byName(String name,
+                         [Map globalConfiguration = const {},
+                          bool checkedMode = false]) {
     if (name == 'ff' || name == 'firefox') {
       return new Firefox();
     } else if (name == 'chrome') {
       return new Chrome();
     } else if (name == 'dartium') {
-      return new Dartium(globalConfiguration);
+      return new Dartium(globalConfiguration, checkedMode);
     } else if (name == 'safari') {
       return new Safari();
     } else if (name.startsWith('ie')) {
@@ -410,8 +412,9 @@
 
 class Dartium extends Chrome {
   final Map globalConfiguration;
+  final bool checkedMode;
 
-  Dartium(this.globalConfiguration);
+  Dartium(this.globalConfiguration, this.checkedMode);
 
   String _getBinary() {
     return Locations.getDartiumLocation(globalConfiguration);
@@ -423,6 +426,9 @@
     // calls in dart to the top-level javascript function "dartPrint()" if
     // available.
     environment['DART_FORWARDING_PRINT'] = '1';
+    if (checkedMode) {
+      environment['DART_FLAGS'] = '--checked';
+    }
     return environment;
   }
 
@@ -465,6 +471,64 @@
 }
 
 
+class AndroidBrowserConfig {
+  final String name;
+  final String package;
+  final String activity;
+  final String action;
+  AndroidBrowserConfig(this.name, this.package, this.activity, this.action);
+}
+
+
+final contentShellOnAndroidConfig = new AndroidBrowserConfig(
+    'ContentShellOnAndroid',
+    'org.chromium.content_shell_apk',
+    '.ContentShellActivity',
+    'android.intent.action.VIEW');
+
+
+final dartiumOnAndroidConfig = new AndroidBrowserConfig(
+    'DartiumOnAndroid',
+    'com.google.android.apps.chrome',
+    '.Main',
+    'android.intent.action.VIEW');
+
+
+class AndroidBrowser extends Browser {
+  AdbDevice _adbDevice;
+  AndroidBrowserConfig _config;
+
+  AndroidBrowser(this._adbDevice, this._config);
+
+  Future<bool> start(String url) {
+    var intent = new Intent(
+        _config.action, _config.package, _config.activity, url);
+    return _adbDevice.waitForBootCompleted().then((_) {
+      return _adbDevice.forceStop(_config.package);
+    }).then((_) {
+      return _adbDevice.killAll();
+    }).then((_) {
+      return _adbDevice.adbRoot();
+    }).then((_) {
+      return _adbDevice.setProp("DART_FORWARDING_PRINT", "1");
+    }).then((_) {
+      return _adbDevice.startActivity(intent).then((_) => true);
+    });
+  }
+
+  Future<bool> close() {
+    if (_adbDevice != null) {
+      return _adbDevice.forceStop(_config.package).then((_) {
+        return _adbDevice.killAll().then((_) => true);
+      });
+    }
+    return new Future.value(true);
+  }
+
+  String toString() => _config.name;
+}
+
+
 class AndroidChrome extends Browser {
   static const String viewAction = 'android.intent.action.VIEW';
   static const String mainAction = 'android.intent.action.MAIN';
@@ -531,6 +595,7 @@
   String toString() => "chromeOnAndroid";
 }
 
+
 class Firefox extends Browser {
   static const String enablePopUp =
       'user_pref("dom.disable_open_during_load", false);';
@@ -657,6 +722,7 @@
  */
 class BrowserTestRunner {
   final Map globalConfiguration;
+  final bool checkedMode; // needed for dartium
 
   String localIp;
   String browserName;
@@ -683,14 +749,16 @@
   BrowserTestRunner(this.globalConfiguration,
                     this.localIp,
                     this.browserName,
-                    this.maxNumBrowsers);
+                    this.maxNumBrowsers,
+                    {bool this.checkedMode: false});
 
   Future<bool> start() {
     // If [browserName] doesn't support opening new windows, we use new iframes
     // instead.
     bool useIframe =
         !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName);
-    testingServer = new BrowserTestingServer(localIp, useIframe);
+    testingServer = new BrowserTestingServer(
+        globalConfiguration, localIp, useIframe);
     return testingServer.start().then((_) {
       testingServer.testDoneCallBack = handleResults;
       testingServer.testStartedCallBack = handleStarted;
@@ -718,7 +786,14 @@
     // TODO(kustermann): This is a hackisch way to accomplish it and should
     // be encapsulated
     var browsersCompleter = new Completer();
-    if (browserName == 'chromeOnAndroid') {
+    var androidBrowserCreationMapping = {
+      'chromeOnAndroid' : (AdbDevice device) => new AndroidChrome(device),
+      'ContentShellOnAndroid' : (AdbDevice device) =>
+          new AndroidBrowser(device, contentShellOnAndroidConfig),
+      'DartiumOnAndroid' : (AdbDevice device) =>
+          new AndroidBrowser(device, dartiumOnAndroidConfig),
+    };
+    if (androidBrowserCreationMapping.containsKey(browserName)) {
       AdbHelper.listDevices().then((deviceIds) {
         if (deviceIds.length > 0) {
           var browsers = [];
@@ -726,7 +801,7 @@
             var id = "BROWSER$i";
             var device = new AdbDevice(deviceIds[i]);
             adbDeviceMapping[id] = device;
-            var browser = new AndroidChrome(device);
+            var browser = androidBrowserCreationMapping[browserName](device);
             browsers.add(browser);
             // We store this in case we need to kill the browser.
             browser.id = id;
@@ -839,6 +914,12 @@
       var new_id = id;
       if (browserName == 'chromeOnAndroid') {
         browser = new AndroidChrome(adbDeviceMapping[id]);
+      } else if (browserName == 'ContentShellOnAndroid') {
+        browser = new AndroidBrowser(adbDeviceMapping[id],
+                                     contentShellOnAndroidConfig);
+      } else if (browserName == 'DartiumOnAndroid') {
+        browser = new AndroidBrowser(adbDeviceMapping[id],
+                                     dartiumOnAndroidConfig);
       } else {
         browserStatus.remove(id);
         browser = getInstance();
@@ -947,13 +1028,15 @@
   }
 
   Browser getInstance() {
-    var browser = new Browser.byName(browserName, globalConfiguration);
+    var browser =
+        new Browser.byName(browserName, globalConfiguration, checkedMode);
     browser.logger = logger;
     return browser;
   }
 }
 
 class BrowserTestingServer {
+  final Map globalConfiguration;
   /// Interface of the testing server:
   ///
   /// GET /driver/BROWSER_ID -- This will get the driver page to fetch
@@ -985,10 +1068,11 @@
   Function testStartedCallBack;
   Function nextTestCallBack;
 
-  BrowserTestingServer(this.localIp, this.useIframe);
+  BrowserTestingServer(this.globalConfiguration, this.localIp, this.useIframe);
 
   Future start() {
-    return HttpServer.bind(localIp, 0).then((createdServer) {
+    int port = globalConfiguration['test_driver_port'];
+    return HttpServer.bind(localIp, port).then((createdServer) {
       httpServer = createdServer;
       void handler(HttpRequest request) {
         // Don't allow caching of resources from the browser controller, i.e.,
@@ -1039,7 +1123,8 @@
 
       // Set up the error reporting server that enables us to send back
       // errors from the browser.
-      return HttpServer.bind(localIp, 0).then((createdReportServer) {
+      port = globalConfiguration['test_driver_error_port'];
+      return HttpServer.bind(localIp, port).then((createdReportServer) {
         errorReportingServer = createdReportServer;
         void errorReportingHandler(HttpRequest request) {
           StringBuffer buffer = new StringBuffer();
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index db7a6b1..f98dfc5 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -31,16 +31,16 @@
     const <String>['--report', '--progress=diff', 'co19'];
 
 const List<List<String>> COMMAND_LINES = const <List<String>>[
-    const <String>['-mrelease,debug', '-rvm', '-cnone'],
-    const <String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
-    const <String>['-mrelease', '-rnone', '-cdartanalyzer'],
-    const <String>['-mrelease', '-rnone', '-cdart2analyzer'],
-    const <String>['-mrelease', '-rvm', '-cdart2dart', '--use-sdk'],
-    const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk'],
-    const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
-                   '--minified'],
-    const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
-                   '--checked'],
+    //const <String>['-mrelease,debug', '-rvm', '-cnone'],
+    //const <String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
+    //const <String>['-mrelease', '-rnone', '-cdartanalyzer'],
+    //const <String>['-mrelease', '-rnone', '-cdart2analyzer'],
+    //const <String>['-mrelease', '-rvm', '-cdart2dart', '--use-sdk'],
+    //const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk'],
+    //const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
+                   //'--minified'],
+    //const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
+                   //'--checked'],
     const <String>['-mrelease', '-rdartium', '-cnone', '--use-sdk',
                    '--use_browser_controller', '--write-debug-log'],
 ];
diff --git a/tools/testing/dart/record_and_replay.dart b/tools/testing/dart/record_and_replay.dart
index 7cfc400..f9b728f 100644
--- a/tools/testing/dart/record_and_replay.dart
+++ b/tools/testing/dart/record_and_replay.dart
@@ -5,7 +5,7 @@
 library record_and_replay;
 
 import 'dart:io';
-import 'dart:json' as json;
+import 'dart:convert';
 import 'dart:utf';
 
 import 'test_runner.dart';
@@ -76,7 +76,7 @@
 
   void finish() {
     var file = new File(_outputPath.toNativePath());
-    var jsonString = json.stringify(_recordedCommandInvocations);
+    var jsonString = JSON.encode(_recordedCommandInvocations);
     file.writeAsStringSync(jsonString);
     print("TestCaseRecorder: written all TestCases to ${_outputPath}");
   }
@@ -92,7 +92,7 @@
 
   void loadFromPath(Path recordingPath) {
     var file = new File(recordingPath.toNativePath());
-    var commandRecordings = json.parse(file.readAsStringSync());
+    var commandRecordings = JSON.decode(file.readAsStringSync());
     _commandOutputRecordings = {};
     for (var commandRecording in commandRecordings) {
       var key = _indexKey(commandRecording['command']['executable'],
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index 38d45a7..ff016e6 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -86,6 +86,11 @@
 
     dartium: Run Dart or JavaScript in Dartium.
 
+    ContentShellOnAndroid: Run Dart or JavaScript in Dartium content shell
+                      on Android.
+
+    DartiumOnAndroid: Run Dart or Javascript in Dartium on Android.
+
     [ff | chrome | safari | ie9 | ie10 | opera | chromeOnAndroid]:
         Run JavaScript in the specified browser.
 
@@ -94,7 +99,7 @@
               ['-r', '--runtime'],
               ['vm', 'd8', 'jsshell', 'drt', 'dartium', 'ff', 'firefox',
                'chrome', 'safari', 'ie9', 'ie10', 'opera', 'chromeOnAndroid',
-               'none'],
+               'ContentShellOnAndroid', 'DartiumOnAndroid', 'none'],
               'vm'),
           new _TestOptionSpecification(
               'arch',
@@ -302,6 +307,34 @@
               [],
               '127.0.0.1'),
           new _TestOptionSpecification(
+              'test_server_port',
+              'Port for test http server.',
+              ['--test_server_port'],
+              [],
+              0,
+              'int'),
+          new _TestOptionSpecification(
+              'test_server_cross_origin_port',
+              'Port for test http server cross origin.',
+              ['--test_server_cross_origin_port'],
+              [],
+              0,
+              'int'),
+          new _TestOptionSpecification(
+              'test_driver_port',
+              'Port for http test driver server.',
+              ['--test_driver_port'],
+              [],
+              0,
+              'int'),
+          new _TestOptionSpecification(
+              'test_driver_error_port',
+              'Port for http test driver server errors.',
+              ['--test_driver_error_port'],
+              [],
+              0,
+              'int'),
+          new _TestOptionSpecification(
               'record_to_file',
               'Records all the commands that need to be executed and writes it '
               'out to a file.',
@@ -513,7 +546,8 @@
         break;
       case 'none':
       case 'dart2dart':
-        validRuntimes = const ['vm', 'drt', 'dartium'];
+        validRuntimes = const ['vm', 'drt', 'dartium',
+                               'ContentShellOnAndroid', 'DartiumOnAndroid'];
         break;
     }
     if (!validRuntimes.contains(config['runtime'])) {
@@ -533,15 +567,6 @@
       print("Error: shard index is ${config['shard']} out of "
             "${config['shards']} shards");
     }
-    if (config['runtime'] == 'dartium' &&
-        const ['none', 'dart2dart'].contains(config['compiler']) &&
-        config['checked']) {
-      // TODO(vsm): Set the DART_FLAGS environment appropriately when
-      // invoking Selenium to support checked mode.  It's not clear
-      // the current selenium API supports this.
-      isValid = false;
-      print("Warning: checked mode is not yet supported for dartium tests.");
-    }
     return isValid;
   }
 
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 0bb1fa0..5527d03 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -281,12 +281,14 @@
 class BrowserTestCommand extends Command {
   final String browser;
   final String url;
+  final bool checkedMode; // needed for dartium
 
   BrowserTestCommand._(String _browser,
                        this.url,
                        String executable,
                        List<String> arguments,
-                       String configurationDir)
+                       String configurationDir,
+                       {bool this.checkedMode: false})
       : super._(_browser, executable, arguments, configurationDir),
         browser = _browser;
 
@@ -294,6 +296,7 @@
     super._buildHashCode(builder);
     builder.add(browser);
     builder.add(url);
+    builder.add(checkedMode);
   }
 
   bool _equal(Command other) {
@@ -301,7 +304,8 @@
         other is BrowserTestCommand &&
         super._equal(other) &&
         browser == other.browser &&
-        url == other.url;
+        url == other.url &&
+        checkedMode == other.checkedMode;
   }
 }
 
@@ -396,9 +400,11 @@
                                            String url,
                                            String executable,
                                            List<String> arguments,
-                                           String configurationDir) {
+                                           String configurationDir,
+                                           {bool checkedMode: false}) {
     var command = new BrowserTestCommand._(
-        browser, url, executable, arguments, configurationDir);
+        browser, url, executable, arguments, configurationDir,
+        checkedMode: checkedMode);
     return _getUniqueCommand(command);
   }
 
@@ -1383,7 +1389,7 @@
       },
       'dart2analyzer' : {
         // This is a unix shell script, no windows equivalent available
-        'run_executable' : 'editor/tools/analyzer_experimental',
+        'run_executable' : 'editor/tools/analyzer',
         'run_arguments' : ['--batch'],
         'terminate_command' : null,
     },
@@ -1907,7 +1913,7 @@
 
   // For dartc/selenium batch processing we keep a list of batch processes.
   final _batchProcesses = new Map<String, List<BatchRunnerProcess>>();
-  // For browser tests we keepa [BrowserTestRunner]
+  // We keep a BrowserTestRunner for every "browserName-checked" configuration.
   final _browserTestRunners = new Map<String, BrowserTestRunner>();
 
   bool _finishing = false;
@@ -2022,24 +2028,28 @@
     BrowserTest browserTest = new BrowserTest(browserCommand.url,
                                               callback,
                                               timeout);
-    _getBrowserTestRunner(browserCommand.browser).then((testRunner) {
+    _getBrowserTestRunner(browserCommand.browser, browserCommand.checkedMode)
+        .then((testRunner) {
       testRunner.queueTest(browserTest);
     });
 
     return completer.future;
   }
 
-  Future<BrowserTestRunner> _getBrowserTestRunner(String browser) {
+  Future<BrowserTestRunner> _getBrowserTestRunner(
+      String browser, bool checkedMode) {
+    var browserCheckedString = "$browser-$checkedMode";
+
     var localIp = globalConfiguration['local_ip'];
     var num_browsers = maxBrowserProcesses;
-    if (_browserTestRunners[browser] == null) {
-      var testRunner =
-        new BrowserTestRunner(
-            globalConfiguration, localIp, browser, num_browsers);
+    if (_browserTestRunners[browserCheckedString] == null) {
+      var testRunner = new BrowserTestRunner(
+            globalConfiguration, localIp, browser, num_browsers,
+            checkedMode: checkedMode);
       if (globalConfiguration['verbose']) {
         testRunner.logger = DebugLogger.info;
       }
-      _browserTestRunners[browser] = testRunner;
+      _browserTestRunners[browserCheckedString] = testRunner;
       return testRunner.start().then((started) {
         if (started) {
           return testRunner;
@@ -2048,7 +2058,7 @@
         io.exit(1);
       });
     }
-    return new Future.value(_browserTestRunners[browser]);
+    return new Future.value(_browserTestRunners[browserCheckedString]);
   }
 }
 
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index d62a33e..caa2c6e 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -187,7 +187,7 @@
       case 'dartanalyzer':
         return 'sdk/bin/dartanalyzer_developer$suffix';
       case 'dart2analyzer':
-        return 'editor/tools/analyzer_experimental';
+        return 'editor/tools/analyzer';
       default:
         throw "Unknown executable for: ${configuration['compiler']}";
     }
@@ -1097,8 +1097,8 @@
                   runtime,
                   fullHtmlPath];
           commandSet.add(CommandBuilder.instance.getBrowserTestCommand(
-              runtime, fullHtmlPath,
-              TestUtils.dartTestExecutable.toString(), args, configurationDir));
+              runtime, fullHtmlPath, TestUtils.dartTestExecutable.toString(),
+              args, configurationDir, checkedMode: configuration['checked']));
         } else if (TestUtils.usesWebDriver(runtime)) {
           args = [
               dartDir.append('tools/testing/run_selenium.py').toNativePath(),
@@ -1522,7 +1522,8 @@
 
   List<List<String>> getVmOptions(Map optionsFromFile) {
     var COMPILERS = const ['none', 'dart2dart'];
-    var RUNTIMES = const ['none', 'vm', 'drt', 'dartium'];
+    var RUNTIMES = const ['none', 'vm', 'drt', 'dartium',
+                          'ContentShellOnAndroid', 'DartiumOnAndroid'];
     var needsVmOptions = COMPILERS.contains(configuration['compiler']) &&
                          RUNTIMES.contains(configuration['runtime']);
     if (!needsVmOptions) return [[]];
@@ -1908,6 +1909,8 @@
       'chrome',
       'ff',
       'chromeOnAndroid',
+      'ContentShellOnAndroid',
+      'DartiumOnAndroid'
     ];
     return BROWSERS.contains(runtime);
   }
diff --git a/tools/testing/webdriver_test_setup.py b/tools/testing/webdriver_test_setup.py
index 7988bab5..33a76c2 100755
--- a/tools/testing/webdriver_test_setup.py
+++ b/tools/testing/webdriver_test_setup.py
@@ -80,32 +80,98 @@
         return loc
   raise Exception("Could not find depot_tools in your path.")
 
+class GoogleBasedInstaller(object):
+  """Install a project from a Google source, pulling latest version."""
 
-class GoogleCodeInstaller(object):
-  """Install code that is being hosted on Google Code."""
-
-  def __init__(self, project_name, download_location, download_name_func):
-    """ Create a object that will install code from a Google Code site.
+  def __init__(self, project_name, destination, download_path_func):
+    """Create an object that will install the project.
     Arguments:
-    project_name - The GoogleCode project name such as "selenium" or
+    project_name - Google code name of the project, such as "selenium" or
     "chromedriver."
-    download_location - Where to download the desired file on our filesystem.
-    download_name_func - A function that takes a dictionary (currently with keys
+    destination - Where to download the desired file on our filesystem.
+    download_path_func - A function that takes a dictionary (currently with keys
     "os" and "version", but more can be added) that calculates the string
-    representing the name of the download we want.
-     """
+    representing the path of the download we want.
+    """
     self.project_name = project_name
-    self.download_location = download_location
-    self.download_name_func = download_name_func
-    self.download_regex_str = self.download_name_func({'os': self.get_os_str,
-        'version': '.+'})
+    self.destination = destination
+    self.download_path_func = download_path_func
+
+  @property
+  def get_os_str(self):
+    """The strings to indicate what OS a download is for."""
+    os_str = 'win'
+    if 'darwin' in sys.platform:
+      os_str = 'mac'
+    elif 'linux' in sys.platform:
+      os_str = 'linux32'
+      if '64bit' in platform.architecture()[0]:
+        os_str = 'linux64'
+    if self.project_name == 'chromedriver' and (
+        os_str == 'mac' or os_str == 'win'):
+      os_str = os_str + '32'
+    return os_str
+
+  def run(self):
+    """Download and install the project."""
+    print 'Installing %s' % self.project_name
+    os_str = self.get_os_str
+    version = self.find_latest_version()
+    download_path = self.download_path_func({'os': os_str, 'version': version})
+    download_name = os.path.basename(download_path)
+    urllib.urlretrieve(os.path.join(self.source_path(), download_path),
+        os.path.join(self.destination, download_name))
+    if download_name.endswith('.zip'):
+      if platform.system() != 'Windows':
+        # The Python zip utility does not preserve executable permissions, but
+        # this does not seem to be a problem for Windows, which does not have a
+        # built in zip utility. :-/
+        run_cmd('unzip -u %s -d %s' % (os.path.join(self.destination,
+                download_name), self.destination), stdin='y')
+      else:
+        z = zipfile.ZipFile(os.path.join(self.destination, download_name))
+        z.extractall(self.destination)
+        z.close()
+      os.remove(os.path.join(self.destination, download_name))
+    chrome_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+        'orig-chromedriver')
+    if self.project_name == 'chromedriver' and os.path.exists(chrome_path):
+      # We have one additional location to make sure chromedriver is updated.
+      # TODO(efortuna): Remove this. See move_chrome_driver_if_needed in
+      # perf_testing/run_perf_tests.py
+      driver = 'chromedriver'
+      if platform.system() == 'Windows':
+        driver += '.exe'
+      shutil.copy(os.path.join(self.destination, driver),
+          os.path.join(chrome_path, driver))
+
+class ChromeDriverInstaller(GoogleBasedInstaller):
+  """Install chromedriver from Google Storage."""
+
+  def __init__(self, destination):
+    """Create an object to install ChromeDriver
+    destination - Where to download the desired file on our filesystem.
+    """
+    super(ChromeDriverInstaller, self).__init__('chromedriver', destination,
+        lambda x: '%(version)s/chromedriver_%(os)s.zip' % x)
+
+  def find_latest_version(self):
+    """Find the latest version number of ChromeDriver."""
+    source_page = urllib2.urlopen(self.source_path())
+    source_text = source_page.read()
+    regex = re.compile('(?:<Key>)(\d+\.\d+)')
+    latest = max(regex.findall(source_text))
+    return latest
+
+  def source_path(self):
+    return 'http://chromedriver.storage.googleapis.com'
+
+class GoogleCodeInstaller(GoogleBasedInstaller):
+  """Install a project from Google Code."""
 
   def google_code_downloads_page(self):
     return 'http://code.google.com/p/%s/downloads/list' % self.project_name
 
-  def google_code_download(self):
-    return 'http://%s.googlecode.com/files/' % self.project_name
-
   def find_latest_version(self):
     """Find the latest version number of some code available for download on a
     Google code page. This was unfortunately done in an ad hoc manner because
@@ -115,12 +181,16 @@
     google_code_site = self.google_code_downloads_page()
     f = urllib2.urlopen(google_code_site)
     latest = ''
+
+    download_regex_str = self.download_path_func({'os': self.get_os_str,
+        'version': '.+'})
+
     for line in f.readlines():
-      if re.search(self.download_regex_str, line):
+      if re.search(download_regex_str, line):
         suffix_index = line.find(
-            self.download_regex_str[self.download_regex_str.rfind('.'):])
-        name_end = self.download_regex_str.rfind('.+')
-        name = self.download_name_func({'os': self.get_os_str, 'version': ''})
+            download_regex_str[download_regex_str.rfind('.'):])
+        name_end = download_regex_str.rfind('.+')
+        name = self.download_path_func({'os': self.get_os_str, 'version': ''})
         name = name[:name.rfind('.')]
         version_str = line[line.find(name) + len(name) : suffix_index]
         orig_version_str = version_str
@@ -134,7 +204,7 @@
         else:
           orig_latest_str = latest
           latest = latest.replace('_', '.')
-	  latest = re.compile(r'[^\d.]+').sub('', latest)
+          latest = re.compile(r'[^\d.]+').sub('', latest)
         nums = version_str.split('.')
         latest_nums = latest.split('.')
         for (num, latest_num) in zip(nums, latest_nums):
@@ -148,53 +218,8 @@
           ' %s.' % google_code_site)
     return latest
 
-  def run(self):
-    """Download and install the Google Code."""
-    print 'Installing from %s' % self.project_name
-    os_str = self.get_os_str
-    version = self.find_latest_version()
-    download_name = self.download_name_func({'os': os_str, 'version': version})
-    urllib.urlretrieve(self.google_code_download() + '/' + download_name,
-        os.path.join(self.download_location, download_name))
-    if download_name.endswith('.zip'):
-      if platform.system() != 'Windows':
-        # The Python zip utility does not preserve executable permissions, but
-        # this does not seem to be a problem for Windows, which does not have a
-        # built in zip utility. :-/
-        run_cmd('unzip -u %s -d %s' % (os.path.join(self.download_location,
-                download_name), self.download_location), stdin='y')
-      else:
-        z = zipfile.ZipFile(os.path.join(self.download_location, download_name))
-        z.extractall(self.download_location)
-        z.close()
-      os.remove(os.path.join(self.download_location, download_name))
-    chrome_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
-        'orig-chromedriver')
-    if self.project_name == 'chromedriver' and os.path.exists(chrome_path):
-      # We have one additional location to make sure chromedriver is updated.
-      # TODO(efortuna): Remove this. See move_chrome_driver_if_needed in
-      # perf_testing/run_perf_tests.py
-      driver = 'chromedriver'
-      if platform.system() == 'Windows':
-        driver += '.exe'
-      shutil.copy(os.path.join(self.download_location, driver),
-          os.path.join(chrome_path, driver))
-
-  @property
-  def get_os_str(self):
-    """The strings to indicate what OS a download is for as used on Google Code.
-    """
-    os_str = 'win'
-    if 'darwin' in sys.platform:
-      os_str = 'mac'
-    elif 'linux' in sys.platform:
-      os_str = 'linux32'
-      if '64bit' in platform.architecture()[0]:
-        os_str = 'linux64'
-    if self.project_name == 'chromedriver' and (
-        os_str == 'mac' or os_str == 'win'):
-      os_str = os_str + '32'
-    return os_str
+  def source_path(self):
+    return 'http://%s.googlecode.com/files/' % self.project_name
 
 
 class FirefoxInstaller(object):
@@ -393,9 +418,7 @@
   if not args.python:
     SeleniumBindingsInstaller(args.buildbot).run()
   if not args.chromedriver:
-    GoogleCodeInstaller('chromedriver',
-        find_depot_tools_location(args.buildbot),
-        lambda x: 'chromedriver_%(os)s_%(version)s.zip' % x).run()
+    ChromeDriverInstaller(find_depot_tools_location(args.buildbot)).run()
   if not args.seleniumrc:
     GoogleCodeInstaller('selenium', os.path.dirname(os.path.abspath(__file__)),
         lambda x: 'selenium-server-standalone-%(version)s.jar' % x).run()
diff --git a/utils/apidoc/apidoc.gyp b/utils/apidoc/apidoc.gyp
index c521ce0..7707557 100644
--- a/utils/apidoc/apidoc.gyp
+++ b/utils/apidoc/apidoc.gyp
@@ -84,7 +84,7 @@
             '--version=<!@(["python", "../../tools/print_version.py"])',
             '--package-root=<(PRODUCT_DIR)/packages',
             '--mode=static',
-            '--exclude-lib=analyzer_experimental',
+            '--exclude-lib=analyzer',
             '--exclude-lib=async_helper',
             '--exclude-lib=barback',
             '--exclude-lib=browser',
diff --git a/utils/testrunner/run_pipeline.dart b/utils/testrunner/run_pipeline.dart
index f1de2d3..c5ac6b3 100644
--- a/utils/testrunner/run_pipeline.dart
+++ b/utils/testrunner/run_pipeline.dart
@@ -60,9 +60,12 @@
 /** Directory where test wrappers are created. */
 String tmpDir;
 
-void main() {
-  port.receive((cfg, replyPort) {
-    config = cfg;
+void main(List<String> args, SendPort replyTo) {
+  var port = new ReceivePort();
+  replyTo.send(port);
+  port.first.then((message) {
+    config = message[0];
+    var replyPort = message[1];
     stdout = new List();
     stderr = new List();
     initPipeline(replyPort);
@@ -178,7 +181,6 @@
   excludeFilters = ${config["exclude"]};
   tprint = (msg) => print('###\$msg');
   notifyDone = (e) { exit(e); };
-  testState["port"] = $serverPort;
     ''';
   } else {
     directives = '''
@@ -194,7 +196,6 @@
   excludeFilters = ${config["exclude"]};
   tprint = (msg) => query('#console').appendText('###\$msg\\n');
   notifyDone = (e) => window.postMessage('done', '*');
-  testState["port"] = $serverPort;
     ''';
   }
 
@@ -247,7 +248,6 @@
 main() {
   includeFilters = ${config["include"]};
   excludeFilters = ${config["exclude"]};
-  unittest.testState["port"] = $serverPort;
   runTests(test.main);
 }
     ''');
diff --git a/utils/testrunner/standard_test_runner.dart b/utils/testrunner/standard_test_runner.dart
index 7429259..cb39ff2 100644
--- a/utils/testrunner/standard_test_runner.dart
+++ b/utils/testrunner/standard_test_runner.dart
@@ -204,21 +204,21 @@
 }
 
 var parentPort;
-runChildTest() {
-  port.receive((testName, sendport) {
-    parentPort = sendport;
-    unittestConfiguration = new TestRunnerChildConfiguration();
-    groupSep = marker;
-    group('', test.main);
-    filterTests(testName);
-    runTests();
-  });
+runChildTest(message) {
+  var testName = message[0];
+  parentPort = message[1];
+  unittestConfiguration = new TestRunnerChildConfiguration();
+  groupSep = marker;
+  group('', test.main);
+  filterTests(testName);
+  runTests();
 }
 
 isolatedTestParentWrapper(testCase) => () {
-  SendPort childPort = spawnFunction(runChildTest);
-  var f = childPort.call(testCase.description);
-  f.then((results) {
+  ReceivePort response = new ReceivePort();
+  return Isolate.spawn(runChildTest, [testCase.description, response.sendPort])
+      .then((_) => response.first)
+      .then((results) {
     var result = results[0];
     var duration = new Duration(milliseconds: results[1]);
     var message = results[2];
@@ -229,7 +229,6 @@
       testCase.error(message, stack);
     }
   });
-  return f;
 };
 
 runIsolateTests() {
diff --git a/utils/testrunner/testrunner.dart b/utils/testrunner/testrunner.dart
index 7ecf8ac..0292b2c 100755
--- a/utils/testrunner/testrunner.dart
+++ b/utils/testrunner/testrunner.dart
@@ -256,8 +256,6 @@
         // We could later print a summary report here.
       }
     });
-    SendPort s = spawnUri(config['pipeline']);
-
     // Get the names of the source and target test files and containing
     // directories.
     var testPath = new Path(testfile);
@@ -279,14 +277,12 @@
           config['pub'], config['runtime']);
       _testDir = targetDir;
     }
-    if (f == null) {
-      s.send(config, port.toSendPort());
-    } else {
-      f.then((_) {
-        s.send(config, port.toSendPort());
-      });
-      break; // Don't do any more until pub is done.
-    }
+    var response = new ReceivePort();
+    spawnUri(config['pipeline'], [], response)
+        .then((_) => f)
+        .then((_) => response.first)
+        .then((s) { s.send([config, port.sendPort]); });
+    if (f != null) break; // Don't do any more until pub is done.
   }
 }